cmd.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  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. fn, _ := cmd.Flags().GetString("file")
  45. filename := fn
  46. if filename == "" {
  47. filename = "Modelfile"
  48. }
  49. absName, err := filepath.Abs(filename)
  50. if err != nil {
  51. return "", err
  52. }
  53. _, err = os.Stat(absName)
  54. if err != nil {
  55. return fn, err
  56. }
  57. return absName, nil
  58. }
  59. func CreateHandler(cmd *cobra.Command, args []string) error {
  60. p := progress.NewProgress(os.Stderr)
  61. defer p.Stop()
  62. var reader io.Reader
  63. filename, err := getModelfileName(cmd)
  64. if os.IsNotExist(err) {
  65. if filename == "" {
  66. reader = strings.NewReader("FROM .\n")
  67. } else {
  68. return errModelfileNotFound
  69. }
  70. } else if err != nil {
  71. return err
  72. } else {
  73. f, err := os.Open(filename)
  74. if err != nil {
  75. return err
  76. }
  77. reader = f
  78. defer f.Close()
  79. }
  80. modelfile, err := parser.ParseFile(reader)
  81. if err != nil {
  82. return err
  83. }
  84. status := "gathering model components"
  85. spinner := progress.NewSpinner(status)
  86. p.Add(status, spinner)
  87. req, err := modelfile.CreateRequest()
  88. if err != nil {
  89. return err
  90. }
  91. spinner.Stop()
  92. req.Name = args[0]
  93. quantize, _ := cmd.Flags().GetString("quantize")
  94. if quantize != "" {
  95. req.Quantize = quantize
  96. }
  97. client, err := api.ClientFromEnvironment()
  98. if err != nil {
  99. return err
  100. }
  101. if len(req.Files) > 0 {
  102. fileMap := map[string]string{}
  103. for f, digest := range req.Files {
  104. if _, err := createBlob(cmd, client, f, digest, p); err != nil {
  105. return err
  106. }
  107. fileMap[filepath.Base(f)] = digest
  108. }
  109. req.Files = fileMap
  110. }
  111. if len(req.Adapters) > 0 {
  112. fileMap := map[string]string{}
  113. for f, digest := range req.Adapters {
  114. if _, err := createBlob(cmd, client, f, digest, p); err != nil {
  115. return err
  116. }
  117. fileMap[filepath.Base(f)] = digest
  118. }
  119. req.Adapters = fileMap
  120. }
  121. bars := make(map[string]*progress.Bar)
  122. fn := func(resp api.ProgressResponse) error {
  123. if resp.Digest != "" {
  124. bar, ok := bars[resp.Digest]
  125. if !ok {
  126. bar = progress.NewBar(fmt.Sprintf("pulling %s...", resp.Digest[7:19]), resp.Total, resp.Completed)
  127. bars[resp.Digest] = bar
  128. p.Add(resp.Digest, bar)
  129. }
  130. bar.Set(resp.Completed)
  131. } else if status != resp.Status {
  132. spinner.Stop()
  133. status = resp.Status
  134. spinner = progress.NewSpinner(status)
  135. p.Add(status, spinner)
  136. }
  137. return nil
  138. }
  139. if err := client.Create(cmd.Context(), req, fn); err != nil {
  140. if strings.Contains(err.Error(), "path or Modelfile are required") {
  141. return fmt.Errorf("the ollama server must be updated to use `ollama create` with this client")
  142. }
  143. return err
  144. }
  145. return nil
  146. }
  147. func createBlob(cmd *cobra.Command, client *api.Client, path string, digest string, p *progress.Progress) (string, error) {
  148. realPath, err := filepath.EvalSymlinks(path)
  149. if err != nil {
  150. return "", err
  151. }
  152. bin, err := os.Open(realPath)
  153. if err != nil {
  154. return "", err
  155. }
  156. defer bin.Close()
  157. // Get file info to retrieve the size
  158. fileInfo, err := bin.Stat()
  159. if err != nil {
  160. return "", err
  161. }
  162. fileSize := fileInfo.Size()
  163. var pw progressWriter
  164. status := fmt.Sprintf("copying file %s 0%%", digest)
  165. spinner := progress.NewSpinner(status)
  166. p.Add(status, spinner)
  167. defer spinner.Stop()
  168. done := make(chan struct{})
  169. defer close(done)
  170. go func() {
  171. ticker := time.NewTicker(60 * time.Millisecond)
  172. defer ticker.Stop()
  173. for {
  174. select {
  175. case <-ticker.C:
  176. spinner.SetMessage(fmt.Sprintf("copying file %s %d%%", digest, int(100*pw.n.Load()/fileSize)))
  177. case <-done:
  178. spinner.SetMessage(fmt.Sprintf("copying file %s 100%%", digest))
  179. return
  180. }
  181. }
  182. }()
  183. if err = client.CreateBlob(cmd.Context(), digest, io.TeeReader(bin, &pw)); err != nil {
  184. return "", err
  185. }
  186. return digest, nil
  187. }
  188. type progressWriter struct {
  189. n atomic.Int64
  190. }
  191. func (w *progressWriter) Write(p []byte) (n int, err error) {
  192. w.n.Add(int64(len(p)))
  193. return len(p), nil
  194. }
  195. func loadOrUnloadModel(cmd *cobra.Command, opts *runOptions) error {
  196. p := progress.NewProgress(os.Stderr)
  197. defer p.StopAndClear()
  198. spinner := progress.NewSpinner("")
  199. p.Add("", spinner)
  200. client, err := api.ClientFromEnvironment()
  201. if err != nil {
  202. return err
  203. }
  204. req := &api.GenerateRequest{
  205. Model: opts.Model,
  206. KeepAlive: opts.KeepAlive,
  207. }
  208. return client.Generate(cmd.Context(), req, func(api.GenerateResponse) error { return nil })
  209. }
  210. func StopHandler(cmd *cobra.Command, args []string) error {
  211. opts := &runOptions{
  212. Model: args[0],
  213. KeepAlive: &api.Duration{Duration: 0},
  214. }
  215. if err := loadOrUnloadModel(cmd, opts); err != nil {
  216. if strings.Contains(err.Error(), "not found") {
  217. return fmt.Errorf("couldn't find model \"%s\" to stop", args[0])
  218. }
  219. }
  220. return nil
  221. }
  222. func RunHandler(cmd *cobra.Command, args []string) error {
  223. interactive := true
  224. opts := runOptions{
  225. Model: args[0],
  226. WordWrap: os.Getenv("TERM") == "xterm-256color",
  227. Options: map[string]interface{}{},
  228. }
  229. format, err := cmd.Flags().GetString("format")
  230. if err != nil {
  231. return err
  232. }
  233. opts.Format = format
  234. keepAlive, err := cmd.Flags().GetString("keepalive")
  235. if err != nil {
  236. return err
  237. }
  238. if keepAlive != "" {
  239. d, err := time.ParseDuration(keepAlive)
  240. if err != nil {
  241. return err
  242. }
  243. opts.KeepAlive = &api.Duration{Duration: d}
  244. }
  245. prompts := args[1:]
  246. // prepend stdin to the prompt if provided
  247. if !term.IsTerminal(int(os.Stdin.Fd())) {
  248. in, err := io.ReadAll(os.Stdin)
  249. if err != nil {
  250. return err
  251. }
  252. prompts = append([]string{string(in)}, prompts...)
  253. opts.WordWrap = false
  254. interactive = false
  255. }
  256. opts.Prompt = strings.Join(prompts, " ")
  257. if len(prompts) > 0 {
  258. interactive = false
  259. }
  260. // Be quiet if we're redirecting to a pipe or file
  261. if !term.IsTerminal(int(os.Stdout.Fd())) {
  262. interactive = false
  263. }
  264. nowrap, err := cmd.Flags().GetBool("nowordwrap")
  265. if err != nil {
  266. return err
  267. }
  268. opts.WordWrap = !nowrap
  269. // Fill out the rest of the options based on information about the
  270. // model.
  271. client, err := api.ClientFromEnvironment()
  272. if err != nil {
  273. return err
  274. }
  275. name := args[0]
  276. info, err := func() (*api.ShowResponse, error) {
  277. showReq := &api.ShowRequest{Name: name}
  278. info, err := client.Show(cmd.Context(), showReq)
  279. var se api.StatusError
  280. if errors.As(err, &se) && se.StatusCode == http.StatusNotFound {
  281. if err := PullHandler(cmd, []string{name}); err != nil {
  282. return nil, err
  283. }
  284. return client.Show(cmd.Context(), &api.ShowRequest{Name: name})
  285. }
  286. return info, err
  287. }()
  288. if err != nil {
  289. return err
  290. }
  291. opts.MultiModal = len(info.ProjectorInfo) != 0
  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. cancelCtx, cancel := context.WithCancel(cmd.Context())
  727. defer cancel()
  728. sigChan := make(chan os.Signal, 1)
  729. signal.Notify(sigChan, syscall.SIGINT)
  730. go func() {
  731. <-sigChan
  732. cancel()
  733. }()
  734. var state *displayResponseState = &displayResponseState{}
  735. var latest api.ChatResponse
  736. var fullResponse strings.Builder
  737. var role string
  738. fn := func(response api.ChatResponse) error {
  739. p.StopAndClear()
  740. latest = response
  741. role = response.Message.Role
  742. content := response.Message.Content
  743. fullResponse.WriteString(content)
  744. displayResponse(content, opts.WordWrap, state)
  745. return nil
  746. }
  747. if opts.Format == "json" {
  748. opts.Format = `"` + opts.Format + `"`
  749. }
  750. req := &api.ChatRequest{
  751. Model: opts.Model,
  752. Messages: opts.Messages,
  753. Format: json.RawMessage(opts.Format),
  754. Options: opts.Options,
  755. }
  756. if opts.KeepAlive != nil {
  757. req.KeepAlive = opts.KeepAlive
  758. }
  759. if err := client.Chat(cancelCtx, req, fn); err != nil {
  760. if errors.Is(err, context.Canceled) {
  761. return nil, nil
  762. }
  763. return nil, err
  764. }
  765. if len(opts.Messages) > 0 {
  766. fmt.Println()
  767. fmt.Println()
  768. }
  769. verbose, err := cmd.Flags().GetBool("verbose")
  770. if err != nil {
  771. return nil, err
  772. }
  773. if verbose {
  774. latest.Summary()
  775. }
  776. return &api.Message{Role: role, Content: fullResponse.String()}, nil
  777. }
  778. func generate(cmd *cobra.Command, opts runOptions) error {
  779. client, err := api.ClientFromEnvironment()
  780. if err != nil {
  781. return err
  782. }
  783. p := progress.NewProgress(os.Stderr)
  784. defer p.StopAndClear()
  785. spinner := progress.NewSpinner("")
  786. p.Add("", spinner)
  787. var latest api.GenerateResponse
  788. generateContext, ok := cmd.Context().Value(generateContextKey("context")).([]int)
  789. if !ok {
  790. generateContext = []int{}
  791. }
  792. ctx, cancel := context.WithCancel(cmd.Context())
  793. defer cancel()
  794. sigChan := make(chan os.Signal, 1)
  795. signal.Notify(sigChan, syscall.SIGINT)
  796. go func() {
  797. <-sigChan
  798. cancel()
  799. }()
  800. var state *displayResponseState = &displayResponseState{}
  801. fn := func(response api.GenerateResponse) error {
  802. p.StopAndClear()
  803. latest = response
  804. content := response.Response
  805. displayResponse(content, opts.WordWrap, state)
  806. return nil
  807. }
  808. if opts.MultiModal {
  809. opts.Prompt, opts.Images, err = extractFileData(opts.Prompt)
  810. if err != nil {
  811. return err
  812. }
  813. }
  814. if opts.Format == "json" {
  815. opts.Format = `"` + opts.Format + `"`
  816. }
  817. request := api.GenerateRequest{
  818. Model: opts.Model,
  819. Prompt: opts.Prompt,
  820. Context: generateContext,
  821. Images: opts.Images,
  822. Format: json.RawMessage(opts.Format),
  823. System: opts.System,
  824. Options: opts.Options,
  825. KeepAlive: opts.KeepAlive,
  826. }
  827. if err := client.Generate(ctx, &request, fn); err != nil {
  828. if errors.Is(err, context.Canceled) {
  829. return nil
  830. }
  831. return err
  832. }
  833. if opts.Prompt != "" {
  834. fmt.Println()
  835. fmt.Println()
  836. }
  837. if !latest.Done {
  838. return nil
  839. }
  840. verbose, err := cmd.Flags().GetBool("verbose")
  841. if err != nil {
  842. return err
  843. }
  844. if verbose {
  845. latest.Summary()
  846. }
  847. ctx = context.WithValue(cmd.Context(), generateContextKey("context"), latest.Context)
  848. cmd.SetContext(ctx)
  849. return nil
  850. }
  851. func RunServer(_ *cobra.Command, _ []string) error {
  852. if err := initializeKeypair(); err != nil {
  853. return err
  854. }
  855. ln, err := net.Listen("tcp", envconfig.Host().Host)
  856. if err != nil {
  857. return err
  858. }
  859. err = server.Serve(ln)
  860. if errors.Is(err, http.ErrServerClosed) {
  861. return nil
  862. }
  863. return err
  864. }
  865. func initializeKeypair() error {
  866. home, err := os.UserHomeDir()
  867. if err != nil {
  868. return err
  869. }
  870. privKeyPath := filepath.Join(home, ".ollama", "id_ed25519")
  871. pubKeyPath := filepath.Join(home, ".ollama", "id_ed25519.pub")
  872. _, err = os.Stat(privKeyPath)
  873. if os.IsNotExist(err) {
  874. fmt.Printf("Couldn't find '%s'. Generating new private key.\n", privKeyPath)
  875. cryptoPublicKey, cryptoPrivateKey, err := ed25519.GenerateKey(rand.Reader)
  876. if err != nil {
  877. return err
  878. }
  879. privateKeyBytes, err := ssh.MarshalPrivateKey(cryptoPrivateKey, "")
  880. if err != nil {
  881. return err
  882. }
  883. if err := os.MkdirAll(filepath.Dir(privKeyPath), 0o755); err != nil {
  884. return fmt.Errorf("could not create directory %w", err)
  885. }
  886. if err := os.WriteFile(privKeyPath, pem.EncodeToMemory(privateKeyBytes), 0o600); err != nil {
  887. return err
  888. }
  889. sshPublicKey, err := ssh.NewPublicKey(cryptoPublicKey)
  890. if err != nil {
  891. return err
  892. }
  893. publicKeyBytes := ssh.MarshalAuthorizedKey(sshPublicKey)
  894. if err := os.WriteFile(pubKeyPath, publicKeyBytes, 0o644); err != nil {
  895. return err
  896. }
  897. fmt.Printf("Your new public key is: \n\n%s\n", publicKeyBytes)
  898. }
  899. return nil
  900. }
  901. func checkServerHeartbeat(cmd *cobra.Command, _ []string) error {
  902. client, err := api.ClientFromEnvironment()
  903. if err != nil {
  904. return err
  905. }
  906. if err := client.Heartbeat(cmd.Context()); err != nil {
  907. if !strings.Contains(err.Error(), " refused") {
  908. return err
  909. }
  910. if err := startApp(cmd.Context(), client); err != nil {
  911. return errors.New("could not connect to ollama app, is it running?")
  912. }
  913. }
  914. return nil
  915. }
  916. func versionHandler(cmd *cobra.Command, _ []string) {
  917. client, err := api.ClientFromEnvironment()
  918. if err != nil {
  919. return
  920. }
  921. serverVersion, err := client.Version(cmd.Context())
  922. if err != nil {
  923. fmt.Println("Warning: could not connect to a running Ollama instance")
  924. }
  925. if serverVersion != "" {
  926. fmt.Printf("ollama version is %s\n", serverVersion)
  927. }
  928. if serverVersion != version.Version {
  929. fmt.Printf("Warning: client version is %s\n", version.Version)
  930. }
  931. }
  932. func appendEnvDocs(cmd *cobra.Command, envs []envconfig.EnvVar) {
  933. if len(envs) == 0 {
  934. return
  935. }
  936. envUsage := `
  937. Environment Variables:
  938. `
  939. for _, e := range envs {
  940. envUsage += fmt.Sprintf(" %-24s %s\n", e.Name, e.Description)
  941. }
  942. cmd.SetUsageTemplate(cmd.UsageTemplate() + envUsage)
  943. }
  944. func NewCLI() *cobra.Command {
  945. log.SetFlags(log.LstdFlags | log.Lshortfile)
  946. cobra.EnableCommandSorting = false
  947. if runtime.GOOS == "windows" && term.IsTerminal(int(os.Stdout.Fd())) {
  948. console.ConsoleFromFile(os.Stdin) //nolint:errcheck
  949. }
  950. rootCmd := &cobra.Command{
  951. Use: "ollama",
  952. Short: "Large language model runner",
  953. SilenceUsage: true,
  954. SilenceErrors: true,
  955. CompletionOptions: cobra.CompletionOptions{
  956. DisableDefaultCmd: true,
  957. },
  958. Run: func(cmd *cobra.Command, args []string) {
  959. if version, _ := cmd.Flags().GetBool("version"); version {
  960. versionHandler(cmd, args)
  961. return
  962. }
  963. cmd.Print(cmd.UsageString())
  964. },
  965. }
  966. rootCmd.Flags().BoolP("version", "v", false, "Show version information")
  967. createCmd := &cobra.Command{
  968. Use: "create MODEL",
  969. Short: "Create a model from a Modelfile",
  970. Args: cobra.ExactArgs(1),
  971. PreRunE: checkServerHeartbeat,
  972. RunE: CreateHandler,
  973. }
  974. createCmd.Flags().StringP("file", "f", "", "Name of the Modelfile (default \"Modelfile\"")
  975. createCmd.Flags().StringP("quantize", "q", "", "Quantize model to this level (e.g. q4_0)")
  976. showCmd := &cobra.Command{
  977. Use: "show MODEL",
  978. Short: "Show information for a model",
  979. Args: cobra.ExactArgs(1),
  980. PreRunE: checkServerHeartbeat,
  981. RunE: ShowHandler,
  982. }
  983. showCmd.Flags().Bool("license", false, "Show license of a model")
  984. showCmd.Flags().Bool("modelfile", false, "Show Modelfile of a model")
  985. showCmd.Flags().Bool("parameters", false, "Show parameters of a model")
  986. showCmd.Flags().Bool("template", false, "Show template of a model")
  987. showCmd.Flags().Bool("system", false, "Show system message of a model")
  988. runCmd := &cobra.Command{
  989. Use: "run MODEL [PROMPT]",
  990. Short: "Run a model",
  991. Args: cobra.MinimumNArgs(1),
  992. PreRunE: checkServerHeartbeat,
  993. RunE: RunHandler,
  994. }
  995. runCmd.Flags().String("keepalive", "", "Duration to keep a model loaded (e.g. 5m)")
  996. runCmd.Flags().Bool("verbose", false, "Show timings for response")
  997. runCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  998. runCmd.Flags().Bool("nowordwrap", false, "Don't wrap words to the next line automatically")
  999. runCmd.Flags().String("format", "", "Response format (e.g. json)")
  1000. stopCmd := &cobra.Command{
  1001. Use: "stop MODEL",
  1002. Short: "Stop a running model",
  1003. Args: cobra.ExactArgs(1),
  1004. PreRunE: checkServerHeartbeat,
  1005. RunE: StopHandler,
  1006. }
  1007. serveCmd := &cobra.Command{
  1008. Use: "serve",
  1009. Aliases: []string{"start"},
  1010. Short: "Start ollama",
  1011. Args: cobra.ExactArgs(0),
  1012. RunE: RunServer,
  1013. }
  1014. pullCmd := &cobra.Command{
  1015. Use: "pull MODEL",
  1016. Short: "Pull a model from a registry",
  1017. Args: cobra.ExactArgs(1),
  1018. PreRunE: checkServerHeartbeat,
  1019. RunE: PullHandler,
  1020. }
  1021. pullCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1022. pushCmd := &cobra.Command{
  1023. Use: "push MODEL",
  1024. Short: "Push a model to a registry",
  1025. Args: cobra.ExactArgs(1),
  1026. PreRunE: checkServerHeartbeat,
  1027. RunE: PushHandler,
  1028. }
  1029. pushCmd.Flags().Bool("insecure", false, "Use an insecure registry")
  1030. listCmd := &cobra.Command{
  1031. Use: "list",
  1032. Aliases: []string{"ls"},
  1033. Short: "List models",
  1034. PreRunE: checkServerHeartbeat,
  1035. RunE: ListHandler,
  1036. }
  1037. psCmd := &cobra.Command{
  1038. Use: "ps",
  1039. Short: "List running models",
  1040. PreRunE: checkServerHeartbeat,
  1041. RunE: ListRunningHandler,
  1042. }
  1043. copyCmd := &cobra.Command{
  1044. Use: "cp SOURCE DESTINATION",
  1045. Short: "Copy a model",
  1046. Args: cobra.ExactArgs(2),
  1047. PreRunE: checkServerHeartbeat,
  1048. RunE: CopyHandler,
  1049. }
  1050. deleteCmd := &cobra.Command{
  1051. Use: "rm MODEL [MODEL...]",
  1052. Short: "Remove a model",
  1053. Args: cobra.MinimumNArgs(1),
  1054. PreRunE: checkServerHeartbeat,
  1055. RunE: DeleteHandler,
  1056. }
  1057. runnerCmd := &cobra.Command{
  1058. Use: "runner",
  1059. Short: llama.PrintSystemInfo(),
  1060. Hidden: true,
  1061. RunE: func(cmd *cobra.Command, args []string) error {
  1062. return runner.Execute(os.Args[1:])
  1063. },
  1064. FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
  1065. }
  1066. runnerCmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
  1067. _ = runner.Execute(args[1:])
  1068. })
  1069. envVars := envconfig.AsMap()
  1070. envs := []envconfig.EnvVar{envVars["OLLAMA_HOST"]}
  1071. for _, cmd := range []*cobra.Command{
  1072. createCmd,
  1073. showCmd,
  1074. runCmd,
  1075. stopCmd,
  1076. pullCmd,
  1077. pushCmd,
  1078. listCmd,
  1079. psCmd,
  1080. copyCmd,
  1081. deleteCmd,
  1082. serveCmd,
  1083. } {
  1084. switch cmd {
  1085. case runCmd:
  1086. appendEnvDocs(cmd, []envconfig.EnvVar{envVars["OLLAMA_HOST"], envVars["OLLAMA_NOHISTORY"]})
  1087. case serveCmd:
  1088. appendEnvDocs(cmd, []envconfig.EnvVar{
  1089. envVars["OLLAMA_DEBUG"],
  1090. envVars["OLLAMA_HOST"],
  1091. envVars["OLLAMA_KEEP_ALIVE"],
  1092. envVars["OLLAMA_MAX_LOADED_MODELS"],
  1093. envVars["OLLAMA_MAX_QUEUE"],
  1094. envVars["OLLAMA_MODELS"],
  1095. envVars["OLLAMA_NUM_PARALLEL"],
  1096. envVars["OLLAMA_NOPRUNE"],
  1097. envVars["OLLAMA_ORIGINS"],
  1098. envVars["OLLAMA_SCHED_SPREAD"],
  1099. envVars["OLLAMA_TMPDIR"],
  1100. envVars["OLLAMA_FLASH_ATTENTION"],
  1101. envVars["OLLAMA_KV_CACHE_TYPE"],
  1102. envVars["OLLAMA_LLM_LIBRARY"],
  1103. envVars["OLLAMA_GPU_OVERHEAD"],
  1104. envVars["OLLAMA_LOAD_TIMEOUT"],
  1105. })
  1106. default:
  1107. appendEnvDocs(cmd, envs)
  1108. }
  1109. }
  1110. rootCmd.AddCommand(
  1111. serveCmd,
  1112. createCmd,
  1113. showCmd,
  1114. runCmd,
  1115. stopCmd,
  1116. pullCmd,
  1117. pushCmd,
  1118. listCmd,
  1119. psCmd,
  1120. copyCmd,
  1121. deleteCmd,
  1122. runnerCmd,
  1123. )
  1124. return rootCmd
  1125. }