langchain
前段时间去玩了一下langchain,熟悉了一下大模型的基本概念,使用等。前段时间meta
的ollama
模型发布了3.0,感觉还是比较强大的,在了解过后,自己去用前后端代码,调用ollama
模型搭建了一个本地的gpt应用。
核心逻辑
开始搭建
首先本地需要安装ollama的模型,这里有两种方式,大家自己选择即可,第一种选择官网下载ollama, 第二种可以去docker hub里面下载,里面有ollama的镜像包, 这里为了方便我就用第一种了。
ollama
下载好之后,我们直接执行
ollama serve
命令即可, 出现下面的样子,代表执行成功了。
这时候ollama会运行在11434
端口,这样我们的后端可以通过端口连接到ollama的服务了。
ollama run llama3
直接执行这个命令就可以在本地终端里起一个gpt, llama3
是ollama
最新的模型
后端代码实现
后端我们用nestjs
来搭建
首先我们需要安装一个langchain的包 @langchain/community
, 我这里选用的社区版,支持度比较好,模型也比较多。
!!!⚠️注意点
推荐用npm和yarn安装, pnpm安装会导致失败,官网上面也有说明这个,楼主踩过坑,如果非要用pnpm安装的话,按照官网指示的操作来
import { Controller, Post, Body, Sse, Header } from '@nestjs/common';
import { Observable, Subject } from 'rxjs';
import { Ollama } from '@langchain/community/llms/ollama';
@Controller()
export class AppController {
private messageSubject = new Subject<MessageEvent>();
private model: Ollama;
constructor() {
this.model = new Ollama({
baseUrl: 'http://localhost:11434',
model: 'llama3',
});
}
@Sse('sse')
@Header('Content-Type', 'text/event-stream')
sse(): Observable<MessageEvent> {
return this.messageSubject.asObservable();
}
@Post('question')
async addList(@Body() body: { question: string }): Promise<any> {
const stream = await this.model.stream(body.question);
for await (const str of stream) {
this.messageSubject.next({
data: JSON.stringify({ answer: str, end: false }),
} as MessageEvent);
Å
}
this.messageSubject.next({
data: JSON.stringify({ answer: '', end: true }),
} as MessageEvent);
}
}
sse技术
是一种基于HTTP协议的服务器到客户端的单向数据通信技术,允许服务器向浏览器实时推送更新,而不需要客户端通过轮询等方式反复请求数据。很多gpt应用服务端向客户端发送消息都是利用这种方式去做的。SSE协议本质上就是一个Http的get请求,也支持Https,服务端在接到该请求后,返回状态。同时请求头设置也变为流形式。
Content-Type: text/event-stream,
这里因为只是示例demo,逻辑就写在controller层了,标准一点的还是抽到service层。
nest的sse接口返回值是一个Observable(可观察对象)
, 刚好在rxjs中,我们的suject(主体)也是一种Observable
suject和普通的Observable区别在于,suject是多播,并且像EventEmitters
,像维护着多个监听器的一张注册表,当我们在请求到ollama返回的数据后,就可以调用next方法,将值多播到Observale中,这样就可以做到结果的接收
这个next方法,其实也就是迭代器方法,不断的调用next,会不断的输出值,直到没有值为止, 这里的end属性是控制我们客户端什么时候和服务端断开连接。
前端实现
前端的逻辑就很简单了,当我们发送问题后,监听到服务端发过来的结果收集起来展示即可,我这里的样式写的比较简陋,功能也只是最基本的,大家可以自己完善
import { useRef, useState } from "react";
type Message = {
answer: string;
end: boolean;
};
export default function Layout() {
const [message, setMessage] = useState<Message[]>([]);
const [question, setQuestion] = useState<string>("");
const ref = useRef<any>();
const send = () => {
const question = ref.current.value as string;
if (!question) return;
fetch("http://localhost:3000/question", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
question,
}),
});
setQuestion(question);
ref.current.value = "";
setMessage((prev) => [...prev, { answer: "", end: false }]);
const eventSource = new EventSource("http://localhost:3000/sse");
eventSource.onmessage = ({ data }) => {
const { answer, end } = JSON.parse(data);
if (!end) {
setMessage((prev) => {
const newMessages = [...prev];
newMessages[newMessages.length - 1].answer += answer;
return newMessages;
});
}
if (end) {
eventSource.close();
}
};
};
return (
<div className="h-screen w-screen overflow-hidden bg-orange-400">
<nav className="w-full h-16 flex items-center justify-between bg-indigo-400 px-4">
<span className="w-10 h-10">
<img src="public/ollama.png" className="w-full h-full" />
</span>
<span>ollama大模型</span>
<span className="">欢迎使用</span>
</nav>
<div className="w-full h-[calc(100%-64px)] relative">
<aside className="w-[200px] bg-red-400 h-full p-4 absolute top-0 flex justify-center">
todo
</aside>
<main className="w-full h-full absolute left-[200px] top-0 px-2">
<div className="w-full h-[calc(100%-64px)] py-4 overflow-y-auto">
<div
style={{
display: question ? "block" : "none",
}}
className="human min-h-[100px] w-[calc(100%-200px)] p-4 rounded-lg text-white bg-yellow-300"
>
{question}
</div>
<div
style={{
display: message?.[message.length - 1]?.answer
? "block"
: "none",
}}
className="ai min-h-[100px] text-white w-[calc(100%-200px)] bg-indigo-500 mt-5 rounded-lg p-4 "
>
{message?.[message.length - 1]?.answer}
</div>
</div>
<footer className="rounded-lg relative bottom-2 w-[calc(100%-200px)] h-[64px] border-red-300 border-solid border-[1px]">
<input
ref={ref}
type="text"
className="rounded-lg w-full px-4 text-lg h-full caret-red-300 outline-none focus:border-[1px] focus:border-solid focus:border-red-500"
/>
<button
onClick={() => send()}
className="z-10 focus:text-red-700 absolute right-0 top-0 w-[64px] h-[62px] bg-red-300"
>
发送
</button>
</footer>
</main>
</div>
</div>
);
}
看下实现效果
总结
ollama
的中文支持度不是很好,看视频效果也能看得出来,不过功能还是很强大的。 功能实现的比较基础,不过核心功能都有,大家可以参考代码自行拓展,动动手,你我都有属于自己的gpt
如何学习AI大模型?
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;
第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;
第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;
第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;
第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;
第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;
第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集
👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓