cmd.go 30 KB

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