cmd.go 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345
  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/llama/runner"
  36. "github.com/ollama/ollama/parser"
  37. "github.com/ollama/ollama/progress"
  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. opts.MultiModal = len(info.ProjectorInfo) != 0
  291. opts.ParentModel = info.Details.ParentModel
  292. if interactive {
  293. if err := loadOrUnloadModel(cmd, &opts); err != nil {
  294. return err
  295. }
  296. for _, msg := range info.Messages {
  297. switch msg.Role {
  298. case "user":
  299. fmt.Printf(">>> %s\n", msg.Content)
  300. case "assistant":
  301. state := &displayResponseState{}
  302. displayResponse(msg.Content, opts.WordWrap, state)
  303. fmt.Println()
  304. fmt.Println()
  305. }
  306. }
  307. return generateInteractive(cmd, opts)
  308. }
  309. return generate(cmd, opts)
  310. }
  311. func PushHandler(cmd *cobra.Command, args []string) error {
  312. client, err := api.ClientFromEnvironment()
  313. if err != nil {
  314. return err
  315. }
  316. insecure, err := cmd.Flags().GetBool("insecure")
  317. if err != nil {
  318. return err
  319. }
  320. p := progress.NewProgress(os.Stderr)
  321. defer p.Stop()
  322. bars := make(map[string]*progress.Bar)
  323. var status string
  324. var spinner *progress.Spinner
  325. fn := func(resp api.ProgressResponse) error {
  326. if resp.Digest != "" {
  327. if spinner != nil {
  328. spinner.Stop()
  329. }
  330. bar, ok := bars[resp.Digest]
  331. if !ok {
  332. bar = progress.NewBar(fmt.Sprintf("pushing %s...", resp.Digest[7:19]), resp.Total, resp.Completed)
  333. bars[resp.Digest] = bar
  334. p.Add(resp.Digest, bar)
  335. }
  336. bar.Set(resp.Completed)
  337. } else if status != resp.Status {
  338. if spinner != nil {
  339. spinner.Stop()
  340. }
  341. status = resp.Status
  342. spinner = progress.NewSpinner(status)
  343. p.Add(status, spinner)
  344. }
  345. return nil
  346. }
  347. request := api.PushRequest{Name: args[0], Insecure: insecure}
  348. n := model.ParseName(args[0])
  349. if err := client.Push(cmd.Context(), &request, fn); err != nil {
  350. if spinner != nil {
  351. spinner.Stop()
  352. }
  353. if strings.Contains(err.Error(), "access denied") {
  354. return errors.New("you are not authorized to push to this namespace, create the model under a namespace you own")
  355. }
  356. return err
  357. }
  358. p.Stop()
  359. spinner.Stop()
  360. destination := n.String()
  361. if strings.HasSuffix(n.Host, ".ollama.ai") || strings.HasSuffix(n.Host, ".ollama.com") {
  362. destination = "https://ollama.com/" + strings.TrimSuffix(n.DisplayShortest(), ":latest")
  363. }
  364. fmt.Printf("\nYou can find your model at:\n\n")
  365. fmt.Printf("\t%s\n", destination)
  366. return nil
  367. }
  368. func ListHandler(cmd *cobra.Command, args []string) error {
  369. client, err := api.ClientFromEnvironment()
  370. if err != nil {
  371. return err
  372. }
  373. models, err := client.List(cmd.Context())
  374. if err != nil {
  375. return err
  376. }
  377. var data [][]string
  378. for _, m := range models.Models {
  379. if len(args) == 0 || strings.HasPrefix(strings.ToLower(m.Name), strings.ToLower(args[0])) {
  380. data = append(data, []string{m.Name, m.Digest[:12], format.HumanBytes(m.Size), format.HumanTime(m.ModifiedAt, "Never")})
  381. }
  382. }
  383. table := tablewriter.NewWriter(os.Stdout)
  384. table.SetHeader([]string{"NAME", "ID", "SIZE", "MODIFIED"})
  385. table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
  386. table.SetAlignment(tablewriter.ALIGN_LEFT)
  387. table.SetHeaderLine(false)
  388. table.SetBorder(false)
  389. table.SetNoWhiteSpace(true)
  390. table.SetTablePadding(" ")
  391. table.AppendBulk(data)
  392. table.Render()
  393. return nil
  394. }
  395. func ListRunningHandler(cmd *cobra.Command, args []string) error {
  396. client, err := api.ClientFromEnvironment()
  397. if err != nil {
  398. return err
  399. }
  400. models, err := client.ListRunning(cmd.Context())
  401. if err != nil {
  402. return err
  403. }
  404. var data [][]string
  405. for _, m := range models.Models {
  406. if len(args) == 0 || strings.HasPrefix(m.Name, args[0]) {
  407. var procStr string
  408. switch {
  409. case m.SizeVRAM == 0:
  410. procStr = "100% CPU"
  411. case m.SizeVRAM == m.Size:
  412. procStr = "100% GPU"
  413. case m.SizeVRAM > m.Size || m.Size == 0:
  414. procStr = "Unknown"
  415. default:
  416. sizeCPU := m.Size - m.SizeVRAM
  417. cpuPercent := math.Round(float64(sizeCPU) / float64(m.Size) * 100)
  418. procStr = fmt.Sprintf("%d%%/%d%% CPU/GPU", int(cpuPercent), int(100-cpuPercent))
  419. }
  420. var until string
  421. delta := time.Since(m.ExpiresAt)
  422. if delta > 0 {
  423. until = "Stopping..."
  424. } else {
  425. until = format.HumanTime(m.ExpiresAt, "Never")
  426. }
  427. data = append(data, []string{m.Name, m.Digest[:12], format.HumanBytes(m.Size), procStr, until})
  428. }
  429. }
  430. table := tablewriter.NewWriter(os.Stdout)
  431. table.SetHeader([]string{"NAME", "ID", "SIZE", "PROCESSOR", "UNTIL"})
  432. table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
  433. table.SetAlignment(tablewriter.ALIGN_LEFT)
  434. table.SetHeaderLine(false)
  435. table.SetBorder(false)
  436. table.SetNoWhiteSpace(true)
  437. table.SetTablePadding(" ")
  438. table.AppendBulk(data)
  439. table.Render()
  440. return nil
  441. }
  442. func DeleteHandler(cmd *cobra.Command, args []string) error {
  443. client, err := api.ClientFromEnvironment()
  444. if err != nil {
  445. return err
  446. }
  447. // Unload the model if it's running before deletion
  448. opts := &runOptions{
  449. Model: args[0],
  450. KeepAlive: &api.Duration{Duration: 0},
  451. }
  452. if err := loadOrUnloadModel(cmd, opts); err != nil {
  453. if !strings.Contains(err.Error(), "not found") {
  454. return fmt.Errorf("unable to stop existing running model \"%s\": %s", args[0], err)
  455. }
  456. }
  457. for _, name := range args {
  458. req := api.DeleteRequest{Name: name}
  459. if err := client.Delete(cmd.Context(), &req); err != nil {
  460. return err
  461. }
  462. fmt.Printf("deleted '%s'\n", name)
  463. }
  464. return nil
  465. }
  466. func ShowHandler(cmd *cobra.Command, args []string) error {
  467. client, err := api.ClientFromEnvironment()
  468. if err != nil {
  469. return err
  470. }
  471. license, errLicense := cmd.Flags().GetBool("license")
  472. modelfile, errModelfile := cmd.Flags().GetBool("modelfile")
  473. parameters, errParams := cmd.Flags().GetBool("parameters")
  474. system, errSystem := cmd.Flags().GetBool("system")
  475. template, errTemplate := cmd.Flags().GetBool("template")
  476. for _, boolErr := range []error{errLicense, errModelfile, errParams, errSystem, errTemplate} {
  477. if boolErr != nil {
  478. return errors.New("error retrieving flags")
  479. }
  480. }
  481. flagsSet := 0
  482. showType := ""
  483. if license {
  484. flagsSet++
  485. showType = "license"
  486. }
  487. if modelfile {
  488. flagsSet++
  489. showType = "modelfile"
  490. }
  491. if parameters {
  492. flagsSet++
  493. showType = "parameters"
  494. }
  495. if system {
  496. flagsSet++
  497. showType = "system"
  498. }
  499. if template {
  500. flagsSet++
  501. showType = "template"
  502. }
  503. if flagsSet > 1 {
  504. return errors.New("only one of '--license', '--modelfile', '--parameters', '--system', or '--template' can be specified")
  505. }
  506. req := api.ShowRequest{Name: args[0]}
  507. resp, err := client.Show(cmd.Context(), &req)
  508. if err != nil {
  509. return err
  510. }
  511. if flagsSet == 1 {
  512. switch showType {
  513. case "license":
  514. fmt.Println(resp.License)
  515. case "modelfile":
  516. fmt.Println(resp.Modelfile)
  517. case "parameters":
  518. fmt.Println(resp.Parameters)
  519. case "system":
  520. fmt.Print(resp.System)
  521. case "template":
  522. fmt.Print(resp.Template)
  523. }
  524. return nil
  525. }
  526. return showInfo(resp, os.Stdout)
  527. }
  528. func showInfo(resp *api.ShowResponse, w io.Writer) error {
  529. tableRender := func(header string, rows func() [][]string) {
  530. fmt.Fprintln(w, " ", header)
  531. table := tablewriter.NewWriter(w)
  532. table.SetAlignment(tablewriter.ALIGN_LEFT)
  533. table.SetBorder(false)
  534. table.SetNoWhiteSpace(true)
  535. table.SetTablePadding(" ")
  536. switch header {
  537. case "Template", "System", "License":
  538. table.SetColWidth(100)
  539. }
  540. table.AppendBulk(rows())
  541. table.Render()
  542. fmt.Fprintln(w)
  543. }
  544. tableRender("Model", func() (rows [][]string) {
  545. if resp.ModelInfo != nil {
  546. arch := resp.ModelInfo["general.architecture"].(string)
  547. rows = append(rows, []string{"", "architecture", arch})
  548. rows = append(rows, []string{"", "parameters", format.HumanNumber(uint64(resp.ModelInfo["general.parameter_count"].(float64)))})
  549. rows = append(rows, []string{"", "context length", strconv.FormatFloat(resp.ModelInfo[fmt.Sprintf("%s.context_length", arch)].(float64), 'f', -1, 64)})
  550. rows = append(rows, []string{"", "embedding length", strconv.FormatFloat(resp.ModelInfo[fmt.Sprintf("%s.embedding_length", arch)].(float64), 'f', -1, 64)})
  551. } else {
  552. rows = append(rows, []string{"", "architecture", resp.Details.Family})
  553. rows = append(rows, []string{"", "parameters", resp.Details.ParameterSize})
  554. }
  555. rows = append(rows, []string{"", "quantization", resp.Details.QuantizationLevel})
  556. return
  557. })
  558. if resp.ProjectorInfo != nil {
  559. tableRender("Projector", func() (rows [][]string) {
  560. arch := resp.ProjectorInfo["general.architecture"].(string)
  561. rows = append(rows, []string{"", "architecture", arch})
  562. rows = append(rows, []string{"", "parameters", format.HumanNumber(uint64(resp.ProjectorInfo["general.parameter_count"].(float64)))})
  563. rows = append(rows, []string{"", "embedding length", strconv.FormatFloat(resp.ProjectorInfo[fmt.Sprintf("%s.vision.embedding_length", arch)].(float64), 'f', -1, 64)})
  564. rows = append(rows, []string{"", "dimensions", strconv.FormatFloat(resp.ProjectorInfo[fmt.Sprintf("%s.vision.projection_dim", arch)].(float64), 'f', -1, 64)})
  565. return
  566. })
  567. }
  568. if resp.Parameters != "" {
  569. tableRender("Parameters", func() (rows [][]string) {
  570. scanner := bufio.NewScanner(strings.NewReader(resp.Parameters))
  571. for scanner.Scan() {
  572. if text := scanner.Text(); text != "" {
  573. rows = append(rows, append([]string{""}, strings.Fields(text)...))
  574. }
  575. }
  576. return
  577. })
  578. }
  579. head := func(s string, n int) (rows [][]string) {
  580. scanner := bufio.NewScanner(strings.NewReader(s))
  581. for scanner.Scan() && (len(rows) < n || n < 0) {
  582. if text := scanner.Text(); text != "" {
  583. rows = append(rows, []string{"", strings.TrimSpace(text)})
  584. }
  585. }
  586. return
  587. }
  588. if resp.System != "" {
  589. tableRender("System", func() [][]string {
  590. return head(resp.System, 2)
  591. })
  592. }
  593. if resp.License != "" {
  594. tableRender("License", func() [][]string {
  595. return head(resp.License, 2)
  596. })
  597. }
  598. return nil
  599. }
  600. func CopyHandler(cmd *cobra.Command, args []string) error {
  601. client, err := api.ClientFromEnvironment()
  602. if err != nil {
  603. return err
  604. }
  605. req := api.CopyRequest{Source: args[0], Destination: args[1]}
  606. if err := client.Copy(cmd.Context(), &req); err != nil {
  607. return err
  608. }
  609. fmt.Printf("copied '%s' to '%s'\n", args[0], args[1])
  610. return nil
  611. }
  612. func PullHandler(cmd *cobra.Command, args []string) error {
  613. insecure, err := cmd.Flags().GetBool("insecure")
  614. if err != nil {
  615. return err
  616. }
  617. client, err := api.ClientFromEnvironment()
  618. if err != nil {
  619. return err
  620. }
  621. p := progress.NewProgress(os.Stderr)
  622. defer p.Stop()
  623. bars := make(map[string]*progress.Bar)
  624. var status string
  625. var spinner *progress.Spinner
  626. fn := func(resp api.ProgressResponse) error {
  627. if resp.Digest != "" {
  628. if spinner != nil {
  629. spinner.Stop()
  630. }
  631. bar, ok := bars[resp.Digest]
  632. if !ok {
  633. bar = progress.NewBar(fmt.Sprintf("pulling %s...", resp.Digest[7:19]), resp.Total, resp.Completed)
  634. bars[resp.Digest] = bar
  635. p.Add(resp.Digest, bar)
  636. }
  637. bar.Set(resp.Completed)
  638. } else if status != resp.Status {
  639. if spinner != nil {
  640. spinner.Stop()
  641. }
  642. status = resp.Status
  643. spinner = progress.NewSpinner(status)
  644. p.Add(status, spinner)
  645. }
  646. return nil
  647. }
  648. request := api.PullRequest{Name: args[0], Insecure: insecure}
  649. if err := client.Pull(cmd.Context(), &request, fn); err != nil {
  650. return err
  651. }
  652. return nil
  653. }
  654. type generateContextKey string
  655. type runOptions struct {
  656. Model string
  657. ParentModel string
  658. Prompt string
  659. Messages []api.Message
  660. WordWrap bool
  661. Format string
  662. System string
  663. Images []api.ImageData
  664. Options map[string]interface{}
  665. MultiModal bool
  666. KeepAlive *api.Duration
  667. }
  668. type displayResponseState struct {
  669. lineLength int
  670. wordBuffer string
  671. }
  672. func displayResponse(content string, wordWrap bool, state *displayResponseState) {
  673. termWidth, _, _ := term.GetSize(int(os.Stdout.Fd()))
  674. if wordWrap && termWidth >= 10 {
  675. for _, ch := range content {
  676. if state.lineLength+1 > termWidth-5 {
  677. if runewidth.StringWidth(state.wordBuffer) > termWidth-10 {
  678. fmt.Printf("%s%c", state.wordBuffer, ch)
  679. state.wordBuffer = ""
  680. state.lineLength = 0
  681. continue
  682. }
  683. // backtrack the length of the last word and clear to the end of the line
  684. a := runewidth.StringWidth(state.wordBuffer)
  685. if a > 0 {
  686. fmt.Printf("\x1b[%dD", a)
  687. }
  688. fmt.Printf("\x1b[K\n")
  689. fmt.Printf("%s%c", state.wordBuffer, ch)
  690. chWidth := runewidth.RuneWidth(ch)
  691. state.lineLength = runewidth.StringWidth(state.wordBuffer) + chWidth
  692. } else {
  693. fmt.Print(string(ch))
  694. state.lineLength += runewidth.RuneWidth(ch)
  695. if runewidth.RuneWidth(ch) >= 2 {
  696. state.wordBuffer = ""
  697. continue
  698. }
  699. switch ch {
  700. case ' ':
  701. state.wordBuffer = ""
  702. case '\n':
  703. state.lineLength = 0
  704. default:
  705. state.wordBuffer += string(ch)
  706. }
  707. }
  708. }
  709. } else {
  710. fmt.Printf("%s%s", state.wordBuffer, content)
  711. if len(state.wordBuffer) > 0 {
  712. state.wordBuffer = ""
  713. }
  714. }
  715. }
  716. func chat(cmd *cobra.Command, opts runOptions) (*api.Message, error) {
  717. client, err := api.ClientFromEnvironment()
  718. if err != nil {
  719. return nil, err
  720. }
  721. p := progress.NewProgress(os.Stderr)
  722. defer p.StopAndClear()
  723. spinner := progress.NewSpinner("")
  724. p.Add("", spinner)
  725. cancelCtx, cancel := context.WithCancel(cmd.Context())
  726. defer cancel()
  727. sigChan := make(chan os.Signal, 1)
  728. signal.Notify(sigChan, syscall.SIGINT)
  729. go func() {
  730. <-sigChan
  731. cancel()
  732. }()
  733. var state *displayResponseState = &displayResponseState{}
  734. var latest api.ChatResponse
  735. var fullResponse strings.Builder
  736. var role string
  737. fn := func(response api.ChatResponse) error {
  738. p.StopAndClear()
  739. latest = response
  740. role = response.Message.Role
  741. content := response.Message.Content
  742. fullResponse.WriteString(content)
  743. displayResponse(content, opts.WordWrap, state)
  744. return nil
  745. }
  746. if opts.Format == "json" {
  747. opts.Format = `"` + opts.Format + `"`
  748. }
  749. req := &api.ChatRequest{
  750. Model: opts.Model,
  751. Messages: opts.Messages,
  752. Format: json.RawMessage(opts.Format),
  753. Options: opts.Options,
  754. }
  755. if opts.KeepAlive != nil {
  756. req.KeepAlive = opts.KeepAlive
  757. }
  758. if err := client.Chat(cancelCtx, req, fn); err != nil {
  759. if errors.Is(err, context.Canceled) {
  760. return nil, nil
  761. }
  762. return nil, err
  763. }
  764. if len(opts.Messages) > 0 {
  765. fmt.Println()
  766. fmt.Println()
  767. }
  768. verbose, err := cmd.Flags().GetBool("verbose")
  769. if err != nil {
  770. return nil, err
  771. }
  772. if verbose {
  773. latest.Summary()
  774. }
  775. return &api.Message{Role: role, Content: fullResponse.String()}, nil
  776. }
  777. func generate(cmd *cobra.Command, opts runOptions) error {
  778. client, err := api.ClientFromEnvironment()
  779. if err != nil {
  780. return err
  781. }
  782. p := progress.NewProgress(os.Stderr)
  783. defer p.StopAndClear()
  784. spinner := progress.NewSpinner("")
  785. p.Add("", spinner)
  786. var latest api.GenerateResponse
  787. generateContext, ok := cmd.Context().Value(generateContextKey("context")).([]int)
  788. if !ok {
  789. generateContext = []int{}
  790. }
  791. ctx, cancel := context.WithCancel(cmd.Context())
  792. defer cancel()
  793. sigChan := make(chan os.Signal, 1)
  794. signal.Notify(sigChan, syscall.SIGINT)
  795. go func() {
  796. <-sigChan
  797. cancel()
  798. }()
  799. var state *displayResponseState = &displayResponseState{}
  800. fn := func(response api.GenerateResponse) error {
  801. p.StopAndClear()
  802. latest = response
  803. content := response.Response
  804. displayResponse(content, opts.WordWrap, state)
  805. return nil
  806. }
  807. if opts.MultiModal {
  808. opts.Prompt, opts.Images, err = extractFileData(opts.Prompt)
  809. if err != nil {
  810. return err
  811. }
  812. }
  813. if opts.Format == "json" {
  814. opts.Format = `"` + opts.Format + `"`
  815. }
  816. request := api.GenerateRequest{
  817. Model: opts.Model,
  818. Prompt: opts.Prompt,
  819. Context: generateContext,
  820. Images: opts.Images,
  821. Format: json.RawMessage(opts.Format),
  822. System: opts.System,
  823. Options: opts.Options,
  824. KeepAlive: opts.KeepAlive,
  825. }
  826. if err := client.Generate(ctx, &request, fn); err != nil {
  827. if errors.Is(err, context.Canceled) {
  828. return nil
  829. }
  830. return err
  831. }
  832. if opts.Prompt != "" {
  833. fmt.Println()
  834. fmt.Println()
  835. }
  836. if !latest.Done {
  837. return nil
  838. }
  839. verbose, err := cmd.Flags().GetBool("verbose")
  840. if err != nil {
  841. return err
  842. }
  843. if verbose {
  844. latest.Summary()
  845. }
  846. ctx = context.WithValue(cmd.Context(), generateContextKey("context"), latest.Context)
  847. cmd.SetContext(ctx)
  848. return nil
  849. }
  850. func RunServer(_ *cobra.Command, _ []string) error {
  851. if err := initializeKeypair(); err != nil {
  852. return err
  853. }
  854. ln, err := net.Listen("tcp", envconfig.Host().Host)
  855. if err != nil {
  856. return err
  857. }
  858. err = server.Serve(ln)
  859. if errors.Is(err, http.ErrServerClosed) {
  860. return nil
  861. }
  862. return err
  863. }
  864. func initializeKeypair() error {
  865. home, err := os.UserHomeDir()
  866. if err != nil {
  867. return err
  868. }
  869. privKeyPath := filepath.Join(home, ".ollama", "id_ed25519")
  870. pubKeyPath := filepath.Join(home, ".ollama", "id_ed25519.pub")
  871. _, err = os.Stat(privKeyPath)
  872. if os.IsNotExist(err) {
  873. fmt.Printf("Couldn't find '%s'. Generating new private key.\n", privKeyPath)
  874. cryptoPublicKey, cryptoPrivateKey, err := ed25519.GenerateKey(rand.Reader)
  875. if err != nil {
  876. return err
  877. }
  878. privateKeyBytes, err := ssh.MarshalPrivateKey(cryptoPrivateKey, "")
  879. if err != nil {
  880. return err
  881. }
  882. if err := os.MkdirAll(filepath.Dir(privKeyPath), 0o755); err != nil {
  883. return fmt.Errorf("could not create directory %w", err)
  884. }
  885. if err := os.WriteFile(privKeyPath, pem.EncodeToMemory(privateKeyBytes), 0o600); err != nil {
  886. return err
  887. }
  888. sshPublicKey, err := ssh.NewPublicKey(cryptoPublicKey)
  889. if err != nil {
  890. return err
  891. }
  892. publicKeyBytes := ssh.MarshalAuthorizedKey(sshPublicKey)
  893. if err := os.WriteFile(pubKeyPath, publicKeyBytes, 0o644); err != nil {
  894. return err
  895. }
  896. fmt.Printf("Your new public key is: \n\n%s\n", publicKeyBytes)
  897. }
  898. return nil
  899. }
  900. func checkServerHeartbeat(cmd *cobra.Command, _ []string) error {
  901. client, err := api.ClientFromEnvironment()
  902. if err != nil {
  903. return err
  904. }
  905. if err := client.Heartbeat(cmd.Context()); err != nil {
  906. if !strings.Contains(err.Error(), " refused") {
  907. return err
  908. }
  909. if err := startApp(cmd.Context(), client); err != nil {
  910. return errors.New("could not connect to ollama app, is it running?")
  911. }
  912. }
  913. return nil
  914. }
  915. func versionHandler(cmd *cobra.Command, _ []string) {
  916. client, err := api.ClientFromEnvironment()
  917. if err != nil {
  918. return
  919. }
  920. serverVersion, err := client.Version(cmd.Context())
  921. if err != nil {
  922. fmt.Println("Warning: could not connect to a running Ollama instance")
  923. }
  924. if serverVersion != "" {
  925. fmt.Printf("ollama version is %s\n", serverVersion)
  926. }
  927. if serverVersion != version.Version {
  928. fmt.Printf("Warning: client version is %s\n", version.Version)
  929. }
  930. }
  931. func appendEnvDocs(cmd *cobra.Command, envs []envconfig.EnvVar) {
  932. if len(envs) == 0 {
  933. return
  934. }
  935. envUsage := `
  936. Environment Variables:
  937. `
  938. for _, e := range envs {
  939. envUsage += fmt.Sprintf(" %-24s %s\n", e.Name, e.Description)
  940. }
  941. cmd.SetUsageTemplate(cmd.UsageTemplate() + envUsage)
  942. }
  943. func NewCLI() *cobra.Command {
  944. log.SetFlags(log.LstdFlags | log.Lshortfile)
  945. cobra.EnableCommandSorting = false
  946. if runtime.GOOS == "windows" && term.IsTerminal(int(os.Stdout.Fd())) {
  947. console.ConsoleFromFile(os.Stdin) //nolint:errcheck
  948. }
  949. rootCmd := &cobra.Command{
  950. Use: "ollama",
  951. Short: "Large language model runner",
  952. SilenceUsage: true,
  953. SilenceErrors: true,
  954. CompletionOptions: cobra.CompletionOptions{
  955. DisableDefaultCmd: true,
  956. },
  957. Run: func(cmd *cobra.Command, args []string) {
  958. if version, _ := cmd.Flags().GetBool("version"); version {
  959. versionHandler(cmd, args)
  960. return
  961. }
  962. cmd.Print(cmd.UsageString())
  963. },
  964. }
  965. rootCmd.Flags().BoolP("version", "v", false, "Show version information")
  966. createCmd := &cobra.Command{
  967. Use: "create MODEL",
  968. Short: "Create a model from a Modelfile",
  969. Args: cobra.ExactArgs(1),
  970. PreRunE: checkServerHeartbeat,
  971. RunE: CreateHandler,
  972. }
  973. createCmd.Flags().StringP("file", "f", "", "Name of the Modelfile (default \"Modelfile\"")
  974. createCmd.Flags().StringP("quantize", "q", "", "Quantize model to this level (e.g. q4_0)")
  975. showCmd := &cobra.Command{
  976. Use: "show MODEL",
  977. Short: "Show information for a model",
  978. Args: cobra.ExactArgs(1),
  979. PreRunE: checkServerHeartbeat,
  980. RunE: ShowHandler,
  981. }
  982. showCmd.Flags().Bool("license", false, "Show license of a model")
  983. showCmd.Flags().Bool("modelfile", false, "Show Modelfile of a model")
  984. showCmd.Flags().Bool("parameters", false, "Show parameters of a model")
  985. showCmd.Flags().Bool("template", false, "Show template of a model")
  986. showCmd.Flags().Bool("system", false, "Show system message of a model")
  987. runCmd := &cobra.Command{
  988. Use: "run MODEL [PROMPT]",
  989. Short: "Run a model",
  990. Args: cobra.MinimumNArgs(1),
  991. PreRunE: checkServerHeartbeat,
  992. RunE: RunHandler,
  993. }
  994. runCmd.Flags().String("keepalive", "", "Duration to keep a model loaded (e.g. 5m)")
  995. runCmd.Flags().Bool("verbose", false, "Show timings for response")
  996. runCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  997. runCmd.Flags().Bool("nowordwrap", false, "Don't wrap words to the next line automatically")
  998. runCmd.Flags().String("format", "", "Response format (e.g. json)")
  999. stopCmd := &cobra.Command{
  1000. Use: "stop MODEL",
  1001. Short: "Stop a running model",
  1002. Args: cobra.ExactArgs(1),
  1003. PreRunE: checkServerHeartbeat,
  1004. RunE: StopHandler,
  1005. }
  1006. serveCmd := &cobra.Command{
  1007. Use: "serve",
  1008. Aliases: []string{"start"},
  1009. Short: "Start ollama",
  1010. Args: cobra.ExactArgs(0),
  1011. RunE: RunServer,
  1012. }
  1013. pullCmd := &cobra.Command{
  1014. Use: "pull MODEL",
  1015. Short: "Pull a model from a registry",
  1016. Args: cobra.ExactArgs(1),
  1017. PreRunE: checkServerHeartbeat,
  1018. RunE: PullHandler,
  1019. }
  1020. pullCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1021. pushCmd := &cobra.Command{
  1022. Use: "push MODEL",
  1023. Short: "Push a model to a registry",
  1024. Args: cobra.ExactArgs(1),
  1025. PreRunE: checkServerHeartbeat,
  1026. RunE: PushHandler,
  1027. }
  1028. pushCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1029. listCmd := &cobra.Command{
  1030. Use: "list",
  1031. Aliases: []string{"ls"},
  1032. Short: "List models",
  1033. PreRunE: checkServerHeartbeat,
  1034. RunE: ListHandler,
  1035. }
  1036. psCmd := &cobra.Command{
  1037. Use: "ps",
  1038. Short: "List running models",
  1039. PreRunE: checkServerHeartbeat,
  1040. RunE: ListRunningHandler,
  1041. }
  1042. copyCmd := &cobra.Command{
  1043. Use: "cp SOURCE DESTINATION",
  1044. Short: "Copy a model",
  1045. Args: cobra.ExactArgs(2),
  1046. PreRunE: checkServerHeartbeat,
  1047. RunE: CopyHandler,
  1048. }
  1049. deleteCmd := &cobra.Command{
  1050. Use: "rm MODEL [MODEL...]",
  1051. Short: "Remove a model",
  1052. Args: cobra.MinimumNArgs(1),
  1053. PreRunE: checkServerHeartbeat,
  1054. RunE: DeleteHandler,
  1055. }
  1056. runnerCmd := &cobra.Command{
  1057. Use: "runner",
  1058. Short: llama.PrintSystemInfo(),
  1059. Hidden: true,
  1060. RunE: func(cmd *cobra.Command, args []string) error {
  1061. return runner.Execute(os.Args[1:])
  1062. },
  1063. FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
  1064. }
  1065. runnerCmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
  1066. _ = runner.Execute(args[1:])
  1067. })
  1068. envVars := envconfig.AsMap()
  1069. envs := []envconfig.EnvVar{envVars["OLLAMA_HOST"]}
  1070. for _, cmd := range []*cobra.Command{
  1071. createCmd,
  1072. showCmd,
  1073. runCmd,
  1074. stopCmd,
  1075. pullCmd,
  1076. pushCmd,
  1077. listCmd,
  1078. psCmd,
  1079. copyCmd,
  1080. deleteCmd,
  1081. serveCmd,
  1082. } {
  1083. switch cmd {
  1084. case runCmd:
  1085. appendEnvDocs(cmd, []envconfig.EnvVar{envVars["OLLAMA_HOST"], envVars["OLLAMA_NOHISTORY"]})
  1086. case serveCmd:
  1087. appendEnvDocs(cmd, []envconfig.EnvVar{
  1088. envVars["OLLAMA_DEBUG"],
  1089. envVars["OLLAMA_HOST"],
  1090. envVars["OLLAMA_KEEP_ALIVE"],
  1091. envVars["OLLAMA_MAX_LOADED_MODELS"],
  1092. envVars["OLLAMA_MAX_QUEUE"],
  1093. envVars["OLLAMA_MODELS"],
  1094. envVars["OLLAMA_NUM_PARALLEL"],
  1095. envVars["OLLAMA_NOPRUNE"],
  1096. envVars["OLLAMA_ORIGINS"],
  1097. envVars["OLLAMA_SCHED_SPREAD"],
  1098. envVars["OLLAMA_TMPDIR"],
  1099. envVars["OLLAMA_FLASH_ATTENTION"],
  1100. envVars["OLLAMA_KV_CACHE_TYPE"],
  1101. envVars["OLLAMA_LLM_LIBRARY"],
  1102. envVars["OLLAMA_GPU_OVERHEAD"],
  1103. envVars["OLLAMA_LOAD_TIMEOUT"],
  1104. })
  1105. default:
  1106. appendEnvDocs(cmd, envs)
  1107. }
  1108. }
  1109. rootCmd.AddCommand(
  1110. serveCmd,
  1111. createCmd,
  1112. showCmd,
  1113. runCmd,
  1114. stopCmd,
  1115. pullCmd,
  1116. pushCmd,
  1117. listCmd,
  1118. psCmd,
  1119. copyCmd,
  1120. deleteCmd,
  1121. runnerCmd,
  1122. )
  1123. return rootCmd
  1124. }