cmd.go 31 KB

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