cmd.go 32 KB

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