文章泉源:IT阅读排行榜
本文摘编自《大模型项目实战:多领域智能应用开发》,高强文 著,机器工业出版社出版,经出版方授权发布,转载请标明文章泉源。
目标
基于大语言模型的 Chat 应用,是一种利用自然语言处置处罚技能来进行对话交互的智能应用。
大语言模型通过大量数据的学习和训练,可以或许明白自然语言表达的语义,具备智能对话的本领。当用户向 Chat 应用提出问题时,Chat 应用就会利用其学习到的知识和自然语言处置处罚技能来明白用户的意图,然后推理生成相应的答案。
我们的目标是使用 React.js 开发一个通用的 Chat 应 用步伐,提供对话 Web 界面,调用 ChatGLM3 项目的 OpenAI 兼容接口,编译并部署到 Nginx。
功能概要
(1)Chat 交互界面
该应用使用 Chat 对话模式的界面,接收用户的输入内容,并将其显示到聊天记载中。大语言模型返回的结果会回写到聊天记载中。用户与大模型交换的文本用左右位置或图标进行区分。
(2)流式接口
这是指 OpenAI 兼容的流式调用方式,最早由 ChatGPT 使用,现在已成为大语言模型 Chat 应用究竟上的接口标准。流式访问是一种服务端逐步推送数据、客户端逐步接收结果并显示的方法,适用于处置处罚大量数据或长时间运行的任务。
(3)多轮会话
多轮对话是指模型把当前的问题及上文的问答情况整合到一起,形成关于问题的上下文形貌。由于在多轮会话中输入的 token 较长,问题的上下文形貌得比较清楚,相干语境也构建得相对完备,所以相比于单轮对话,多轮会话生成的答案更为公道。
其缺点在于随着对话轮数的增长,输入的 token 越来越长,会影响大语言模型的运算效率。所以在详细实现 Chat 应用时,要对汗青对话记载进行一定的限定,以防止输入 token 过长导致模型的生成性能降落。
(4)打字效果
ChatGPT 采用了模仿打字的视觉效果实现行文本的逐步生成,既保证用户能在第一时间获取生成的部分文本信息,不会觉得等候时间很长,也淘汰了大模型一次性生成长文本导致算力过载的情况。因此,这次所开发的应用也采用了此技能来显示文本的生成过程。
打字效果的实现基于 SSE 服务端推送技能。SSE 是一种 HTML5 技能,允许服务器向客户端推送数据,而不需要客户端主动请求。它能在服务端有新消息时,将消息实时推送到前 端,从而实现动态打字的聊天效果。
系统架构
Chat 应用是一个 B/S 结构的应用。服务端由大语言模型的 OpenAI API 服务提供,客户端使用 React.js 编写,部署于 Nginx。客户端通过欣赏器访问页面,在欣赏器中执行 JavaScript 代码,以将用户的输入发送至服务端,渲染页面显示服务端返回的结果。其架构图见图 1。
图 1 C h a t 应用架构图 图 1 Chat 应用架构图 图1Chat应用架构图
(1)大模型服务层
模型推理服务由大语言模型的代码完成,如在 ChatGLM3-6B 模型的 modeling_chatglm.py 文件中,stream_chat 函数实现了流式推理。模型 API 服务则由 ChatGLM3 项目源码中的openai_api_demo/api_server.py 提供。
(2)应用服务层
在开发情况下由 npm 模仿一个本地应用服务,承担页面下载和请求代理的职责。而在正式运行情况中,这两个职责是由 Nginx 的页面部署服务和代理转发功能来完成的。Nginx 在配置上还要支持 SSE 推流模式。
(3)客户端欣赏器层
通过运行在欣赏器中的 HTML5 和 JavaScript 代码来与应用服务层交互。JavaScript 发出的 HTTP/HTTPS 请求经应用服务层转发到模型 API 服务。
运行原理
- 欣赏器负责展现页面,调用 OpenAI 兼容接口来获取生成内容。
- Nginx 提供页面内容以及代理调用 OpenAI 兼容接口。
- 页面请求和接口调用在一个域名或IP:端口内,这样可以制止跨域问题。跨域问题是指在 Web 开发中,当一个网站的客户端(前端)需要调用服务端(后端)的 API 时,请求的 URL 与页面的 URL 来自差别的域名,导致安全风险,而被欣赏器拦截。
- openai_api.py 用于装载模型,提供 API 服务。
开发
(1)Node.js 安装
React.js 步伐的开发调试要在 Node.js 情况下进行。从 https://nodejs.org/ 中下载并安装 Node.js,然后在下令行运行node -v下令来测试它是否安装成功。
(2)chat-app 新建
1)新建应用新建一个名为 chat-app 的 React.js 应用,下令如下。
- npm install -g create-react-app
- create-react-app chat-app
- cd chat-app
复制代码 2)安装组件chat-app 用到两个第三方组件,一个是作为 Chat 界面的 ChatUI 框架,另一个是调用模型 API 服务的 Node.js 组件—openai-node。
- npm i --save @chatui/core
- npm i --save openai
复制代码 源代码
实现 Chat 页面和业务逻辑的代码在 src/app.js 中。它只有 61 行代码,下面完备展示出来。
- import './App.css';
- import React from 'react';
- import '@chatui/core/es/styles/index.less';
- import Chat, { Bubble, useMessages } from '@chatui/core';
- import '@chatui/core/dist/index.css';
- import OpenAI from 'openai';
- const openai = new OpenAI({
- apiKey: 'EMPTY', dangerouslyAllowBrowser: true,
- baseURL: "http://server-llm-dev:8000/v1"
- });
- var message_history = [];
- function App() {
- const { messages, appendMsg, setTyping, updateMsg } = useMessages([]);
- async function chat_stream(prompt, _msgId) {
- message_history.push({ role: 'user', content: prompt });
- const stream = openai.beta.chat.completions.stream({
- model: 'ChatGLM3-6B',
- messages: message_history,
- stream: true,
- });
- var snapshot = "";
- for await (const chunk of stream) {
- snapshot = snapshot + chunk.choices[0]?.delta?.content || '';
- updateMsg(_msgId, {
- type: "text",
- content: { text: snapshot.trim() }
- });
- }
- message_history.push({ "role": "assistant", "content": snapshot });
- }
- function handleSend(type, val) {
- if (type === 'text' && val.trim()) {
- appendMsg({
- type: 'text',
- content: { text: val },
- position: 'right',
- });
- const msgID = new Date().getTime();
- setTyping(true);
- appendMsg({
- _id: msgID,
- type: 'text',
- content: { text: '' },
- });
- chat_stream(val, msgID);
- }
- }
- function renderMessageContent(msg) {
- const { content } = msg;
- return <Bubble content={content.text} />;
- }
- return (
- <Chat
- navbar={{ title: 'chat-app' }}
- messages={messages}
- renderMessageContent={renderMessageContent}
- onSend={handleSend}
- />
- );
- }
- export default App;
复制代码 测试
(1)启动大模型 API 服务
安装 ChatGLM3-6B 模型。API 服务则由 ChatGLM3 代码库的 openai_api_demo/api_server.py 提供。在这个文件中,/v1/embeddings 接口依赖一个较小文本向量模型 BAAI/bge-large-zh-v1.5。虽然本次开发应用步伐中不会用到它,但为了保证步伐能正常运行,建议先下载这个模型。
- cd ChatGLM3
- conda activate ChatGLM3
- wget https://aliendao.cn/model_download.py
- python model_download.py --e --repo_id BAAI/bge-large-zh-v1.5 \
- --token YPY8KHDQ2NAHQ2SG
复制代码 设定模型及文本向量模型文件所在位置,启动 API 服务,监听 8000 端口。
- MODEL_PATH=./dataroot/models/THUDM/chatglm3-6b \
- EMBEDDING_PATH=./dataroot/models/BAAI/bge-large-zh-v1.5 \
- python openai_api_demo/api_server.py
复制代码 (2)测试 chat-app
客户端步伐目录下运行npm start下令,以启动客户端的开发情况服务。在欣赏器中打开http://localhost:3000,运行结果如图 2 所示。
图 2 c h a t − a p p 运行 图 2 chat-app 运行 图2chat−app运行
运行发现,在 chat-app 应用中,用户可以进行流式人机对话。该应用同时支持多轮对话,也实现了打字的视觉效果。
也就是说,该应用达到了原先设定的目标。
(3)界面美化
chat-app 是一个通用的 Chat 应用客户端,通过改变步伐中的apiKey和baseURL参数,可以毗连任意一个兼容 OpenAI 接口的大语言模型推理服务,当然包括在正确设置apiKey的情况下毗连 OpenAI 的服务。
此时,chat-app 的界面还需要进一步美化。比如,将输入框从一行变为多行以便于输入。
需要在 app.js 文件的同级目录下建一个 chatui-theme.css 文件,内容如下。
- .ChatFooter .Composer-input {
- background: white;
- max-height: 160px;
- border: 1px solid darkgray;
- min-height: 80px;
- height: auto;
- }
复制代码 在 app.js 文件中的第 6 行代码import OpenAI from ’openai’;后增长一行 下令,如下所示。
- import './chatui-theme.css';
复制代码 重新用npm start下令运行步伐,就可以看到输入框变成多行了。
应用发布
在步伐开发调试过程中,应用依赖于 Node.js,并以“ npm start”的方式运行。
对此,可以通过编译过程,将 React.js 步伐编译成离开 Node.js 的 HTML5 和 JavaScript 文件,部署到 Nginx 等应用服务器中运行。
(1)编译
运行以下下令编译源代码,将编译结果存放在 build 目录下。
(2)发布
将 build 目录下的所有文件复制到 Nginx 的 html 目录下即可完成部署。
如果是 Windows操作系统,则 html 在 Nginx 的目录下;如果是 Linux 操作系统,其目录则可能是/usr/local/share/nginx/html 或 /usr/local/nginx/html。
(3)运行
首次运行 Nginx 时,在 Windows 上直接运行 nginx.exe,在 Linux 上则要运行sudo nginx下令。
如果 Nginx 已运行,那么配置文件会发生改变,需要重启。可以执行以下下令。
对于该下令,在 Windows 或 Linux 上的情势几乎是一样的,区别在于因为涉及权限问题,对于 Linux 系统,需要在下令前加sudo。
(4)应用升级
借助欣赏器的缓存机制可以淘汰页面、JavaScript 代码的下载量。因为它会对相同请求 URL 的 HTML5 页面、JavaScript 代码进行缓存。然而,每次执行npm build下令产生的文件名是固定的,这样即使代码有调整,且 Nginx 的 html 目录下的文件已更新,但由于 URL 未发生变化,欣赏器仍会从缓存中加载旧版本。
为相识决这个问题,可修改 package.json 中的 version参数值,提高版本号,以编译出差别的文件名。这样欣赏器会由于 URL发生变化而忽略缓存,加载文件的最新版本。
(5)SSE 配置
启动 Nginx 服务后,就可以使用诸如http://127.0.0.1这样不带端口的 URL 访问页面,但是可能会存在跨域问题。因为页面临应 Nginx 所在盘算机的 80 端口,JavaScript 调用的是 API 服务器的 8000 端口,两者的 IP 和端口是不一样的。
如果 API 服务端不处置处罚跨域问题的话,chat-app 调 API 服务就会报跨域错误。解决的方法是在 Nginx 的 80 端口上配置一个 API 服务的路径代理。因为要支持 SSE,这个代理配置要与一般的路径代理有一定的区别。
举例来说,在 baseURL 为http://server-llm-dev:8000/v1的情况下,在 Nginx 的 conf/nginx.conf 中的 server 模块下增长一个location,如下所示。
- location /v1 {
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- # SSE 连接时的超时时间
- proxy_read_timeout 86400s;
- # 取消缓冲
- proxy_buffering off;
- # 关闭代理缓存
- proxy_cache off;
- # 禁用分块传输编码
- chunked_transfer_encoding off;
- # 反向代理到 SSE 应用的地址和端口
- proxy_pass http://server-llm-dev:8000/v1;
- }
复制代码 重启 Nginx,将 app.js 中的 baseURL 由http://server-llm-dev:8000/v1更改为http://127.0.0.1/ v1。
重新编译部署后,即可发现跨域问题得以解决。
文章泉源:IT阅读排行榜
本文摘编自《大模型项目实战:多领域智能应用开发》,高强文 著,机器工业出版社出版,经出版方授权发布,转载请标明文章泉源。
▼延伸阅读 ▼延伸阅读 ▼延伸阅读
《大模型项目实战:多领域智能应用开发》 《大模型项目实战:多领域智能应用开发》 《大模型项目实战:多领域智能应用开发》
高强文著 高强文 著 高强文著
从模型明白到高级应用开发真正解决实操问题 从模型明白到高级应用开发真正解决实操问题 从模型明白到高级应用开发真正解决实操问题
10 大场景案例覆盖主流开发需求 10大场景案例覆盖主流开发需求 10大场景案例覆盖主流开发需求
获取方式:https://item.jd.com/14810472.html
内容简介:
本书系统地讲解了大语言模型的实战应用过程,涵盖基础知识、常见操作和应用开发3个方面,帮助大语言模型的使用者、应用开发者循规蹈矩地掌握大模型的原理、操作以及多个场景下的应用开发技能。
目录

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |