config.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package envconfig
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "os"
  6. "path/filepath"
  7. "runtime"
  8. "strconv"
  9. "strings"
  10. )
  11. var (
  12. // Set via OLLAMA_ORIGINS in the environment
  13. AllowOrigins []string
  14. // Set via OLLAMA_DEBUG in the environment
  15. Debug bool
  16. // Set via OLLAMA_LLM_LIBRARY in the environment
  17. LLMLibrary string
  18. // Set via OLLAMA_MAX_LOADED_MODELS in the environment
  19. MaxRunners int
  20. // Set via OLLAMA_MAX_QUEUE in the environment
  21. MaxQueuedRequests int
  22. // Set via OLLAMA_MAX_VRAM in the environment
  23. MaxVRAM uint64
  24. // Set via OLLAMA_NOPRUNE in the environment
  25. NoPrune bool
  26. // Set via OLLAMA_NUM_PARALLEL in the environment
  27. NumParallel int
  28. // Set via OLLAMA_RUNNERS_DIR in the environment
  29. RunnersDir string
  30. // Set via OLLAMA_TMPDIR in the environment
  31. TmpDir string
  32. )
  33. func AsMap() map[string]string {
  34. return map[string]string{
  35. "OLLAMA_ORIGINS": fmt.Sprintf("%v", AllowOrigins),
  36. "OLLAMA_DEBUG": fmt.Sprintf("%v", Debug),
  37. "OLLAMA_LLM_LIBRARY": fmt.Sprintf("%v", LLMLibrary),
  38. "OLLAMA_MAX_LOADED_MODELS": fmt.Sprintf("%v", MaxRunners),
  39. "OLLAMA_MAX_QUEUE": fmt.Sprintf("%v", MaxQueuedRequests),
  40. "OLLAMA_MAX_VRAM": fmt.Sprintf("%v", MaxVRAM),
  41. "OLLAMA_NOPRUNE": fmt.Sprintf("%v", NoPrune),
  42. "OLLAMA_NUM_PARALLEL": fmt.Sprintf("%v", NumParallel),
  43. "OLLAMA_RUNNERS_DIR": fmt.Sprintf("%v", RunnersDir),
  44. "OLLAMA_TMPDIR": fmt.Sprintf("%v", TmpDir),
  45. }
  46. }
  47. var defaultAllowOrigins = []string{
  48. "localhost",
  49. "127.0.0.1",
  50. "0.0.0.0",
  51. }
  52. // Clean quotes and spaces from the value
  53. func clean(key string) string {
  54. return strings.Trim(os.Getenv(key), "\"' ")
  55. }
  56. func init() {
  57. // default values
  58. NumParallel = 1
  59. MaxRunners = 1
  60. MaxQueuedRequests = 512
  61. LoadConfig()
  62. }
  63. func LoadConfig() {
  64. if debug := clean("OLLAMA_DEBUG"); debug != "" {
  65. d, err := strconv.ParseBool(debug)
  66. if err == nil {
  67. Debug = d
  68. } else {
  69. Debug = true
  70. }
  71. }
  72. RunnersDir = clean("OLLAMA_RUNNERS_DIR")
  73. if runtime.GOOS == "windows" && RunnersDir == "" {
  74. // On Windows we do not carry the payloads inside the main executable
  75. appExe, err := os.Executable()
  76. if err != nil {
  77. slog.Error("failed to lookup executable path", "error", err)
  78. }
  79. cwd, err := os.Getwd()
  80. if err != nil {
  81. slog.Error("failed to lookup working directory", "error", err)
  82. }
  83. var paths []string
  84. for _, root := range []string{filepath.Dir(appExe), cwd} {
  85. paths = append(paths,
  86. filepath.Join(root),
  87. filepath.Join(root, "windows-"+runtime.GOARCH),
  88. filepath.Join(root, "dist", "windows-"+runtime.GOARCH),
  89. )
  90. }
  91. // Try a few variations to improve developer experience when building from source in the local tree
  92. for _, p := range paths {
  93. candidate := filepath.Join(p, "ollama_runners")
  94. _, err := os.Stat(candidate)
  95. if err == nil {
  96. RunnersDir = candidate
  97. break
  98. }
  99. }
  100. if RunnersDir == "" {
  101. slog.Error("unable to locate llm runner directory. Set OLLAMA_RUNNERS_DIR to the location of 'ollama_runners'")
  102. }
  103. }
  104. TmpDir = clean("OLLAMA_TMPDIR")
  105. userLimit := clean("OLLAMA_MAX_VRAM")
  106. if userLimit != "" {
  107. avail, err := strconv.ParseUint(userLimit, 10, 64)
  108. if err != nil {
  109. slog.Error("invalid setting, ignoring", "OLLAMA_MAX_VRAM", userLimit, "error", err)
  110. } else {
  111. MaxVRAM = avail
  112. }
  113. }
  114. LLMLibrary = clean("OLLAMA_LLM_LIBRARY")
  115. if onp := clean("OLLAMA_NUM_PARALLEL"); onp != "" {
  116. val, err := strconv.Atoi(onp)
  117. if err != nil || val <= 0 {
  118. slog.Error("invalid setting must be greater than zero", "OLLAMA_NUM_PARALLEL", onp, "error", err)
  119. } else {
  120. NumParallel = val
  121. }
  122. }
  123. if noprune := clean("OLLAMA_NOPRUNE"); noprune != "" {
  124. NoPrune = true
  125. }
  126. if origins := clean("OLLAMA_ORIGINS"); origins != "" {
  127. AllowOrigins = strings.Split(origins, ",")
  128. }
  129. for _, allowOrigin := range defaultAllowOrigins {
  130. AllowOrigins = append(AllowOrigins,
  131. fmt.Sprintf("http://%s", allowOrigin),
  132. fmt.Sprintf("https://%s", allowOrigin),
  133. fmt.Sprintf("http://%s:*", allowOrigin),
  134. fmt.Sprintf("https://%s:*", allowOrigin),
  135. )
  136. }
  137. maxRunners := clean("OLLAMA_MAX_LOADED_MODELS")
  138. if maxRunners != "" {
  139. m, err := strconv.Atoi(maxRunners)
  140. if err != nil {
  141. slog.Error("invalid setting", "OLLAMA_MAX_LOADED_MODELS", maxRunners, "error", err)
  142. } else {
  143. MaxRunners = m
  144. }
  145. }
  146. if onp := os.Getenv("OLLAMA_MAX_QUEUE"); onp != "" {
  147. p, err := strconv.Atoi(onp)
  148. if err != nil || p <= 0 {
  149. slog.Error("invalid setting", "OLLAMA_MAX_QUEUE", onp, "error", err)
  150. } else {
  151. MaxQueuedRequests = p
  152. }
  153. }
  154. }