cmd.go 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. package cmd
  2. import (
  3. "bufio"
  4. "context"
  5. "crypto/ed25519"
  6. "crypto/rand"
  7. "encoding/json"
  8. "encoding/pem"
  9. "errors"
  10. "fmt"
  11. "io"
  12. "log"
  13. "math"
  14. "net"
  15. "net/http"
  16. "os"
  17. "os/signal"
  18. "path/filepath"
  19. "runtime"
  20. "strconv"
  21. "strings"
  22. "sync/atomic"
  23. "syscall"
  24. "time"
  25. "github.com/containerd/console"
  26. "github.com/mattn/go-runewidth"
  27. "github.com/olekukonko/tablewriter"
  28. "github.com/spf13/cobra"
  29. "golang.org/x/crypto/ssh"
  30. "golang.org/x/term"
  31. "github.com/ollama/ollama/api"
  32. "github.com/ollama/ollama/envconfig"
  33. "github.com/ollama/ollama/format"
  34. "github.com/ollama/ollama/llama"
  35. "github.com/ollama/ollama/parser"
  36. "github.com/ollama/ollama/progress"
  37. "github.com/ollama/ollama/runner"
  38. "github.com/ollama/ollama/server"
  39. "github.com/ollama/ollama/types/model"
  40. "github.com/ollama/ollama/version"
  41. )
  42. var errModelfileNotFound = errors.New("specified Modelfile wasn't found")
  43. func getModelfileName(cmd *cobra.Command) (string, error) {
  44. filename, _ := cmd.Flags().GetString("file")
  45. if filename == "" {
  46. filename = "Modelfile"
  47. }
  48. absName, err := filepath.Abs(filename)
  49. if err != nil {
  50. return "", err
  51. }
  52. _, err = os.Stat(absName)
  53. if err != nil {
  54. return "", err
  55. }
  56. return absName, nil
  57. }
  58. func CreateHandler(cmd *cobra.Command, args []string) error {
  59. p := progress.NewProgress(os.Stderr)
  60. defer p.Stop()
  61. var reader io.Reader
  62. filename, err := getModelfileName(cmd)
  63. if os.IsNotExist(err) {
  64. if filename == "" {
  65. reader = strings.NewReader("FROM .\n")
  66. } else {
  67. return errModelfileNotFound
  68. }
  69. } else if err != nil {
  70. return err
  71. } else {
  72. f, err := os.Open(filename)
  73. if err != nil {
  74. return err
  75. }
  76. reader = f
  77. defer f.Close()
  78. }
  79. modelfile, err := parser.ParseFile(reader)
  80. if err != nil {
  81. return err
  82. }
  83. status := "gathering model components"
  84. spinner := progress.NewSpinner(status)
  85. p.Add(status, spinner)
  86. req, err := modelfile.CreateRequest(filepath.Dir(filename))
  87. if err != nil {
  88. return err
  89. }
  90. spinner.Stop()
  91. req.Name = args[0]
  92. quantize, _ := cmd.Flags().GetString("quantize")
  93. if quantize != "" {
  94. req.Quantize = quantize
  95. }
  96. client, err := api.ClientFromEnvironment()
  97. if err != nil {
  98. return err
  99. }
  100. if len(req.Files) > 0 {
  101. fileMap := map[string]string{}
  102. for f, digest := range req.Files {
  103. if _, err := createBlob(cmd, client, f, digest, p); err != nil {
  104. return err
  105. }
  106. fileMap[filepath.Base(f)] = digest
  107. }
  108. req.Files = fileMap
  109. }
  110. if len(req.Adapters) > 0 {
  111. fileMap := map[string]string{}
  112. for f, digest := range req.Adapters {
  113. if _, err := createBlob(cmd, client, f, digest, p); err != nil {
  114. return err
  115. }
  116. fileMap[filepath.Base(f)] = digest
  117. }
  118. req.Adapters = fileMap
  119. }
  120. bars := make(map[string]*progress.Bar)
  121. fn := func(resp api.ProgressResponse) error {
  122. if resp.Digest != "" {
  123. bar, ok := bars[resp.Digest]
  124. if !ok {
  125. bar = progress.NewBar(fmt.Sprintf("pulling %s...", resp.Digest[7:19]), resp.Total, resp.Completed)
  126. bars[resp.Digest] = bar
  127. p.Add(resp.Digest, bar)
  128. }
  129. bar.Set(resp.Completed)
  130. } else if status != resp.Status {
  131. spinner.Stop()
  132. status = resp.Status
  133. spinner = progress.NewSpinner(status)
  134. p.Add(status, spinner)
  135. }
  136. return nil
  137. }
  138. if err := client.Create(cmd.Context(), req, fn); err != nil {
  139. if strings.Contains(err.Error(), "path or Modelfile are required") {
  140. return fmt.Errorf("the ollama server must be updated to use `ollama create` with this client")
  141. }
  142. return err
  143. }
  144. return nil
  145. }
  146. func createBlob(cmd *cobra.Command, client *api.Client, path string, digest string, p *progress.Progress) (string, error) {
  147. realPath, err := filepath.EvalSymlinks(path)
  148. if err != nil {
  149. return "", err
  150. }
  151. bin, err := os.Open(realPath)
  152. if err != nil {
  153. return "", err
  154. }
  155. defer bin.Close()
  156. // Get file info to retrieve the size
  157. fileInfo, err := bin.Stat()
  158. if err != nil {
  159. return "", err
  160. }
  161. fileSize := fileInfo.Size()
  162. var pw progressWriter
  163. status := fmt.Sprintf("copying file %s 0%%", digest)
  164. spinner := progress.NewSpinner(status)
  165. p.Add(status, spinner)
  166. defer spinner.Stop()
  167. done := make(chan struct{})
  168. defer close(done)
  169. go func() {
  170. ticker := time.NewTicker(60 * time.Millisecond)
  171. defer ticker.Stop()
  172. for {
  173. select {
  174. case <-ticker.C:
  175. spinner.SetMessage(fmt.Sprintf("copying file %s %d%%", digest, int(100*pw.n.Load()/fileSize)))
  176. case <-done:
  177. spinner.SetMessage(fmt.Sprintf("copying file %s 100%%", digest))
  178. return
  179. }
  180. }
  181. }()
  182. if err = client.CreateBlob(cmd.Context(), digest, io.TeeReader(bin, &pw)); err != nil {
  183. return "", err
  184. }
  185. return digest, nil
  186. }
  187. type progressWriter struct {
  188. n atomic.Int64
  189. }
  190. func (w *progressWriter) Write(p []byte) (n int, err error) {
  191. w.n.Add(int64(len(p)))
  192. return len(p), nil
  193. }
  194. func loadOrUnloadModel(cmd *cobra.Command, opts *runOptions) error {
  195. p := progress.NewProgress(os.Stderr)
  196. defer p.StopAndClear()
  197. spinner := progress.NewSpinner("")
  198. p.Add("", spinner)
  199. client, err := api.ClientFromEnvironment()
  200. if err != nil {
  201. return err
  202. }
  203. req := &api.GenerateRequest{
  204. Model: opts.Model,
  205. KeepAlive: opts.KeepAlive,
  206. }
  207. return client.Generate(cmd.Context(), req, func(api.GenerateResponse) error { return nil })
  208. }
  209. func StopHandler(cmd *cobra.Command, args []string) error {
  210. opts := &runOptions{
  211. Model: args[0],
  212. KeepAlive: &api.Duration{Duration: 0},
  213. }
  214. if err := loadOrUnloadModel(cmd, opts); err != nil {
  215. if strings.Contains(err.Error(), "not found") {
  216. return fmt.Errorf("couldn't find model \"%s\" to stop", args[0])
  217. }
  218. }
  219. return nil
  220. }
  221. func RunHandler(cmd *cobra.Command, args []string) error {
  222. interactive := true
  223. opts := runOptions{
  224. Model: args[0],
  225. WordWrap: os.Getenv("TERM") == "xterm-256color",
  226. Options: map[string]interface{}{},
  227. }
  228. format, err := cmd.Flags().GetString("format")
  229. if err != nil {
  230. return err
  231. }
  232. opts.Format = format
  233. keepAlive, err := cmd.Flags().GetString("keepalive")
  234. if err != nil {
  235. return err
  236. }
  237. if keepAlive != "" {
  238. d, err := time.ParseDuration(keepAlive)
  239. if err != nil {
  240. return err
  241. }
  242. opts.KeepAlive = &api.Duration{Duration: d}
  243. }
  244. prompts := args[1:]
  245. // prepend stdin to the prompt if provided
  246. if !term.IsTerminal(int(os.Stdin.Fd())) {
  247. in, err := io.ReadAll(os.Stdin)
  248. if err != nil {
  249. return err
  250. }
  251. prompts = append([]string{string(in)}, prompts...)
  252. opts.WordWrap = false
  253. interactive = false
  254. }
  255. opts.Prompt = strings.Join(prompts, " ")
  256. if len(prompts) > 0 {
  257. interactive = false
  258. }
  259. // Be quiet if we're redirecting to a pipe or file
  260. if !term.IsTerminal(int(os.Stdout.Fd())) {
  261. interactive = false
  262. }
  263. nowrap, err := cmd.Flags().GetBool("nowordwrap")
  264. if err != nil {
  265. return err
  266. }
  267. opts.WordWrap = !nowrap
  268. // Fill out the rest of the options based on information about the
  269. // model.
  270. client, err := api.ClientFromEnvironment()
  271. if err != nil {
  272. return err
  273. }
  274. name := args[0]
  275. info, err := func() (*api.ShowResponse, error) {
  276. showReq := &api.ShowRequest{Name: name}
  277. info, err := client.Show(cmd.Context(), showReq)
  278. var se api.StatusError
  279. if errors.As(err, &se) && se.StatusCode == http.StatusNotFound {
  280. if err := PullHandler(cmd, []string{name}); err != nil {
  281. return nil, err
  282. }
  283. return client.Show(cmd.Context(), &api.ShowRequest{Name: name})
  284. }
  285. return info, err
  286. }()
  287. if err != nil {
  288. return err
  289. }
  290. // TODO(jessegross): We should either find another way to know if this is
  291. // a vision model or remove the logic. Also consider that other modalities will
  292. // need different behavior anyways.
  293. opts.MultiModal = len(info.ProjectorInfo) != 0 || envconfig.NewEngine()
  294. opts.ParentModel = info.Details.ParentModel
  295. if interactive {
  296. if err := loadOrUnloadModel(cmd, &opts); err != nil {
  297. return err
  298. }
  299. for _, msg := range info.Messages {
  300. switch msg.Role {
  301. case "user":
  302. fmt.Printf(">>> %s\n", msg.Content)
  303. case "assistant":
  304. state := &displayResponseState{}
  305. displayResponse(msg.Content, opts.WordWrap, state)
  306. fmt.Println()
  307. fmt.Println()
  308. }
  309. }
  310. return generateInteractive(cmd, opts)
  311. }
  312. return generate(cmd, opts)
  313. }
  314. func PushHandler(cmd *cobra.Command, args []string) error {
  315. client, err := api.ClientFromEnvironment()
  316. if err != nil {
  317. return err
  318. }
  319. insecure, err := cmd.Flags().GetBool("insecure")
  320. if err != nil {
  321. return err
  322. }
  323. p := progress.NewProgress(os.Stderr)
  324. defer p.Stop()
  325. bars := make(map[string]*progress.Bar)
  326. var status string
  327. var spinner *progress.Spinner
  328. fn := func(resp api.ProgressResponse) error {
  329. if resp.Digest != "" {
  330. if spinner != nil {
  331. spinner.Stop()
  332. }
  333. bar, ok := bars[resp.Digest]
  334. if !ok {
  335. bar = progress.NewBar(fmt.Sprintf("pushing %s...", resp.Digest[7:19]), resp.Total, resp.Completed)
  336. bars[resp.Digest] = bar
  337. p.Add(resp.Digest, bar)
  338. }
  339. bar.Set(resp.Completed)
  340. } else if status != resp.Status {
  341. if spinner != nil {
  342. spinner.Stop()
  343. }
  344. status = resp.Status
  345. spinner = progress.NewSpinner(status)
  346. p.Add(status, spinner)
  347. }
  348. return nil
  349. }
  350. request := api.PushRequest{Name: args[0], Insecure: insecure}
  351. n := model.ParseName(args[0])
  352. if err := client.Push(cmd.Context(), &request, fn); err != nil {
  353. if spinner != nil {
  354. spinner.Stop()
  355. }
  356. if strings.Contains(err.Error(), "access denied") {
  357. return errors.New("you are not authorized to push to this namespace, create the model under a namespace you own")
  358. }
  359. return err
  360. }
  361. p.Stop()
  362. spinner.Stop()
  363. destination := n.String()
  364. if strings.HasSuffix(n.Host, ".ollama.ai") || strings.HasSuffix(n.Host, ".ollama.com") {
  365. destination = "https://ollama.com/" + strings.TrimSuffix(n.DisplayShortest(), ":latest")
  366. }
  367. fmt.Printf("\nYou can find your model at:\n\n")
  368. fmt.Printf("\t%s\n", destination)
  369. return nil
  370. }
  371. func ListHandler(cmd *cobra.Command, args []string) error {
  372. client, err := api.ClientFromEnvironment()
  373. if err != nil {
  374. return err
  375. }
  376. models, err := client.List(cmd.Context())
  377. if err != nil {
  378. return err
  379. }
  380. var data [][]string
  381. for _, m := range models.Models {
  382. if len(args) == 0 || strings.HasPrefix(strings.ToLower(m.Name), strings.ToLower(args[0])) {
  383. data = append(data, []string{m.Name, m.Digest[:12], format.HumanBytes(m.Size), format.HumanTime(m.ModifiedAt, "Never")})
  384. }
  385. }
  386. table := tablewriter.NewWriter(os.Stdout)
  387. table.SetHeader([]string{"NAME", "ID", "SIZE", "MODIFIED"})
  388. table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
  389. table.SetAlignment(tablewriter.ALIGN_LEFT)
  390. table.SetHeaderLine(false)
  391. table.SetBorder(false)
  392. table.SetNoWhiteSpace(true)
  393. table.SetTablePadding(" ")
  394. table.AppendBulk(data)
  395. table.Render()
  396. return nil
  397. }
  398. func ListRunningHandler(cmd *cobra.Command, args []string) error {
  399. client, err := api.ClientFromEnvironment()
  400. if err != nil {
  401. return err
  402. }
  403. models, err := client.ListRunning(cmd.Context())
  404. if err != nil {
  405. return err
  406. }
  407. var data [][]string
  408. for _, m := range models.Models {
  409. if len(args) == 0 || strings.HasPrefix(m.Name, args[0]) {
  410. var procStr string
  411. switch {
  412. case m.SizeVRAM == 0:
  413. procStr = "100% CPU"
  414. case m.SizeVRAM == m.Size:
  415. procStr = "100% GPU"
  416. case m.SizeVRAM > m.Size || m.Size == 0:
  417. procStr = "Unknown"
  418. default:
  419. sizeCPU := m.Size - m.SizeVRAM
  420. cpuPercent := math.Round(float64(sizeCPU) / float64(m.Size) * 100)
  421. procStr = fmt.Sprintf("%d%%/%d%% CPU/GPU", int(cpuPercent), int(100-cpuPercent))
  422. }
  423. var until string
  424. delta := time.Since(m.ExpiresAt)
  425. if delta > 0 {
  426. until = "Stopping..."
  427. } else {
  428. until = format.HumanTime(m.ExpiresAt, "Never")
  429. }
  430. data = append(data, []string{m.Name, m.Digest[:12], format.HumanBytes(m.Size), procStr, until})
  431. }
  432. }
  433. table := tablewriter.NewWriter(os.Stdout)
  434. table.SetHeader([]string{"NAME", "ID", "SIZE", "PROCESSOR", "UNTIL"})
  435. table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
  436. table.SetAlignment(tablewriter.ALIGN_LEFT)
  437. table.SetHeaderLine(false)
  438. table.SetBorder(false)
  439. table.SetNoWhiteSpace(true)
  440. table.SetTablePadding(" ")
  441. table.AppendBulk(data)
  442. table.Render()
  443. return nil
  444. }
  445. func DeleteHandler(cmd *cobra.Command, args []string) error {
  446. client, err := api.ClientFromEnvironment()
  447. if err != nil {
  448. return err
  449. }
  450. // Unload the model if it's running before deletion
  451. opts := &runOptions{
  452. Model: args[0],
  453. KeepAlive: &api.Duration{Duration: 0},
  454. }
  455. if err := loadOrUnloadModel(cmd, opts); err != nil {
  456. if !strings.Contains(err.Error(), "not found") {
  457. return fmt.Errorf("unable to stop existing running model \"%s\": %s", args[0], err)
  458. }
  459. }
  460. for _, name := range args {
  461. req := api.DeleteRequest{Name: name}
  462. if err := client.Delete(cmd.Context(), &req); err != nil {
  463. return err
  464. }
  465. fmt.Printf("deleted '%s'\n", name)
  466. }
  467. return nil
  468. }
  469. func ShowHandler(cmd *cobra.Command, args []string) error {
  470. client, err := api.ClientFromEnvironment()
  471. if err != nil {
  472. return err
  473. }
  474. license, errLicense := cmd.Flags().GetBool("license")
  475. modelfile, errModelfile := cmd.Flags().GetBool("modelfile")
  476. parameters, errParams := cmd.Flags().GetBool("parameters")
  477. system, errSystem := cmd.Flags().GetBool("system")
  478. template, errTemplate := cmd.Flags().GetBool("template")
  479. for _, boolErr := range []error{errLicense, errModelfile, errParams, errSystem, errTemplate} {
  480. if boolErr != nil {
  481. return errors.New("error retrieving flags")
  482. }
  483. }
  484. flagsSet := 0
  485. showType := ""
  486. if license {
  487. flagsSet++
  488. showType = "license"
  489. }
  490. if modelfile {
  491. flagsSet++
  492. showType = "modelfile"
  493. }
  494. if parameters {
  495. flagsSet++
  496. showType = "parameters"
  497. }
  498. if system {
  499. flagsSet++
  500. showType = "system"
  501. }
  502. if template {
  503. flagsSet++
  504. showType = "template"
  505. }
  506. if flagsSet > 1 {
  507. return errors.New("only one of '--license', '--modelfile', '--parameters', '--system', or '--template' can be specified")
  508. }
  509. req := api.ShowRequest{Name: args[0]}
  510. resp, err := client.Show(cmd.Context(), &req)
  511. if err != nil {
  512. return err
  513. }
  514. if flagsSet == 1 {
  515. switch showType {
  516. case "license":
  517. fmt.Println(resp.License)
  518. case "modelfile":
  519. fmt.Println(resp.Modelfile)
  520. case "parameters":
  521. fmt.Println(resp.Parameters)
  522. case "system":
  523. fmt.Print(resp.System)
  524. case "template":
  525. fmt.Print(resp.Template)
  526. }
  527. return nil
  528. }
  529. return showInfo(resp, os.Stdout)
  530. }
  531. func showInfo(resp *api.ShowResponse, w io.Writer) error {
  532. tableRender := func(header string, rows func() [][]string) {
  533. fmt.Fprintln(w, " ", header)
  534. table := tablewriter.NewWriter(w)
  535. table.SetAlignment(tablewriter.ALIGN_LEFT)
  536. table.SetBorder(false)
  537. table.SetNoWhiteSpace(true)
  538. table.SetTablePadding(" ")
  539. switch header {
  540. case "Template", "System", "License":
  541. table.SetColWidth(100)
  542. }
  543. table.AppendBulk(rows())
  544. table.Render()
  545. fmt.Fprintln(w)
  546. }
  547. tableRender("Model", func() (rows [][]string) {
  548. if resp.ModelInfo != nil {
  549. arch := resp.ModelInfo["general.architecture"].(string)
  550. rows = append(rows, []string{"", "architecture", arch})
  551. rows = append(rows, []string{"", "parameters", format.HumanNumber(uint64(resp.ModelInfo["general.parameter_count"].(float64)))})
  552. rows = append(rows, []string{"", "context length", strconv.FormatFloat(resp.ModelInfo[fmt.Sprintf("%s.context_length", arch)].(float64), 'f', -1, 64)})
  553. rows = append(rows, []string{"", "embedding length", strconv.FormatFloat(resp.ModelInfo[fmt.Sprintf("%s.embedding_length", arch)].(float64), 'f', -1, 64)})
  554. } else {
  555. rows = append(rows, []string{"", "architecture", resp.Details.Family})
  556. rows = append(rows, []string{"", "parameters", resp.Details.ParameterSize})
  557. }
  558. rows = append(rows, []string{"", "quantization", resp.Details.QuantizationLevel})
  559. return
  560. })
  561. if resp.ProjectorInfo != nil {
  562. tableRender("Projector", func() (rows [][]string) {
  563. arch := resp.ProjectorInfo["general.architecture"].(string)
  564. rows = append(rows, []string{"", "architecture", arch})
  565. rows = append(rows, []string{"", "parameters", format.HumanNumber(uint64(resp.ProjectorInfo["general.parameter_count"].(float64)))})
  566. rows = append(rows, []string{"", "embedding length", strconv.FormatFloat(resp.ProjectorInfo[fmt.Sprintf("%s.vision.embedding_length", arch)].(float64), 'f', -1, 64)})
  567. rows = append(rows, []string{"", "dimensions", strconv.FormatFloat(resp.ProjectorInfo[fmt.Sprintf("%s.vision.projection_dim", arch)].(float64), 'f', -1, 64)})
  568. return
  569. })
  570. }
  571. if resp.Parameters != "" {
  572. tableRender("Parameters", func() (rows [][]string) {
  573. scanner := bufio.NewScanner(strings.NewReader(resp.Parameters))
  574. for scanner.Scan() {
  575. if text := scanner.Text(); text != "" {
  576. rows = append(rows, append([]string{""}, strings.Fields(text)...))
  577. }
  578. }
  579. return
  580. })
  581. }
  582. head := func(s string, n int) (rows [][]string) {
  583. scanner := bufio.NewScanner(strings.NewReader(s))
  584. for scanner.Scan() && (len(rows) < n || n < 0) {
  585. if text := scanner.Text(); text != "" {
  586. rows = append(rows, []string{"", strings.TrimSpace(text)})
  587. }
  588. }
  589. return
  590. }
  591. if resp.System != "" {
  592. tableRender("System", func() [][]string {
  593. return head(resp.System, 2)
  594. })
  595. }
  596. if resp.License != "" {
  597. tableRender("License", func() [][]string {
  598. return head(resp.License, 2)
  599. })
  600. }
  601. return nil
  602. }
  603. func CopyHandler(cmd *cobra.Command, args []string) error {
  604. client, err := api.ClientFromEnvironment()
  605. if err != nil {
  606. return err
  607. }
  608. req := api.CopyRequest{Source: args[0], Destination: args[1]}
  609. if err := client.Copy(cmd.Context(), &req); err != nil {
  610. return err
  611. }
  612. fmt.Printf("copied '%s' to '%s'\n", args[0], args[1])
  613. return nil
  614. }
  615. func PullHandler(cmd *cobra.Command, args []string) error {
  616. insecure, err := cmd.Flags().GetBool("insecure")
  617. if err != nil {
  618. return err
  619. }
  620. client, err := api.ClientFromEnvironment()
  621. if err != nil {
  622. return err
  623. }
  624. p := progress.NewProgress(os.Stderr)
  625. defer p.Stop()
  626. bars := make(map[string]*progress.Bar)
  627. var status string
  628. var spinner *progress.Spinner
  629. fn := func(resp api.ProgressResponse) error {
  630. if resp.Digest != "" {
  631. if spinner != nil {
  632. spinner.Stop()
  633. }
  634. bar, ok := bars[resp.Digest]
  635. if !ok {
  636. bar = progress.NewBar(fmt.Sprintf("pulling %s...", resp.Digest[7:19]), resp.Total, resp.Completed)
  637. bars[resp.Digest] = bar
  638. p.Add(resp.Digest, bar)
  639. }
  640. bar.Set(resp.Completed)
  641. } else if status != resp.Status {
  642. if spinner != nil {
  643. spinner.Stop()
  644. }
  645. status = resp.Status
  646. spinner = progress.NewSpinner(status)
  647. p.Add(status, spinner)
  648. }
  649. return nil
  650. }
  651. request := api.PullRequest{Name: args[0], Insecure: insecure}
  652. if err := client.Pull(cmd.Context(), &request, fn); err != nil {
  653. return err
  654. }
  655. return nil
  656. }
  657. type generateContextKey string
  658. type runOptions struct {
  659. Model string
  660. ParentModel string
  661. Prompt string
  662. Messages []api.Message
  663. WordWrap bool
  664. Format string
  665. System string
  666. Images []api.ImageData
  667. Options map[string]interface{}
  668. MultiModal bool
  669. KeepAlive *api.Duration
  670. }
  671. type displayResponseState struct {
  672. lineLength int
  673. wordBuffer string
  674. }
  675. func displayResponse(content string, wordWrap bool, state *displayResponseState) {
  676. termWidth, _, _ := term.GetSize(int(os.Stdout.Fd()))
  677. if wordWrap && termWidth >= 10 {
  678. for _, ch := range content {
  679. if state.lineLength+1 > termWidth-5 {
  680. if runewidth.StringWidth(state.wordBuffer) > termWidth-10 {
  681. fmt.Printf("%s%c", state.wordBuffer, ch)
  682. state.wordBuffer = ""
  683. state.lineLength = 0
  684. continue
  685. }
  686. // backtrack the length of the last word and clear to the end of the line
  687. a := runewidth.StringWidth(state.wordBuffer)
  688. if a > 0 {
  689. fmt.Printf("\x1b[%dD", a)
  690. }
  691. fmt.Printf("\x1b[K\n")
  692. fmt.Printf("%s%c", state.wordBuffer, ch)
  693. chWidth := runewidth.RuneWidth(ch)
  694. state.lineLength = runewidth.StringWidth(state.wordBuffer) + chWidth
  695. } else {
  696. fmt.Print(string(ch))
  697. state.lineLength += runewidth.RuneWidth(ch)
  698. if runewidth.RuneWidth(ch) >= 2 {
  699. state.wordBuffer = ""
  700. continue
  701. }
  702. switch ch {
  703. case ' ':
  704. state.wordBuffer = ""
  705. case '\n':
  706. state.lineLength = 0
  707. default:
  708. state.wordBuffer += string(ch)
  709. }
  710. }
  711. }
  712. } else {
  713. fmt.Printf("%s%s", state.wordBuffer, content)
  714. if len(state.wordBuffer) > 0 {
  715. state.wordBuffer = ""
  716. }
  717. }
  718. }
  719. func chat(cmd *cobra.Command, opts runOptions) (*api.Message, error) {
  720. client, err := api.ClientFromEnvironment()
  721. if err != nil {
  722. return nil, err
  723. }
  724. p := progress.NewProgress(os.Stderr)
  725. defer p.StopAndClear()
  726. spinner := progress.NewSpinner("")
  727. p.Add("", spinner)
  728. cancelCtx, cancel := context.WithCancel(cmd.Context())
  729. defer cancel()
  730. sigChan := make(chan os.Signal, 1)
  731. signal.Notify(sigChan, syscall.SIGINT)
  732. go func() {
  733. <-sigChan
  734. cancel()
  735. }()
  736. var state *displayResponseState = &displayResponseState{}
  737. var latest api.ChatResponse
  738. var fullResponse strings.Builder
  739. var role string
  740. fn := func(response api.ChatResponse) error {
  741. p.StopAndClear()
  742. latest = response
  743. role = response.Message.Role
  744. content := response.Message.Content
  745. fullResponse.WriteString(content)
  746. displayResponse(content, opts.WordWrap, state)
  747. return nil
  748. }
  749. if opts.Format == "json" {
  750. opts.Format = `"` + opts.Format + `"`
  751. }
  752. req := &api.ChatRequest{
  753. Model: opts.Model,
  754. Messages: opts.Messages,
  755. Format: json.RawMessage(opts.Format),
  756. Options: opts.Options,
  757. }
  758. if opts.KeepAlive != nil {
  759. req.KeepAlive = opts.KeepAlive
  760. }
  761. if err := client.Chat(cancelCtx, req, fn); err != nil {
  762. if errors.Is(err, context.Canceled) {
  763. return nil, nil
  764. }
  765. return nil, err
  766. }
  767. if len(opts.Messages) > 0 {
  768. fmt.Println()
  769. fmt.Println()
  770. }
  771. verbose, err := cmd.Flags().GetBool("verbose")
  772. if err != nil {
  773. return nil, err
  774. }
  775. if verbose {
  776. latest.Summary()
  777. }
  778. return &api.Message{Role: role, Content: fullResponse.String()}, nil
  779. }
  780. func generate(cmd *cobra.Command, opts runOptions) error {
  781. client, err := api.ClientFromEnvironment()
  782. if err != nil {
  783. return err
  784. }
  785. p := progress.NewProgress(os.Stderr)
  786. defer p.StopAndClear()
  787. spinner := progress.NewSpinner("")
  788. p.Add("", spinner)
  789. var latest api.GenerateResponse
  790. generateContext, ok := cmd.Context().Value(generateContextKey("context")).([]int)
  791. if !ok {
  792. generateContext = []int{}
  793. }
  794. ctx, cancel := context.WithCancel(cmd.Context())
  795. defer cancel()
  796. sigChan := make(chan os.Signal, 1)
  797. signal.Notify(sigChan, syscall.SIGINT)
  798. go func() {
  799. <-sigChan
  800. cancel()
  801. }()
  802. var state *displayResponseState = &displayResponseState{}
  803. fn := func(response api.GenerateResponse) error {
  804. p.StopAndClear()
  805. latest = response
  806. content := response.Response
  807. displayResponse(content, opts.WordWrap, state)
  808. return nil
  809. }
  810. if opts.MultiModal {
  811. opts.Prompt, opts.Images, err = extractFileData(opts.Prompt)
  812. if err != nil {
  813. return err
  814. }
  815. }
  816. if opts.Format == "json" {
  817. opts.Format = `"` + opts.Format + `"`
  818. }
  819. request := api.GenerateRequest{
  820. Model: opts.Model,
  821. Prompt: opts.Prompt,
  822. Context: generateContext,
  823. Images: opts.Images,
  824. Format: json.RawMessage(opts.Format),
  825. System: opts.System,
  826. Options: opts.Options,
  827. KeepAlive: opts.KeepAlive,
  828. }
  829. if err := client.Generate(ctx, &request, fn); err != nil {
  830. if errors.Is(err, context.Canceled) {
  831. return nil
  832. }
  833. return err
  834. }
  835. if opts.Prompt != "" {
  836. fmt.Println()
  837. fmt.Println()
  838. }
  839. if !latest.Done {
  840. return nil
  841. }
  842. verbose, err := cmd.Flags().GetBool("verbose")
  843. if err != nil {
  844. return err
  845. }
  846. if verbose {
  847. latest.Summary()
  848. }
  849. ctx = context.WithValue(cmd.Context(), generateContextKey("context"), latest.Context)
  850. cmd.SetContext(ctx)
  851. return nil
  852. }
  853. func RunServer(_ *cobra.Command, _ []string) error {
  854. if err := initializeKeypair(); err != nil {
  855. return err
  856. }
  857. ln, err := net.Listen("tcp", envconfig.Host().Host)
  858. if err != nil {
  859. return err
  860. }
  861. err = server.Serve(ln)
  862. if errors.Is(err, http.ErrServerClosed) {
  863. return nil
  864. }
  865. return err
  866. }
  867. func initializeKeypair() error {
  868. home, err := os.UserHomeDir()
  869. if err != nil {
  870. return err
  871. }
  872. privKeyPath := filepath.Join(home, ".ollama", "id_ed25519")
  873. pubKeyPath := filepath.Join(home, ".ollama", "id_ed25519.pub")
  874. _, err = os.Stat(privKeyPath)
  875. if os.IsNotExist(err) {
  876. fmt.Printf("Couldn't find '%s'. Generating new private key.\n", privKeyPath)
  877. cryptoPublicKey, cryptoPrivateKey, err := ed25519.GenerateKey(rand.Reader)
  878. if err != nil {
  879. return err
  880. }
  881. privateKeyBytes, err := ssh.MarshalPrivateKey(cryptoPrivateKey, "")
  882. if err != nil {
  883. return err
  884. }
  885. if err := os.MkdirAll(filepath.Dir(privKeyPath), 0o755); err != nil {
  886. return fmt.Errorf("could not create directory %w", err)
  887. }
  888. if err := os.WriteFile(privKeyPath, pem.EncodeToMemory(privateKeyBytes), 0o600); err != nil {
  889. return err
  890. }
  891. sshPublicKey, err := ssh.NewPublicKey(cryptoPublicKey)
  892. if err != nil {
  893. return err
  894. }
  895. publicKeyBytes := ssh.MarshalAuthorizedKey(sshPublicKey)
  896. if err := os.WriteFile(pubKeyPath, publicKeyBytes, 0o644); err != nil {
  897. return err
  898. }
  899. fmt.Printf("Your new public key is: \n\n%s\n", publicKeyBytes)
  900. }
  901. return nil
  902. }
  903. func checkServerHeartbeat(cmd *cobra.Command, _ []string) error {
  904. client, err := api.ClientFromEnvironment()
  905. if err != nil {
  906. return err
  907. }
  908. if err := client.Heartbeat(cmd.Context()); err != nil {
  909. if !strings.Contains(err.Error(), " refused") {
  910. return err
  911. }
  912. if err := startApp(cmd.Context(), client); err != nil {
  913. return errors.New("could not connect to ollama app, is it running?")
  914. }
  915. }
  916. return nil
  917. }
  918. func versionHandler(cmd *cobra.Command, _ []string) {
  919. client, err := api.ClientFromEnvironment()
  920. if err != nil {
  921. return
  922. }
  923. serverVersion, err := client.Version(cmd.Context())
  924. if err != nil {
  925. fmt.Println("Warning: could not connect to a running Ollama instance")
  926. }
  927. if serverVersion != "" {
  928. fmt.Printf("ollama version is %s\n", serverVersion)
  929. }
  930. if serverVersion != version.Version {
  931. fmt.Printf("Warning: client version is %s\n", version.Version)
  932. }
  933. }
  934. func appendEnvDocs(cmd *cobra.Command, envs []envconfig.EnvVar) {
  935. if len(envs) == 0 {
  936. return
  937. }
  938. envUsage := `
  939. Environment Variables:
  940. `
  941. for _, e := range envs {
  942. envUsage += fmt.Sprintf(" %-24s %s\n", e.Name, e.Description)
  943. }
  944. cmd.SetUsageTemplate(cmd.UsageTemplate() + envUsage)
  945. }
  946. func NewCLI() *cobra.Command {
  947. log.SetFlags(log.LstdFlags | log.Lshortfile)
  948. cobra.EnableCommandSorting = false
  949. if runtime.GOOS == "windows" && term.IsTerminal(int(os.Stdout.Fd())) {
  950. console.ConsoleFromFile(os.Stdin) //nolint:errcheck
  951. }
  952. rootCmd := &cobra.Command{
  953. Use: "ollama",
  954. Short: "Large language model runner",
  955. SilenceUsage: true,
  956. SilenceErrors: true,
  957. CompletionOptions: cobra.CompletionOptions{
  958. DisableDefaultCmd: true,
  959. },
  960. Run: func(cmd *cobra.Command, args []string) {
  961. if version, _ := cmd.Flags().GetBool("version"); version {
  962. versionHandler(cmd, args)
  963. return
  964. }
  965. cmd.Print(cmd.UsageString())
  966. },
  967. }
  968. rootCmd.Flags().BoolP("version", "v", false, "Show version information")
  969. createCmd := &cobra.Command{
  970. Use: "create MODEL",
  971. Short: "Create a model from a Modelfile",
  972. Args: cobra.ExactArgs(1),
  973. PreRunE: checkServerHeartbeat,
  974. RunE: CreateHandler,
  975. }
  976. createCmd.Flags().StringP("file", "f", "", "Name of the Modelfile (default \"Modelfile\"")
  977. createCmd.Flags().StringP("quantize", "q", "", "Quantize model to this level (e.g. q4_0)")
  978. showCmd := &cobra.Command{
  979. Use: "show MODEL",
  980. Short: "Show information for a model",
  981. Args: cobra.ExactArgs(1),
  982. PreRunE: checkServerHeartbeat,
  983. RunE: ShowHandler,
  984. }
  985. showCmd.Flags().Bool("license", false, "Show license of a model")
  986. showCmd.Flags().Bool("modelfile", false, "Show Modelfile of a model")
  987. showCmd.Flags().Bool("parameters", false, "Show parameters of a model")
  988. showCmd.Flags().Bool("template", false, "Show template of a model")
  989. showCmd.Flags().Bool("system", false, "Show system message of a model")
  990. runCmd := &cobra.Command{
  991. Use: "run MODEL [PROMPT]",
  992. Short: "Run a model",
  993. Args: cobra.MinimumNArgs(1),
  994. PreRunE: checkServerHeartbeat,
  995. RunE: RunHandler,
  996. }
  997. runCmd.Flags().String("keepalive", "", "Duration to keep a model loaded (e.g. 5m)")
  998. runCmd.Flags().Bool("verbose", false, "Show timings for response")
  999. runCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1000. runCmd.Flags().Bool("nowordwrap", false, "Don't wrap words to the next line automatically")
  1001. runCmd.Flags().String("format", "", "Response format (e.g. json)")
  1002. stopCmd := &cobra.Command{
  1003. Use: "stop MODEL",
  1004. Short: "Stop a running model",
  1005. Args: cobra.ExactArgs(1),
  1006. PreRunE: checkServerHeartbeat,
  1007. RunE: StopHandler,
  1008. }
  1009. serveCmd := &cobra.Command{
  1010. Use: "serve",
  1011. Aliases: []string{"start"},
  1012. Short: "Start ollama",
  1013. Args: cobra.ExactArgs(0),
  1014. RunE: RunServer,
  1015. }
  1016. pullCmd := &cobra.Command{
  1017. Use: "pull MODEL",
  1018. Short: "Pull a model from a registry",
  1019. Args: cobra.ExactArgs(1),
  1020. PreRunE: checkServerHeartbeat,
  1021. RunE: PullHandler,
  1022. }
  1023. pullCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1024. pushCmd := &cobra.Command{
  1025. Use: "push MODEL",
  1026. Short: "Push a model to a registry",
  1027. Args: cobra.ExactArgs(1),
  1028. PreRunE: checkServerHeartbeat,
  1029. RunE: PushHandler,
  1030. }
  1031. pushCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1032. listCmd := &cobra.Command{
  1033. Use: "list",
  1034. Aliases: []string{"ls"},
  1035. Short: "List models",
  1036. PreRunE: checkServerHeartbeat,
  1037. RunE: ListHandler,
  1038. }
  1039. psCmd := &cobra.Command{
  1040. Use: "ps",
  1041. Short: "List running models",
  1042. PreRunE: checkServerHeartbeat,
  1043. RunE: ListRunningHandler,
  1044. }
  1045. copyCmd := &cobra.Command{
  1046. Use: "cp SOURCE DESTINATION",
  1047. Short: "Copy a model",
  1048. Args: cobra.ExactArgs(2),
  1049. PreRunE: checkServerHeartbeat,
  1050. RunE: CopyHandler,
  1051. }
  1052. deleteCmd := &cobra.Command{
  1053. Use: "rm MODEL [MODEL...]",
  1054. Short: "Remove a model",
  1055. Args: cobra.MinimumNArgs(1),
  1056. PreRunE: checkServerHeartbeat,
  1057. RunE: DeleteHandler,
  1058. }
  1059. runnerCmd := &cobra.Command{
  1060. Use: "runner",
  1061. Short: llama.PrintSystemInfo(),
  1062. Hidden: true,
  1063. RunE: func(cmd *cobra.Command, args []string) error {
  1064. return runner.Execute(os.Args[1:])
  1065. },
  1066. FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
  1067. }
  1068. runnerCmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
  1069. _ = runner.Execute(args[1:])
  1070. })
  1071. envVars := envconfig.AsMap()
  1072. envs := []envconfig.EnvVar{envVars["OLLAMA_HOST"]}
  1073. for _, cmd := range []*cobra.Command{
  1074. createCmd,
  1075. showCmd,
  1076. runCmd,
  1077. stopCmd,
  1078. pullCmd,
  1079. pushCmd,
  1080. listCmd,
  1081. psCmd,
  1082. copyCmd,
  1083. deleteCmd,
  1084. serveCmd,
  1085. } {
  1086. switch cmd {
  1087. case runCmd:
  1088. appendEnvDocs(cmd, []envconfig.EnvVar{envVars["OLLAMA_HOST"], envVars["OLLAMA_NOHISTORY"]})
  1089. case serveCmd:
  1090. appendEnvDocs(cmd, []envconfig.EnvVar{
  1091. envVars["OLLAMA_DEBUG"],
  1092. envVars["OLLAMA_HOST"],
  1093. envVars["OLLAMA_KEEP_ALIVE"],
  1094. envVars["OLLAMA_MAX_LOADED_MODELS"],
  1095. envVars["OLLAMA_MAX_QUEUE"],
  1096. envVars["OLLAMA_MODELS"],
  1097. envVars["OLLAMA_NUM_PARALLEL"],
  1098. envVars["OLLAMA_NOPRUNE"],
  1099. envVars["OLLAMA_ORIGINS"],
  1100. envVars["OLLAMA_SCHED_SPREAD"],
  1101. envVars["OLLAMA_TMPDIR"],
  1102. envVars["OLLAMA_FLASH_ATTENTION"],
  1103. envVars["OLLAMA_KV_CACHE_TYPE"],
  1104. envVars["OLLAMA_LLM_LIBRARY"],
  1105. envVars["OLLAMA_GPU_OVERHEAD"],
  1106. envVars["OLLAMA_LOAD_TIMEOUT"],
  1107. })
  1108. default:
  1109. appendEnvDocs(cmd, envs)
  1110. }
  1111. }
  1112. rootCmd.AddCommand(
  1113. serveCmd,
  1114. createCmd,
  1115. showCmd,
  1116. runCmd,
  1117. stopCmd,
  1118. pullCmd,
  1119. pushCmd,
  1120. listCmd,
  1121. psCmd,
  1122. copyCmd,
  1123. deleteCmd,
  1124. runnerCmd,
  1125. )
  1126. return rootCmd
  1127. }