ollama搭建本地ai大模型并应用调用

news/2024/11/15 21:20:51/文章来源:https://www.cnblogs.com/ggtop/p/18368333

1、下载ollama

1)https://ollama.com 进入网址,点击download下载
2)下载后直接安装即可。

2、启动配置模型

默认是启动cmd窗口直接输入

1 ollama run llama3

启动llama3大模型 或者启动千问大模型

1 ollama run qwen2

启动输入你需要输入的问题即可

 

3、配置UI界面

安装docker
并部署web操作界面

1 docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui --restart always ghcr.io/open-webui/open-webui:main

安装完毕后,安装包较大,需等待一段时间。
localhost:3000即可打开网址

 

4、搭建本地知识库

AnythingLLM

5、配置文件

开发11434端口,便于外部访问接口,如果跨域访问的话配置OLLAMA_ORIGINS=*

Windows版

只需要在系统环境变量中直接配置,

OLLAMA_HOST为变量名,"0.0.0.0:11434"为变量值

1 OLLAMA_HOST= "0.0.0.0:11434"

MAC版

配置OLLAMA_HOST

1 sudo sh -c 'echo "export OLLAMA_HOST=0.0.0.0:11434">>/etc/profile'launchctl setenv OLLAMA_HOST "0.0.0.0:11434"

Linux版

配置OLLAMA_HOST

1 Environment="OLLAMA\_HOST=0.0.0.0"

6、程序调用接口

golang实现例子:流式响应速度更快,用户体验更佳。

golang例子:非流式响应

package main

import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)

const (
obaseURL = "http://localhost:11434/api"
omodelID = "qwen2:0.5b" // 选择合适的模型
oendpoint = "/chat" //"/chat/completions"
)

// ChatCompletionRequest 定义了请求体的结构
type olChatCompletionRequest struct {
Model string `json:"model"`
Messages []struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"messages"`
Stream bool `json:"stream"`
//Temperature float32 `json:"temperature"`
}

// ChatCompletionResponse 定义了响应体的结构
type olChatCompletionResponse struct {
//Choices []struct {
Message struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"message"`
//} `json:"choices"`
}

// sendRequestWithRetry 发送请求并处理可能的429错误
func olsendRequestWithRetry(client *http.Client, requestBody []byte) (*http.Response, error) {
req, err := http.NewRequest("POST", obaseURL+oendpoint, bytes.NewBuffer(requestBody))
if err != nil {
return nil, err
}

req.Header.Set("Content-Type", "application/json")
//req.Header.Set("Authorization", "Bearer "+apiKey)

resp, err := client.Do(req)
if err != nil {
return nil, err
}

if resp.StatusCode == http.StatusTooManyRequests {
retryAfter := resp.Header.Get("Retry-After")
if retryAfter != "" {
duration, _ := time.ParseDuration(retryAfter)
time.Sleep(duration)
} else {
time.Sleep(5 * time.Second) // 默认等待5秒
}
return olsendRequestWithRetry(client, requestBody) // 递归重试
}

return resp, nil
}

func main() {
client := &http.Client{} // 创建一个全局的 HTTP 客户端实例

// 初始化对话历史记录
history := []struct {
Role string `json:"role"`
Content string `json:"content"`
}{
{"system", "你是一位唐代诗人,特别擅长模仿李白的风格。"},
}

// 创建标准输入的扫描器
scanner := bufio.NewScanner(os.Stdin)

for {
fmt.Print("请输入您的问题(或者输入 'exit' 退出): ")
scanner.Scan()
userInput := strings.TrimSpace(scanner.Text())

// 退出条件
if userInput == "exit" {
fmt.Println("感谢使用,再见!")
break
}

// 添加用户输入到历史记录
history = append(history, struct {
Role string `json:"role"`
Content string `json:"content"`
}{
"user",
userInput,
})

// 创建请求体
requestBody := olChatCompletionRequest{
Model: omodelID,
Messages: history,
Stream: false,
//Temperature: 0.7,
}

// 构建完整的请求体,包含历史消息
requestBody.Messages = append([]struct {
Role string `json:"role"`
Content string `json:"content"`
}{
{
Role: "system",
Content: "你是一位唐代诗人,特别擅长模仿李白的风格。",
},
}, history...)

// 将请求体序列化为 JSON
requestBodyJSON, err := json.Marshal(requestBody)
if err != nil {
fmt.Println("Error marshalling request body:", err)
continue
}
fmt.Println("wocao:" + string(requestBodyJSON))
// 发送请求并处理重试
resp, err := olsendRequestWithRetry(client, requestBodyJSON)
if err != nil {
fmt.Println("Error sending request after retries:", err)
continue
}
defer resp.Body.Close()

// 检查响应状态码
if resp.StatusCode != http.StatusOK {
fmt.Printf("Received non-200 response status code: %d\n", resp.StatusCode)
continue
}

// 读取响应体
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
continue
}
//fmt.Println("0000" + string(responseBody))
// 解析响应体
var completionResponse olChatCompletionResponse
err = json.Unmarshal(responseBody, &completionResponse)
if err != nil {
fmt.Println("Error unmarshalling response body:", err)
continue
}
fmt.Printf("AI 回复: %s\n", completionResponse.Message.Content) // choice.Message.Content
// 将用户的消息添加到历史记录中
history = append(history, struct {
Role string `json:"role"`
Content string `json:"content"`
}{
Role: completionResponse.Message.Role,
Content: completionResponse.Message.Content, // 假设用户的消息是第一个
}) 

}
}

 

golang例子:流式响应
  1 package main
  2 
  3 import (
  4     "bufio"
  5     "bytes"
  6     "encoding/json"
  7     "fmt"
  8     "io"
  9     "net/http"
 10     "os"
 11     "strings"
 12     "time"
 13 )
 14 
 15 const (
 16     obaseURL  = "http://localhost:11434/api" 
 17     omodelID  = "qwen2:0.5b"                 // 选择合适的模型
 18     oendpoint = "/chat"                      //"/chat/completions"
 19 )
 20 
 21 // ChatCompletionRequest 定义了请求体的结构
 22 type olChatCompletionRequest struct {
 23     Model    string `json:"model"`
 24     Messages []struct {
 25         Role    string `json:"role"`
 26         Content string `json:"content"`
 27     } `json:"messages"`
 28     Stream bool `json:"stream"`
 29     //Temperature float32 `json:"temperature"`
 30 }
 31 
 32 // ChatCompletionResponse 定义了响应体的结构
 33 type olChatCompletionResponse struct {
 34     //Choices []struct {
 35     Message struct {
 36         Role    string `json:"role"`
 37         Content string `json:"content"`
 38     } `json:"message"`
 39     //} `json:"choices"`
 40 }
 41 
 42 // sendRequestWithRetry 发送请求并处理可能的429错误
 43 func olsendRequestWithRetry(client *http.Client, requestBody []byte) (*http.Response, error) {
 44     req, err := http.NewRequest("POST", obaseURL+oendpoint, bytes.NewBuffer(requestBody))
 45     if err != nil {
 46         return nil, err
 47     }
 48 
 49     req.Header.Set("Content-Type", "application/json")
 50     //req.Header.Set("Authorization", "Bearer "+apiKey)
 51 
 52     resp, err := client.Do(req)
 53     if err != nil {
 54         return nil, err
 55     }
 56 
 57     if resp.StatusCode == http.StatusTooManyRequests {
 58         retryAfter := resp.Header.Get("Retry-After")
 59         if retryAfter != "" {
 60             duration, _ := time.ParseDuration(retryAfter)
 61             time.Sleep(duration)
 62         } else {
 63             time.Sleep(5 * time.Second) // 默认等待5秒
 64         }
 65         return olsendRequestWithRetry(client, requestBody) // 递归重试
 66     }
 67 
 68     return resp, nil
 69 }
 70 
 71 func main() {
 72     client := &http.Client{} // 创建一个全局的 HTTP 客户端实例
 73 
 74     // 初始化对话历史记录
 75     history := []struct {
 76         Role    string `json:"role"`
 77         Content string `json:"content"`
 78     }{
 79         {"system", "你是一位唐代诗人,特别擅长模仿李白的风格。"},
 80     }
 81 
 82     // 创建标准输入的扫描器
 83     scanner := bufio.NewScanner(os.Stdin)
 84 
 85     for {
 86         fmt.Print("请输入您的问题(或者输入 'exit' 退出): ")
 87         scanner.Scan()
 88         userInput := strings.TrimSpace(scanner.Text())
 89 
 90         // 退出条件
 91         if userInput == "exit" {
 92             fmt.Println("感谢使用,再见!")
 93             break
 94         }
 95 
 96         // 添加用户输入到历史记录
 97         history = append(history, struct {
 98             Role    string `json:"role"`
 99             Content string `json:"content"`
100         }{
101             "user",
102             userInput,
103         })
104 
105         // 创建请求体
106         requestBody := olChatCompletionRequest{
107             Model:    omodelID,
108             Messages: history,
109             Stream:   true,
110             //Temperature: 0.7,
111         }
112 
113         // 构建完整的请求体,包含历史消息
114         requestBody.Messages = append([]struct {
115             Role    string `json:"role"`
116             Content string `json:"content"`
117         }{
118             {
119                 Role:    "system",
120                 Content: "你是一位唐代诗人,特别擅长模仿李白的风格。",
121             },
122         }, history...)
123 
124         // 将请求体序列化为 JSON
125         requestBodyJSON, err := json.Marshal(requestBody)
126         if err != nil {
127             fmt.Println("Error marshalling request body:", err)
128             continue
129         }
130         fmt.Println("wocao:" + string(requestBodyJSON))
131         // 发送请求并处理重试
132         resp, err := olsendRequestWithRetry(client, requestBodyJSON)
133         if err != nil {
134             fmt.Println("Error sending request after retries:", err)
135             continue
136         }
137         defer resp.Body.Close()
138 
139         // 检查响应状态码
140         if resp.StatusCode != http.StatusOK {
141             fmt.Printf("Received non-200 response status code: %d\n", resp.StatusCode)
142             continue
143         }
144                resutlmessage := ""
145         streamReader := resp.Body
146         buf := make([]byte, 1024) // 或者使用更大的缓冲区来提高读取性能
147         var completionResponse olChatCompletionResponse
148         fmt.Print("AI 回复:")
149         for {
150             n, err := streamReader.Read(buf)
151             if n > 0 {
152                 // 处理接收到的数据,这里简单打印出来
153                 //fmt.Print(string(buf[:n]))
154                 err = json.Unmarshal(buf[:n], &completionResponse)
155                 fmt.Print(string(completionResponse.Message.Content))
156                                resutlmessage+=string(completionResponse.Message.Content)
157                 if err != nil {
158                     fmt.Println("Error unmarshalling response body:", err)
159                     continue
160                 }
161             }
162             if err != nil {
163                 if err == io.EOF {
164                     fmt.Println("")
165                     break
166                 }
167                 panic(err)
168             }
169         }
170 
171         // 将用户的消息添加到历史记录中
172         history = append(history, struct {
173             Role    string `json:"role"`
174             Content string `json:"content"`
175         }{
176             Role:    completionResponse.Message.Role,
177             Content: resutlmessage,//completionResponse.Message.Content, // 假设用户的消息是第一个
178         })
179     }
180 }

 


感谢观看,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/784039.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fluent Editor:一个基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用!

你好,我是Kagol,个人公众号:前端开源星球。带大家一起使用下 Fluent Editor,使用起来基本上和 Quill 没什么区别,只需要重点关注下增强的部分,比如表格、附件、@提醒、表情等模块。你好,我是 Kagol,个人公众号:前端开源星球。 今年4月份,听到 Quill 2.0 正式发布的消…

二进制下载部署Nginx

一、通过Nginx官网并采取二进制方式部署 Nginx官网 二、具体步骤[root@web01 yum.repos.d]# ll -d nginx.repo -rw-r--r--. 1 root root 398 Aug 17 22:01 nginx.repo [root@web01 yum.repos.d]# pwd /etc/yum.repos.d接下来可以直接使用 yum -y install nginx 则是直接从官方下…

c语言中%f和%lf读入浮点型数据

001、a、%lf、和 %f读入double型值[root@PC1 test]# ls test.c [root@PC1 test]# cat test.c ## 测试程序 #include <stdio.h>int main(void) {double i, j; // 声明两个double型变量printf("i: "); scanf("%lf", &…

万兆以太网协议栈的FPGA实现(三):万兆网CRC

参考: 基于FPGA的千兆以太网的实现(3)_以太网crc计算-CSDN博客CRC 802.11来自将8位数据同时输入,再输出32位CRC数值; 其能成功实现的原因就是因为并行化。(下路仅是部分的计算步骤)结合千兆网CRC的计算思想,我们只需要把第一轮单字节CRC的结果作为第二轮CRC的开始,就可…

面试场景题:一次关于线程池使用场景的讨论。

你好呀,我是歪歪。 来一起看看一个关于线程池使用场景上的问题,就当是个场景面试题了。 问题是这样的:字有点多,我直接给你上个图你就懂了:前端发起一个生成报表页面的请求,这个页面上的数据由后端多个接口返回,另外由于微服务化了,所以数据散落在每个微服务中,因此需…

R语言VAR模型的多行业关联与溢出效应可视化分析

全文链接:https://tecdat.cn/?p=37397 原文出处:拓端数据部落公众号 摘要:本文对医疗卫生、通信、金融、房地产和零售等行业的数据展开深入研究。通过读取数据、计算收益率、构建 VAR 模型并进行估计,进一步分析各行业变量的影响及残差的协方差与相关矩阵。同时,计算传…

【流程化办公利器】可视化表单拖拽生成器优势多

一起来了解可视化表单拖拽生成器的诸多优势特点,看看它是如何给企业高效助力的。当前,实现流程化办公早已成为大家的发展愿景。低代码技术平台拥有可视化操作界面、够灵活、易操作等多个优势特点,可以在推动企业实现降本、增效、提质等方面全力护航,是不多得的优质软件平台…

C#上传excel,解析主从表,1W数据快速插入数据库,5s完成

参考文章 net core天马行空系列-各大数据库快速批量插入数据方法汇总 ExcelMapperController核心代码 [HttpPost] public async Task<IActionResult> ImportToDoItems(IFormFile file) {if (file == null || file.Length == 0){return BadRequest("File is empty&qu…

Linux scp 文件传输

scp将本服务器的文件传输到远程服务器 基本语法 scp `[源路径]` `[目标服务器]`:`[目标路径]`样例 将本服务器123.txt文件传输到远程服务器并重命名为456.txt scp 123.txt user@remote_server:/home/tabu/456.txt使用-r选项复制整个目录 scp -r tabu/* user@remote_server:/hom…

Android libusb

一、环境:配置NDK环境 1、下载libusb源码: https://github.com/libusb/libusb/releases,如下图所示2、删除一些和Android平台无关的文件,删除后的文件如下图所示:思考问题:Android是怎么获取usb设备?如上图所示:连接adb shell,然后cd到/sys/bus/usb/devices/目录,命令…