Unverified Commit 6febde72 authored by Timothy Jaeryang Baek's avatar Timothy Jaeryang Baek Committed by GitHub
Browse files

Merge branch 'main' into patch-1

parents 96da0792 325cfcd9
...@@ -29,8 +29,7 @@ curl https://ollama.ai/install.sh | sh ...@@ -29,8 +29,7 @@ curl https://ollama.ai/install.sh | sh
### Docker ### Docker
The official [Ollama Docker image `ollama/ollama`](https://hub.docker.com/r/ollama/ollama) The official [Ollama Docker image](https://hub.docker.com/r/ollama/ollama) `ollama/ollama` is available on Docker Hub.
is available on Docker Hub.
## Quickstart ## Quickstart
...@@ -235,6 +234,7 @@ See the [API documentation](./docs/api.md) for all endpoints. ...@@ -235,6 +234,7 @@ See the [API documentation](./docs/api.md) for all endpoints.
- [LlamaIndex](https://gpt-index.readthedocs.io/en/stable/examples/llm/ollama.html) - [LlamaIndex](https://gpt-index.readthedocs.io/en/stable/examples/llm/ollama.html)
- [LiteLLM](https://github.com/BerriAI/litellm) - [LiteLLM](https://github.com/BerriAI/litellm)
- [OllamaSharp for .NET](https://github.com/awaescher/OllamaSharp) - [OllamaSharp for .NET](https://github.com/awaescher/OllamaSharp)
- [Ollama-rs for Rust](https://github.com/pepperoni21/ollama-rs)
### Plugins (Extensions) ### Plugins (Extensions)
- [Raycast extension](https://github.com/MassimilianoPasquini97/raycast_ollama) - [Raycast extension](https://github.com/MassimilianoPasquini97/raycast_ollama)
...@@ -245,5 +245,3 @@ See the [API documentation](./docs/api.md) for all endpoints. ...@@ -245,5 +245,3 @@ See the [API documentation](./docs/api.md) for all endpoints.
- [Discord AI Bot](https://github.com/mekb-turtle/discord-ai-bot) - [Discord AI Bot](https://github.com/mekb-turtle/discord-ai-bot)
- [Dumbar](https://github.com/JerrySievert/Dumbar) - [Dumbar](https://github.com/JerrySievert/Dumbar)
...@@ -72,7 +72,7 @@ func ClientFromEnvironment() (*Client, error) { ...@@ -72,7 +72,7 @@ func ClientFromEnvironment() (*Client, error) {
}, },
} }
mockRequest, err := http.NewRequest("HEAD", client.base.String(), nil) mockRequest, err := http.NewRequest(http.MethodHead, client.base.String(), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -293,7 +293,7 @@ func DefaultOptions() Options { ...@@ -293,7 +293,7 @@ func DefaultOptions() Options {
return Options{ return Options{
// options set on request to runner // options set on request to runner
NumPredict: -1, NumPredict: -1,
NumKeep: -1, NumKeep: 0,
Temperature: 0.8, Temperature: 0.8,
TopK: 40, TopK: 40,
TopP: 0.9, TopP: 0.9,
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"io" "io"
"log" "log"
"net" "net"
"net/http"
"os" "os"
"os/exec" "os/exec"
"os/signal" "os/signal"
...@@ -98,19 +99,16 @@ func RunHandler(cmd *cobra.Command, args []string) error { ...@@ -98,19 +99,16 @@ func RunHandler(cmd *cobra.Command, args []string) error {
return err return err
} }
models, err := client.List(context.Background()) name := args[0]
if err != nil { // check if the model exists on the server
return err _, err = client.Show(context.Background(), &api.ShowRequest{Name: name})
} var statusError api.StatusError
switch {
canonicalModelPath := server.ParseModelPath(args[0]) case errors.As(err, &statusError) && statusError.StatusCode == http.StatusNotFound:
for _, model := range models.Models { if err := PullHandler(cmd, args); err != nil {
if model.Name == canonicalModelPath.GetShortTagname() { return err
return RunGenerate(cmd, args)
} }
} case err != nil:
if err := PullHandler(cmd, args); err != nil {
return err return err
} }
...@@ -731,21 +729,6 @@ func RunServer(cmd *cobra.Command, _ []string) error { ...@@ -731,21 +729,6 @@ func RunServer(cmd *cobra.Command, _ []string) error {
origins = strings.Split(o, ",") origins = strings.Split(o, ",")
} }
if noprune := os.Getenv("OLLAMA_NOPRUNE"); noprune == "" {
if err := server.PruneLayers(); err != nil {
return err
}
manifestsPath, err := server.GetManifestPath()
if err != nil {
return err
}
if err := server.PruneDirectory(manifestsPath); err != nil {
return err
}
}
return server.Serve(ln, origins) return server.Serve(ln, origins)
} }
......
...@@ -45,9 +45,11 @@ Advanced parameters (optional): ...@@ -45,9 +45,11 @@ Advanced parameters (optional):
- `system`: system prompt to (overrides what is defined in the `Modelfile`) - `system`: system prompt to (overrides what is defined in the `Modelfile`)
- `template`: the full prompt or prompt template (overrides what is defined in the `Modelfile`) - `template`: the full prompt or prompt template (overrides what is defined in the `Modelfile`)
- `context`: the context parameter returned from a previous request to `/generate`, this can be used to keep a short conversational memory - `context`: the context parameter returned from a previous request to `/generate`, this can be used to keep a short conversational memory
- `stream`: if `false` the response will be be returned as a single response object, rather than a stream of objects - `stream`: if `false` the response will be returned as a single response object, rather than a stream of objects
### Request ### Examples
#### Request
```shell ```shell
curl -X POST http://localhost:11434/api/generate -d '{ curl -X POST http://localhost:11434/api/generate -d '{
...@@ -56,9 +58,9 @@ curl -X POST http://localhost:11434/api/generate -d '{ ...@@ -56,9 +58,9 @@ curl -X POST http://localhost:11434/api/generate -d '{
}' }'
``` ```
### Response #### Response
A stream of JSON objects: A stream of JSON objects is returned:
```json ```json
{ {
...@@ -102,6 +104,38 @@ To calculate how fast the response is generated in tokens per second (token/s), ...@@ -102,6 +104,38 @@ To calculate how fast the response is generated in tokens per second (token/s),
} }
``` ```
#### Request
```shell
curl -X POST http://localhost:11434/api/generate -d '{
"model": "llama2:7b",
"prompt": "Why is the sky blue?",
"stream": false
}'
```
#### Response
If `stream` is set to `false`, the response will be a single JSON object:
```json
{
"model": "llama2:7b",
"created_at": "2023-08-04T19:22:45.499127Z",
"response": "The sky is blue because it is the color of the sky.",
"context": [1, 2, 3],
"done": true,
"total_duration": 5589157167,
"load_duration": 3013701500,
"sample_count": 114,
"sample_duration": 81442000,
"prompt_eval_count": 46,
"prompt_eval_duration": 1160282000,
"eval_count": 13,
"eval_duration": 1325948000
}
```
## Create a Model ## Create a Model
```shell ```shell
...@@ -114,9 +148,11 @@ Create a model from a [`Modelfile`](./modelfile.md) ...@@ -114,9 +148,11 @@ Create a model from a [`Modelfile`](./modelfile.md)
- `name`: name of the model to create - `name`: name of the model to create
- `path`: path to the Modelfile - `path`: path to the Modelfile
- `stream`: (optional) if `false` the response will be be returned as a single response object, rather than a stream of objects - `stream`: (optional) if `false` the response will be returned as a single response object, rather than a stream of objects
### Examples
### Request #### Request
```shell ```shell
curl -X POST http://localhost:11434/api/create -d '{ curl -X POST http://localhost:11434/api/create -d '{
...@@ -125,7 +161,7 @@ curl -X POST http://localhost:11434/api/create -d '{ ...@@ -125,7 +161,7 @@ curl -X POST http://localhost:11434/api/create -d '{
}' }'
``` ```
### Response #### Response
A stream of JSON objects. When finished, `status` is `success`. A stream of JSON objects. When finished, `status` is `success`.
...@@ -143,13 +179,17 @@ GET /api/tags ...@@ -143,13 +179,17 @@ GET /api/tags
List models that are available locally. List models that are available locally.
### Request ### Examples
#### Request
```shell ```shell
curl http://localhost:11434/api/tags curl http://localhost:11434/api/tags
``` ```
### Response #### Response
A single JSON object will be returned.
```json ```json
{ {
...@@ -180,7 +220,9 @@ Show details about a model including modelfile, template, parameters, license, a ...@@ -180,7 +220,9 @@ Show details about a model including modelfile, template, parameters, license, a
- `name`: name of the model to show - `name`: name of the model to show
### Request ### Examples
#### Request
```shell ```shell
curl http://localhost:11434/api/show -d '{ curl http://localhost:11434/api/show -d '{
...@@ -188,7 +230,7 @@ curl http://localhost:11434/api/show -d '{ ...@@ -188,7 +230,7 @@ curl http://localhost:11434/api/show -d '{
}' }'
``` ```
### Response #### Response
```json ```json
{ {
...@@ -207,7 +249,9 @@ POST /api/copy ...@@ -207,7 +249,9 @@ POST /api/copy
Copy a model. Creates a model with another name from an existing model. Copy a model. Creates a model with another name from an existing model.
### Request ### Examples
#### Request
```shell ```shell
curl http://localhost:11434/api/copy -d '{ curl http://localhost:11434/api/copy -d '{
...@@ -216,6 +260,10 @@ curl http://localhost:11434/api/copy -d '{ ...@@ -216,6 +260,10 @@ curl http://localhost:11434/api/copy -d '{
}' }'
``` ```
#### Response
The only response is a 200 OK if successful.
## Delete a Model ## Delete a Model
```shell ```shell
...@@ -226,9 +274,11 @@ Delete a model and its data. ...@@ -226,9 +274,11 @@ Delete a model and its data.
### Parameters ### Parameters
- `model`: model name to delete - `name`: model name to delete
### Request ### Examples
#### Request
```shell ```shell
curl -X DELETE http://localhost:11434/api/delete -d '{ curl -X DELETE http://localhost:11434/api/delete -d '{
...@@ -236,6 +286,10 @@ curl -X DELETE http://localhost:11434/api/delete -d '{ ...@@ -236,6 +286,10 @@ curl -X DELETE http://localhost:11434/api/delete -d '{
}' }'
``` ```
#### Response
If successful, the only response is a 200 OK.
## Pull a Model ## Pull a Model
```shell ```shell
...@@ -248,9 +302,11 @@ Download a model from the ollama library. Cancelled pulls are resumed from where ...@@ -248,9 +302,11 @@ Download a model from the ollama library. Cancelled pulls are resumed from where
- `name`: name of the model to pull - `name`: name of the model to pull
- `insecure`: (optional) allow insecure connections to the library. Only use this if you are pulling from your own library during development. - `insecure`: (optional) allow insecure connections to the library. Only use this if you are pulling from your own library during development.
- `stream`: (optional) if `false` the response will be be returned as a single response object, rather than a stream of objects - `stream`: (optional) if `false` the response will be returned as a single response object, rather than a stream of objects
### Examples
### Request #### Request
```shell ```shell
curl -X POST http://localhost:11434/api/pull -d '{ curl -X POST http://localhost:11434/api/pull -d '{
...@@ -258,13 +314,51 @@ curl -X POST http://localhost:11434/api/pull -d '{ ...@@ -258,13 +314,51 @@ curl -X POST http://localhost:11434/api/pull -d '{
}' }'
``` ```
### Response #### Response
If `stream` is not specified, or set to `true`, a stream of JSON objects is returned:
The first object is the manifest:
```json
{
"status": "pulling manifest"
}
```
Then there is a series of downloading responses. Until any of the download is completed, the `completed` key may not be included. The number of files to be downloaded depends on the number of layers specified in the manifest.
```json ```json
{ {
"status": "downloading digestname", "status": "downloading digestname",
"digest": "digestname", "digest": "digestname",
"total": 2142590208 "total": 2142590208,
"completed": 241970
}
```
After all the files are downloaded, the final responses are:
```json
{
"status": "verifying sha256 digest"
}
{
"status": "writing manifest"
}
{
"status": "removing any unused layers"
}
{
"status": "success"
}
```
if `stream` is set to false, then the response is a single JSON object:
```json
{
"status": "success"
} }
``` ```
...@@ -280,9 +374,11 @@ Upload a model to a model library. Requires registering for ollama.ai and adding ...@@ -280,9 +374,11 @@ Upload a model to a model library. Requires registering for ollama.ai and adding
- `name`: name of the model to push in the form of `<namespace>/<model>:<tag>` - `name`: name of the model to push in the form of `<namespace>/<model>:<tag>`
- `insecure`: (optional) allow insecure connections to the library. Only use this if you are pushing to your library during development. - `insecure`: (optional) allow insecure connections to the library. Only use this if you are pushing to your library during development.
- `stream`: (optional) if `false` the response will be be returned as a single response object, rather than a stream of objects - `stream`: (optional) if `false` the response will be returned as a single response object, rather than a stream of objects
### Request ### Examples
#### Request
```shell ```shell
curl -X POST http://localhost:11434/api/push -d '{ curl -X POST http://localhost:11434/api/push -d '{
...@@ -290,9 +386,9 @@ curl -X POST http://localhost:11434/api/push -d '{ ...@@ -290,9 +386,9 @@ curl -X POST http://localhost:11434/api/push -d '{
}' }'
``` ```
### Response #### Response
Streaming response that starts with: If `stream` is not specified, or set to `true`, a stream of JSON objects is returned:
```json ```json
{ "status": "retrieving manifest" } { "status": "retrieving manifest" }
...@@ -325,6 +421,12 @@ Finally, when the upload is complete: ...@@ -325,6 +421,12 @@ Finally, when the upload is complete:
{"status":"success"} {"status":"success"}
``` ```
If `stream` is set to `false`, then the response is a single JSON object:
```json
{ "status": "success" }
```
## Generate Embeddings ## Generate Embeddings
```shell ```shell
...@@ -342,7 +444,9 @@ Advanced parameters: ...@@ -342,7 +444,9 @@ Advanced parameters:
- `options`: additional model parameters listed in the documentation for the [Modelfile](./modelfile.md#valid-parameters-and-values) such as `temperature` - `options`: additional model parameters listed in the documentation for the [Modelfile](./modelfile.md#valid-parameters-and-values) such as `temperature`
### Request ### Examples
#### Request
```shell ```shell
curl -X POST http://localhost:11434/api/embeddings -d '{ curl -X POST http://localhost:11434/api/embeddings -d '{
...@@ -351,7 +455,7 @@ curl -X POST http://localhost:11434/api/embeddings -d '{ ...@@ -351,7 +455,7 @@ curl -X POST http://localhost:11434/api/embeddings -d '{
}' }'
``` ```
### Response #### Response
```json ```json
{ {
......
...@@ -185,7 +185,7 @@ python convert.py <path to model directory> ...@@ -185,7 +185,7 @@ python convert.py <path to model directory>
python convert-falcon-hf-to-gguf.py <path to model directory> python convert-falcon-hf-to-gguf.py <path to model directory>
# GPTNeoXForCausalLM # GPTNeoXForCausalLM
python convert-falcon-hf-to-gguf.py <path to model directory> python convert-gptneox-hf-to-gguf.py <path to model directory>
# GPTBigCodeForCausalLM # GPTBigCodeForCausalLM
python convert-starcoder-hf-to-gguf.py <path to model directory> python convert-starcoder-hf-to-gguf.py <path to model directory>
......
...@@ -6,7 +6,6 @@ PERSIST_DIRECTORY = os.environ.get('PERSIST_DIRECTORY', 'db') ...@@ -6,7 +6,6 @@ PERSIST_DIRECTORY = os.environ.get('PERSIST_DIRECTORY', 'db')
# Define the Chroma settings # Define the Chroma settings
CHROMA_SETTINGS = Settings( CHROMA_SETTINGS = Settings(
chroma_db_impl='duckdb+parquet',
persist_directory=PERSIST_DIRECTORY, persist_directory=PERSIST_DIRECTORY,
anonymized_telemetry=False anonymized_telemetry=False
) )
...@@ -150,7 +150,7 @@ def main(): ...@@ -150,7 +150,7 @@ def main():
print("Creating new vectorstore") print("Creating new vectorstore")
texts = process_documents() texts = process_documents()
print(f"Creating embeddings. May take some minutes...") print(f"Creating embeddings. May take some minutes...")
db = Chroma.from_documents(texts, embeddings, persist_directory=persist_directory, client_settings=CHROMA_SETTINGS) db = Chroma.from_documents(texts, embeddings, persist_directory=persist_directory)
db.persist() db.persist()
db = None db = None
......
...@@ -4,6 +4,7 @@ from langchain.embeddings import HuggingFaceEmbeddings ...@@ -4,6 +4,7 @@ from langchain.embeddings import HuggingFaceEmbeddings
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from langchain.vectorstores import Chroma from langchain.vectorstores import Chroma
from langchain.llms import Ollama from langchain.llms import Ollama
import chromadb
import os import os
import argparse import argparse
import time import time
...@@ -22,7 +23,9 @@ def main(): ...@@ -22,7 +23,9 @@ def main():
# Parse the command line arguments # Parse the command line arguments
args = parse_arguments() args = parse_arguments()
embeddings = HuggingFaceEmbeddings(model_name=embeddings_model_name) embeddings = HuggingFaceEmbeddings(model_name=embeddings_model_name)
db = Chroma(persist_directory=persist_directory, embedding_function=embeddings, client_settings=CHROMA_SETTINGS)
db = Chroma(persist_directory=persist_directory, embedding_function=embeddings)
retriever = db.as_retriever(search_kwargs={"k": target_source_chunks}) retriever = db.as_retriever(search_kwargs={"k": target_source_chunks})
# activate/deactivate the streaming StdOut callback for LLMs # activate/deactivate the streaming StdOut callback for LLMs
callbacks = [] if args.mute_stream else [StreamingStdOutCallbackHandler()] callbacks = [] if args.mute_stream else [StreamingStdOutCallbackHandler()]
......
...@@ -11,7 +11,6 @@ require ( ...@@ -11,7 +11,6 @@ require (
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
golang.org/x/sync v0.3.0 golang.org/x/sync v0.3.0
gonum.org/v1/gonum v0.14.0
) )
require github.com/rivo/uniseg v0.2.0 // indirect require github.com/rivo/uniseg v0.2.0 // indirect
......
...@@ -306,13 +306,19 @@ func newLlama(model string, adapters []string, runners []ModelRunner, numLayers ...@@ -306,13 +306,19 @@ func newLlama(model string, adapters []string, runners []ModelRunner, numLayers
params := []string{ params := []string{
"--model", model, "--model", model,
"--ctx-size", fmt.Sprintf("%d", opts.NumCtx), "--ctx-size", fmt.Sprintf("%d", opts.NumCtx),
"--rope-freq-base", fmt.Sprintf("%f", opts.RopeFrequencyBase),
"--rope-freq-scale", fmt.Sprintf("%f", opts.RopeFrequencyScale),
"--batch-size", fmt.Sprintf("%d", opts.NumBatch), "--batch-size", fmt.Sprintf("%d", opts.NumBatch),
"--n-gpu-layers", fmt.Sprintf("%d", numGPU), "--n-gpu-layers", fmt.Sprintf("%d", numGPU),
"--embedding", "--embedding",
} }
if opts.RopeFrequencyBase > 0 {
params = append(params, "--rope-freq-base", fmt.Sprintf("%f", opts.RopeFrequencyBase))
}
if opts.RopeFrequencyScale > 0 {
params = append(params, "--rope-freq-scale", fmt.Sprintf("%f", opts.RopeFrequencyScale))
}
if opts.NumGQA > 0 { if opts.NumGQA > 0 {
params = append(params, "--gqa", fmt.Sprintf("%d", opts.NumGQA)) params = append(params, "--gqa", fmt.Sprintf("%d", opts.NumGQA))
} }
...@@ -360,7 +366,15 @@ func newLlama(model string, adapters []string, runners []ModelRunner, numLayers ...@@ -360,7 +366,15 @@ func newLlama(model string, adapters []string, runners []ModelRunner, numLayers
runner.Path, runner.Path,
append(params, "--port", strconv.Itoa(port))..., append(params, "--port", strconv.Itoa(port))...,
) )
cmd.Env = append(os.Environ(), fmt.Sprintf("LD_LIBRARY_PATH=%s", filepath.Dir(runner.Path)))
var libraryPaths []string
if libraryPath, ok := os.LookupEnv("LD_LIBRARY_PATH"); ok {
libraryPaths = append(libraryPaths, libraryPath)
}
libraryPaths = append(libraryPaths, filepath.Dir(runner.Path))
cmd.Env = append(os.Environ(), fmt.Sprintf("LD_LIBRARY_PATH=%s", strings.Join(libraryPaths, ":")))
cmd.Stdout = os.Stderr cmd.Stdout = os.Stderr
statusWriter := NewStatusWriter() statusWriter := NewStatusWriter()
cmd.Stderr = statusWriter cmd.Stderr = statusWriter
......
...@@ -85,7 +85,10 @@ func New(workDir, model string, adapters []string, opts api.Options) (LLM, error ...@@ -85,7 +85,10 @@ func New(workDir, model string, adapters []string, opts api.Options) (LLM, error
switch ggml.Name() { switch ggml.Name() {
case "gguf": case "gguf":
opts.NumGQA = 0 // TODO: remove this when llama.cpp runners differ enough to need separate newLlama functions // TODO: gguf will load these options automatically from the model binary
opts.NumGQA = 0
opts.RopeFrequencyBase = 0.0
opts.RopeFrequencyScale = 0.0
return newLlama(model, adapters, chooseRunners(workDir, "gguf"), ggml.NumLayers(), opts) return newLlama(model, adapters, chooseRunners(workDir, "gguf"), ggml.NumLayers(), opts)
case "ggml", "ggmf", "ggjt", "ggla": case "ggml", "ggmf", "ggjt", "ggla":
return newLlama(model, adapters, chooseRunners(workDir, "ggml"), ggml.NumLayers(), opts) return newLlama(model, adapters, chooseRunners(workDir, "ggml"), ggml.NumLayers(), opts)
......
...@@ -2,6 +2,7 @@ package readline ...@@ -2,6 +2,7 @@ package readline
import ( import (
"fmt" "fmt"
"os"
"github.com/emirpasic/gods/lists/arraylist" "github.com/emirpasic/gods/lists/arraylist"
"golang.org/x/term" "golang.org/x/term"
...@@ -17,7 +18,8 @@ type Buffer struct { ...@@ -17,7 +18,8 @@ type Buffer struct {
} }
func NewBuffer(prompt *Prompt) (*Buffer, error) { func NewBuffer(prompt *Prompt) (*Buffer, error) {
width, height, err := term.GetSize(0) fd := int(os.Stdout.Fd())
width, height, err := term.GetSize(fd)
if err != nil { if err != nil {
fmt.Println("Error getting size:", err) fmt.Println("Error getting size:", err)
return nil, err return nil, err
......
...@@ -51,11 +51,12 @@ func (i *Instance) Readline() (string, error) { ...@@ -51,11 +51,12 @@ func (i *Instance) Readline() (string, error) {
} }
fmt.Print(prompt) fmt.Print(prompt)
termios, err := SetRawMode(syscall.Stdin) fd := int(syscall.Stdin)
termios, err := SetRawMode(fd)
if err != nil { if err != nil {
return "", err return "", err
} }
defer UnsetRawMode(syscall.Stdin, termios) defer UnsetRawMode(fd, termios)
buf, _ := NewBuffer(i.Prompt) buf, _ := NewBuffer(i.Prompt)
......
//go:build darwin || freebsd || netbsd || openbsd //go:build darwin || freebsd || netbsd || openbsd
package readline package readline
import ( import (
......
//go:build linux || solaris //go:build linux || solaris
package readline package readline
import ( import (
......
package readline
import (
"syscall"
"unsafe"
)
const (
enableLineInput = 2
enableWindowInput = 8
enableMouseInput = 16
enableInsertMode = 32
enableQuickEditMode = 64
enableExtendedFlags = 128
enableProcessedOutput = 1
enableWrapAtEolOutput = 2
enableAutoPosition = 256 // Cursor position is not affected by writing data to the console.
enableEchoInput = 4 // Characters are written to the console as they're read.
enableProcessedInput = 1 // Enables input processing (like recognizing Ctrl+C).
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var (
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
)
type State struct {
mode uint32
}
// IsTerminal checks if the given file descriptor is associated with a terminal
func IsTerminal(fd int) bool {
var st uint32
r, _, e := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
// if the call succeeds and doesn't produce an error, it's a terminal
return r != 0 && e == 0
}
func SetRawMode(fd int) (*State, error) {
var st uint32
// retrieve the current mode of the terminal
_, _, e := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
if e != 0 {
return nil, error(e)
}
// modify the mode to set it to raw
raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
// apply the new mode to the terminal
_, _, e = syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(fd), uintptr(raw), 0)
if e != 0 {
return nil, error(e)
}
// return the original state so that it can be restored later
return &State{st}, nil
}
func UnsetRawMode(fd int, state *State) error {
_, _, err := syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(fd), uintptr(state.mode), 0)
return err
}
...@@ -63,7 +63,10 @@ status "Installing ollama to $BINDIR..." ...@@ -63,7 +63,10 @@ status "Installing ollama to $BINDIR..."
$SUDO install -o0 -g0 -m755 -d $BINDIR $SUDO install -o0 -g0 -m755 -d $BINDIR
$SUDO install -o0 -g0 -m755 $TEMP_DIR/ollama $BINDIR/ollama $SUDO install -o0 -g0 -m755 $TEMP_DIR/ollama $BINDIR/ollama
install_success() { status 'Install complete. Run "ollama" from the command line.'; } install_success() {
status 'The Ollama API is now available at 0.0.0.0:11434.'
status 'Install complete. Run "ollama" from the command line.'
}
trap install_success EXIT trap install_success EXIT
# Everything from this point onwards is optional. # Everything from this point onwards is optional.
...@@ -130,6 +133,7 @@ if check_gpu nvidia-smi; then ...@@ -130,6 +133,7 @@ if check_gpu nvidia-smi; then
fi fi
if ! check_gpu lspci && ! check_gpu lshw; then if ! check_gpu lspci && ! check_gpu lshw; then
install_success
warning "No NVIDIA GPU detected. Ollama will run in CPU-only mode." warning "No NVIDIA GPU detected. Ollama will run in CPU-only mode."
exit 0 exit 0
fi fi
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment