ERNIE-4.5-0.3B-PT实战:vllm环境部署+chainlit前端调用全流程解析
ERNIE-4.5-0.3B-PT实战vllm环境部署chainlit前端调用全流程解析想快速搭建一个属于自己的AI聊天助手吗今天我就带你从零开始把百度最新的轻量级大模型ERNIE-4.5-0.3B-PT跑起来再给它配上一个漂亮的聊天界面。整个过程就像拼乐高一样简单不需要你懂复杂的深度学习框架跟着我的步骤30分钟就能搞定一个能对话的AI应用。1. 准备工作认识我们的“工具箱”在动手之前我们先花几分钟了解一下要用到的几个核心组件。这样你就能明白每一步在做什么而不是机械地复制命令。1.1 主角ERNIE-4.5-0.3B-PT模型ERNIE-4.5-0.3B-PT是百度推出的一个“小而美”的语言模型。别看它只有3亿参数0.3B就是3亿的意思在中文理解和生成任务上表现相当不错。这个模型有几个特点很适合我们这样的个人开发者对硬件要求低普通显卡甚至一些集成显卡就能跑起来不需要昂贵的专业卡中文表现好专门针对中文进行了优化回答更符合我们的语言习惯部署简单支持多种部署方式我们今天用的vllm就是其中最简单的一种1.2 加速器vllm推理引擎vllm你可以理解为一个“模型加速器”。传统的模型推理方式比较慢而且同时只能处理一个请求。vllm通过智能的内存管理和请求调度能让模型推理速度提升好几倍还能支持多人同时使用。用vllm的好处很明显速度快采用先进的内存管理技术减少不必要的计算省内存高效利用显存同样的硬件能跑更大的模型简单好用基本上就是一行命令的事情1.3 颜值担当chainlit前端界面chainlit是一个专门为AI应用设计的Web框架。它最大的优点就是“开箱即用”——你不需要写复杂的HTML、CSS、JavaScript几行Python代码就能得到一个漂亮的聊天界面效果跟ChatGPT的界面差不多。chainlit提供了这些实用的功能对话历史自动保存聊天记录流式输出回答一个字一个字显示有打字机效果文件上传可以直接上传文档让AI处理主题定制可以调整颜色、布局等2. 第一步检查环境与启动模型服务现在开始实际操作。如果你用的是预置好的镜像环境模型服务可能已经在后台运行了。我们先确认一下。2.1 检查模型服务状态打开终端输入下面这个命令查看服务日志cat /root/workspace/llm.log如果看到类似下面的输出特别是最后一行显示“LLM engine is ready”那就说明模型服务已经成功启动了INFO 07-10 14:30:25 llm_engine.py:73] Initializing an LLM engine with config: model/root/.cache/modelscope/hub/baidu/ERNIE-4.5-0.3B-PT... INFO 07-10 14:30:28 llm_engine.py:158] # GPU blocks: 512, # CPU blocks: 512 INFO 07-10 14:30:28 model_runner.py:84] Loading model weights took 3.2 GB INFO 07-10 14:30:29 llm_engine.py:291] LLM engine is ready2.2 手动启动服务如果需要如果服务没有启动或者你想自己手动启动一次可以用这个命令python -m vllm.entrypoints.openai.api_server \ --model baidu/ERNIE-4.5-0.3B-PT \ --served-model-name ernie-4.5 \ --port 8000 \ --max-model-len 4096我来解释一下这几个参数的意思--model baidu/ERNIE-4.5-0.3B-PT指定要加载的模型--served-model-name ernie-4.5给服务起个名字后面调用时会用到--port 8000服务运行在8000端口--max-model-len 4096模型最多能处理4096个token大约2000-3000个汉字2.3 测试服务是否正常服务启动后我们简单测试一下。打开另一个终端窗口输入curl http://localhost:8000/v1/models如果返回类似下面的JSON数据说明一切正常{ object: list, data: [ { id: ernie-4.5, object: model, created: 1688980000, owned_by: vllm } ] }3. 第二步创建chainlit聊天界面模型服务跑起来了现在我们需要一个界面来跟它对话。chainlit让这件事变得特别简单。3.1 创建主程序文件新建一个Python文件名字随便起比如叫chat_app.py然后写入下面的代码import chainlit as cl import requests import json # vllm服务的地址就是刚才启动的那个 VLLM_API_URL http://localhost:8000/v1/chat/completions cl.on_chat_start async def start_chat(): 每次开始新聊天时执行 # 发送欢迎消息 welcome_msg cl.Message( content 你好我是基于ERNIE-4.5模型的AI助手有什么问题尽管问我吧 ) await welcome_msg.send() cl.on_message async def handle_message(message: cl.Message): 处理用户发来的每一条消息 # 先显示一个“正在思考”的提示 response_msg cl.Message(content) await response_msg.send() try: # 准备要发送给模型的数据 request_data { model: ernie-4.5, # 模型名字要跟启动时的一致 messages: [ {role: user, content: message.content} ], temperature: 0.7, # 控制回答的随机性0-1之间 max_tokens: 1024, # 回答的最大长度 stream: True # 启用流式输出有打字机效果 } # 发送请求到vllm服务 response requests.post( VLLM_API_URL, jsonrequest_data, streamTrue, # 重要要设置streamTrue headers{Content-Type: application/json} ) # 处理模型返回的数据流式 full_answer for line in response.iter_lines(): if line: # 跳过空行 line_text line.decode(utf-8) # chainlit期望的数据格式是 data: {...} if line_text.startswith(data: ): data_part line_text[6:] # 去掉前面的data: if data_part ! [DONE]: # 不是结束标记 try: # 解析JSON数据 chunk json.loads(data_part) # 提取回答内容 if choices in chunk and chunk[choices]: delta chunk[choices][0].get(delta, {}) if content in delta: word delta[content] full_answer word # 一个字一个字地显示 await response_msg.stream_token(word) except: # 如果解析出错跳过这一行 continue # 确保最终消息完整 if full_answer: response_msg.content full_answer await response_msg.update() else: # 如果什么都没收到给个提示 await cl.Message(content 好像没有收到回答请再试一次。).send() except requests.exceptions.ConnectionError: # 连接错误vllm服务可能没启动 await cl.Message( content❌ 连接失败请检查vllm服务是否已经启动。 ).send() except Exception as e: # 其他错误 await cl.Message( contentf⚠️ 出错了{str(e)} ).send() # 程序入口 if __name__ __main__: cl.run()这段代码做了几件重要的事情创建聊天应用定义了两个关键函数一个处理聊天开始一个处理每条消息连接vllm服务把用户的提问发送给模型再把模型的回答显示出来实现流式输出让回答一个字一个字显示体验更好错误处理如果出错了会给用户友好的提示3.2 添加一些美化配置可选为了让界面更好看、更好用我们可以加一些配置文件。首先创建一个chainlit.md文件这是应用的介绍页面# ERNIE-4.5聊天助手 欢迎使用基于ERNIE-4.5-0.3B-PT模型的智能对话应用 ## ✨ 功能特色 - **中文对话**专门优化中文理解和生成 - **流式响应**回答逐步显示有打字机效果 - **对话历史**自动保存聊天记录 - **简洁界面**现代设计操作简单 ## 使用提示 1. 直接在下方输入框提问 2. 模型会逐步显示回答内容 3. 可以连续对话模型会记住上下文 4. 如果回答不满意可以换个方式提问 ## ⚙️ 技术栈 - 后端vllm ERNIE-4.5-0.3B-PT - 前端chainlit - 部署一键启动无需复杂配置 开始你的对话吧再创建一个config.toml文件来定制界面样式[UI] name ERNIE-4.5聊天助手 description 基于百度ERNIE-4.5模型的智能对话应用 show_readme_as_default true # 默认显示上面的介绍页面 [Features] show_chain_of_thought false # 不显示思考过程 show_source_documents false # 不显示来源文档 [Theme] primaryColor #1890ff # 主色调蓝色 backgroundColor #f5f5f5 # 背景色浅灰色 textColor #333333 # 文字颜色深灰色 [ChatSettings] show_watermark false # 不显示水印 hide_cot true # 隐藏思考过程4. 第三步启动并使用完整系统所有代码都写好了现在让我们启动整个系统看看效果如何。4.1 启动chainlit应用打开终端进入你存放chat_app.py文件的目录然后运行chainlit run chat_app.py你会看到类似下面的输出Chainlit app is running at: Local URL: http://localhost:8000 Public URL: None (add --host 0.0.0.0 to expose) Press CTRLC to quit这说明应用已经成功启动了访问 http://localhost:8000 就能看到界面。4.2 界面功能概览打开浏览器访问那个地址你会看到一个很漂亮的聊天界面左侧边栏显示所有的对话历史点击可以切换中间区域主聊天窗口显示对话内容底部输入框在这里输入问题按回车或点击发送按钮设置按钮右上角可以调整一些显示选项4.3 开始第一次对话现在可以开始测试了我建议从简单的问题开始测试1基础问答你你好介绍一下你自己 AI你好我是基于ERNIE-4.5-0.3B-PT模型的AI助手...测试2知识查询你中国的首都是哪里 AI中国的首都是北京...测试3创意任务你写一个关于程序员和咖啡的冷笑话 AI为什么程序员喜欢喝咖啡因为Java...测试4代码帮助你用Python写一个Hello World程序 AIprint(Hello, World!)你会看到模型的回答是一个字一个字显示出来的就像有人在打字一样这就是流式输出的效果。4.4 调整回答风格如果你觉得模型的回答太啰嗦或者不够有创意可以调整生成参数。找到chat_app.py中的这部分代码request_data { model: ernie-4.5, messages: [ {role: user, content: message.content} ], temperature: 0.7, # 控制创造性 max_tokens: 1024, # 最大长度 top_p: 0.9, # 多样性控制 stream: True }各个参数的作用temperature温度0-1之间值越小回答越确定和保守值越大越有创意和随机。一般设置0.1-0.3用于事实问答回答准确但可能单调0.5-0.7平衡模式适合大多数对话0.8-1.0创意模式适合写故事、诗歌等max_tokens最大token数限制回答的长度。一个中文汉字大约是1-2个token。设置太小可能回答不完整太大可能浪费资源。top_p核采样0-1之间控制词汇选择范围。通常0.8-0.95效果较好。5. 常见问题与解决方法在实际使用中你可能会遇到一些问题。这里我整理了几个常见的情况和解决办法。5.1 服务启动失败问题运行chainlit run chat_app.py时提示连接失败。可能原因和解决vllm服务没启动先确认vllm服务是否在运行# 查看vllm进程 ps aux | grep vllm # 或者检查8000端口 netstat -tlnp | grep :8000如果没有运行重新启动vllm服务。端口被占用8000端口可能被其他程序用了# 查看哪个程序占用了8000端口 lsof -i :8000 # 如果被占用可以换个端口 # 修改chat_app.py中的地址 VLLM_API_URL http://localhost:8001/v1/chat/completions模型加载失败可能是模型文件有问题# 查看详细的错误日志 tail -f /root/workspace/llm.log5.2 回答速度慢问题模型生成回答需要很长时间。优化建议调整生成参数减少max_tokens比如从1024降到512request_data { max_tokens: 512, # 减少最大长度 # ... 其他参数 }检查硬件使用看看是不是硬件资源不够了# 查看GPU使用情况如果有GPU nvidia-smi # 查看内存使用 free -h # 查看CPU使用 top简化问题如果问题很复杂模型需要更多时间思考。可以尝试把大问题拆成小问题先问简单的问题再问复杂的给模型一些上下文提示5.3 回答质量不理想问题模型的回答不符合预期或者答非所问。改进方法优化提问方式模型对提问方式很敏感不好的提问“写代码”好的提问“用Python写一个函数输入两个数字返回它们的和”提供更多上下文在复杂问题上先给一些背景messages [ {role: system, content: 你是一个专业的Python程序员回答要简洁准确。}, {role: user, content: 如何用Python读取CSV文件} ]调整温度参数如果回答太随机降低temperature如果太死板提高temperature尝试不同的模型如果ERNIE-4.5-0.3B-PT不适合你的任务可以试试其他模型5.4 内存或显存不足问题运行一段时间后出现内存错误。解决方案限制并发用户数在chainlit配置中限制同时使用的人数# 在config.toml中添加 [Advanced] max_concurrent_users 3 # 最多3个用户同时使用定期重启服务设置定时任务每天重启一次释放内存# 创建一个重启脚本 restart.sh #!/bin/bash pkill -f vllm sleep 5 python -m vllm.entrypoints.openai.api_server ... # 设置每天凌晨3点重启 0 3 * * * /path/to/restart.sh监控资源使用安装监控工具及时发现问题# 安装htop更好的top apt-get install htop # 实时查看资源使用 htop6. 进阶功能让聊天助手更智能基本的聊天功能已经实现了如果你想让助手更强大可以试试下面这些进阶功能。6.1 添加对话记忆默认情况下每次对话都是独立的模型不记得之前说过什么。我们可以添加对话历史功能cl.on_chat_start async def start_chat(): 聊天开始时初始化一个空的历史记录 # 每个用户有自己的对话历史 cl.user_session.set(message_history, []) cl.on_message async def handle_message(message: cl.Message): 处理消息包含历史记录 # 获取当前用户的对话历史 history cl.user_session.get(message_history, []) # 添加用户的新消息 history.append({role: user, content: message.content}) # 限制历史记录长度避免太长 # 保留最近5轮对话10条消息5问5答 if len(history) 10: history history[-10:] # 准备请求数据包含整个历史 request_data { model: ernie-4.5, messages: history, # 这里传整个历史不只是当前问题 temperature: 0.7, max_tokens: 1024, stream: True } # ... 发送请求和处理响应 ... # 把模型的回答也加到历史中 history.append({role: assistant, content: full_answer}) # 保存更新后的历史 cl.user_session.set(message_history, history)这样模型就能记住之前的对话实现真正的多轮对话。6.2 支持文件上传和分析chainlit原生支持文件上传我们可以让AI分析上传的文档cl.on_message async def handle_message(message: cl.Message): 处理消息支持文件上传 enhanced_prompt message.content # 检查是否有上传的文件 if message.elements: for element in message.elements: if element.type file: # 显示文件信息 await cl.Message( contentf 收到文件{element.name} ({element.size/1024:.1f} KB) ).send() try: # 读取文本文件 if element.name.endswith(.txt): with open(element.path, r, encodingutf-8) as f: file_content f.read() # 把文件内容加到提示中 enhanced_prompt f请根据以下文件内容回答问题 文件内容 {file_content[:2000]} # 只取前2000字避免太长 问题{message.content} # 可以添加更多文件类型支持 # elif element.name.endswith(.pdf): # # 处理PDF文件 # pass except Exception as e: await cl.Message( contentf❌ 读取文件时出错{str(e)} ).send() return # 使用增强后的提示调用模型 # ... 原有的模型调用代码但使用enhanced_prompt而不是message.content ...6.3 添加自定义工具函数你可以为AI助手添加一些实用的小工具import math from datetime import datetime import requests def calculate_math(expression): 简单的数学计算 try: # 安全地计算数学表达式 allowed_names { sqrt: math.sqrt, sin: math.sin, cos: math.cos, tan: math.tan, pi: math.pi, e: math.e } # 安全检查 for char in expression: if char not in 0123456789-*/(). sqrtcossintanpie: return ❌ 表达式包含不安全字符 result eval(expression, {__builtins__: {}}, allowed_names) return f 计算结果{result} except Exception as e: return f❌ 计算错误{str(e)} def get_current_time(): 获取当前时间 now datetime.now() return f 当前时间{now.strftime(%Y年%m月%d日 %H:%M:%S)} def get_weather(city北京): 获取天气信息示例 # 这里只是一个示例实际需要调用天气API return f️ {city}的天气晴25°C适合外出 cl.on_message async def handle_message(message: cl.Message): 处理消息支持特殊命令 content message.content.lower().strip() # 检查是否是特殊命令 if content.startswith(计算): # 提取计算表达式 expression content[2:].strip() result calculate_math(expression) await cl.Message(contentresult).send() return elif content in [时间, 现在几点, 当前时间]: result get_current_time() await cl.Message(contentresult).send() return elif content.startswith(天气): # 提取城市名 city content[2:].strip() or 北京 result get_weather(city) await cl.Message(contentresult).send() return elif content 帮助: help_text 可用命令 • 计算 [表达式] - 数学计算如计算 35*2 • 时间 - 显示当前时间 • 天气 [城市] - 查看天气如天气 上海 • 其他问题直接提问即可 await cl.Message(contenthelp_text).send() return # 如果不是特殊命令走正常的模型推理 # ... 原有的模型调用代码 ...6.4 部署到公网让朋友使用如果你想让朋友也能用你的AI助手可以部署到公网方法1使用ngrok最简单# 安装ngrok # 访问 https://ngrok.com/ 注册并获取token # 启动隧道假设chainlit运行在8000端口 ngrok http 8000ngrok会给你一个公网地址比如https://abc123.ngrok.io把这个地址发给朋友就能访问了。方法2修改chainlit绑定地址# 让chainlit监听所有网络接口 chainlit run chat_app.py --host 0.0.0.0 --port 8000然后你需要知道你的公网IP地址在路由器上设置端口转发8000端口朋友通过http://你的公网IP:8000访问方法3添加简单密码保护# 在chat_app.py中添加 cl.password_auth_callback def auth_callback(username: str, password: str): 简单的密码验证 # 这里可以改成从数据库或配置文件读取 if username admin and password your_password_here: return cl.User(identifieradmin) return None # 然后在config.toml中启用认证 [Auth] enabled true7. 总结与下一步建议通过这个教程我们完成了一个完整的AI聊天助手搭建。让我们回顾一下关键步骤7.1 关键步骤回顾模型服务部署用vllm一键启动ERNIE-4.5-0.3B-PT模型服务前端界面开发用chainlit快速搭建美观的聊天界面前后端连接通过API把用户的问题传给模型再把回答显示出来功能扩展添加对话记忆、文件上传、自定义工具等实用功能7.2 这个方案的优势部署简单几乎不需要手动配置适合快速验证想法性能不错vllm提供了高效的推理能力响应速度快体验良好chainlit的界面现代美观用户体验好易于扩展Python代码结构清晰添加新功能很方便资源友好3亿参数的模型对硬件要求不高普通电脑就能跑7.3 可以尝试的改进方向如果你已经掌握了基本用法可以尝试这些进阶玩法尝试其他模型除了ERNIE还可以试试其他开源模型添加知识库让AI能够回答特定领域的问题集成到其他应用把聊天助手嵌入到网站或APP中优化性能添加缓存、批量处理等优化添加语音功能结合语音识别和合成实现语音对话7.4 给初学者的建议如果你是第一次接触AI应用开发我建议先跑通不要一开始就追求完美先让整个流程跑起来小步迭代每次只添加一个小功能测试没问题再加下一个多测试用各种问题测试模型了解它的能力和局限参考文档遇到问题先查vllm和chainlit的官方文档加入社区在技术社区提问和分享能学到很多最重要的是动手实践。技术的学习就像学游泳看再多的教程也不如下水试一次。希望这个教程能帮你迈出第一步开启你的AI应用开发之旅。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。