accelerator_cuda.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //go:build cuda
  2. package llm
  3. import (
  4. "bufio"
  5. "bytes"
  6. "errors"
  7. "fmt"
  8. "log"
  9. "os/exec"
  10. "path"
  11. "strconv"
  12. "strings"
  13. "github.com/jmorganca/ollama/format"
  14. )
  15. var (
  16. errNvidiaSMI = errors.New("warning: gpu support may not be enabled, check that you have installed GPU drivers: nvidia-smi command failed")
  17. errAvailableVRAM = errors.New("not enough VRAM available, falling back to CPU only")
  18. )
  19. // acceleratedRunner returns the runner for this accelerator given the provided buildPath string.
  20. func acceleratedRunner(buildPath string) []ModelRunner {
  21. return []ModelRunner{
  22. ModelRunner{
  23. Path: path.Join(buildPath, "cuda", "bin", "ollama-runner"),
  24. Accelerated: true,
  25. },
  26. }
  27. }
  28. // CheckVRAM returns the free VRAM in bytes on Linux machines with NVIDIA GPUs
  29. func CheckVRAM() (int64, error) {
  30. cmd := exec.Command("nvidia-smi", "--query-gpu=memory.free", "--format=csv,noheader,nounits")
  31. var stdout bytes.Buffer
  32. cmd.Stdout = &stdout
  33. err := cmd.Run()
  34. if err != nil {
  35. return 0, errNoAccel
  36. }
  37. var freeMiB int64
  38. scanner := bufio.NewScanner(&stdout)
  39. for scanner.Scan() {
  40. line := scanner.Text()
  41. if strings.Contains(line, "[Insufficient Permissions]") {
  42. return 0, fmt.Errorf("GPU support may not enabled, check you have installed GPU drivers and have the necessary permissions to run nvidia-smi")
  43. }
  44. vram, err := strconv.ParseInt(strings.TrimSpace(line), 10, 64)
  45. if err != nil {
  46. return 0, fmt.Errorf("failed to parse available VRAM: %v", err)
  47. }
  48. freeMiB += vram
  49. }
  50. freeBytes := freeMiB * 1024 * 1024
  51. if freeBytes < 2*format.GigaByte {
  52. log.Printf("less than 2 GB VRAM available")
  53. return 0, errAvailableVRAM
  54. }
  55. return freeBytes, nil
  56. }