Qwen3-4B-Thinking Chainlit前端二次开发:添加文件上传与PDF解析功能
1. 项目背景与目标
Qwen3-4B-Thinking-2507-Gemini-2.5-Flash-Distill是一个基于vLLM部署的文本生成模型,该模型在约5440万个由Gemini 2.5 Flash生成的token上进行了训练,旨在提炼Gemini-2.5 Flash的行为模式、推理轨迹和输出风格。模型覆盖多个专业领域,包括学术、金融、健康、法律等。
Chainlit是一个轻量级的Python框架,用于快速构建AI应用的前端界面。本文将指导您如何在现有Chainlit前端基础上,添加文件上传与PDF解析功能,使模型能够直接处理PDF文档内容。
2. 环境准备与基础验证
2.1 确认模型服务状态
在开始前端开发前,首先需要确认模型服务已正常启动:
cat /root/workspace/llm.log如果看到类似以下输出,表示模型已成功加载:
Loading model weights... Model loaded successfully in 120.5s Ready for inference2.2 基础Chainlit功能验证
启动Chainlit前端进行基础功能测试:
import chainlit as cl @cl.on_message async def main(message: str): # 这里添加模型调用逻辑 response = "这是模型的测试回复" await cl.Message(content=response).send()运行命令启动服务:
chainlit run app.py -w访问本地端口(默认8000)应能看到交互界面,输入问题后能获得模型回复。
3. 文件上传功能实现
3.1 添加上传组件
修改Chainlit前端代码,添加文件上传支持:
from typing import Optional import chainlit as cl @cl.on_message async def handle_message(message: str): # 检查是否有文件上传 if cl.user_session.get("uploaded_file"): file_content = cl.user_session.get("uploaded_file") await cl.Message(content=f"已收到文件,内容长度:{len(file_content)}字节").send() else: await cl.Message(content="请先上传文件").send() @cl.on_file_upload(accept=["application/pdf"]) async def upload_file(files: Optional[list[cl.UploadedFile]]): if files: uploaded_file = files[0] content = await uploaded_file.read() cl.user_session.set("uploaded_file", content) await cl.Message(content=f"文件 {uploaded_file.name} 上传成功").send()3.2 前端界面优化
在Chainlit中自定义上传按钮样式:
@cl.on_chat_start async def start(): await cl.Message( content="欢迎使用Qwen3-4B模型交互系统", actions=[ cl.Action(name="upload", value="upload", label="📁 上传PDF文件") ] ).send()4. PDF解析功能集成
4.1 安装PDF处理库
首先安装必要的PDF解析库:
pip install pypdf2 pdfminer.six4.2 实现PDF文本提取
添加PDF解析功能到消息处理逻辑:
from PyPDF2 import PdfReader from io import BytesIO async def extract_text_from_pdf(pdf_bytes): text = "" try: pdf_file = BytesIO(pdf_bytes) reader = PdfReader(pdf_file) for page in reader.pages: text += page.extract_text() + "\n" return text except Exception as e: return f"PDF解析失败: {str(e)}" @cl.on_message async def handle_message(message: str): if cl.user_session.get("uploaded_file"): pdf_content = cl.user_session.get("uploaded_file") extracted_text = await extract_text_from_pdf(pdf_content) # 将提取的文本发送给模型处理 model_response = "这里是模型对PDF内容的分析结果" await cl.Message(content=f"提取的文本内容:\n{extracted_text[:500]}...").send() await cl.Message(content=model_response).send()4.3 处理大文件优化
对于大PDF文件,添加分页处理逻辑:
async def process_large_pdf(pdf_bytes, max_pages=10): pdf_file = BytesIO(pdf_bytes) reader = PdfReader(pdf_file) total_pages = len(reader.pages) for i in range(min(max_pages, total_pages)): page_text = reader.pages[i].extract_text() # 发送每页内容给模型处理 await cl.Message(content=f"第{i+1}页内容:\n{page_text[:300]}...").send() if total_pages > max_pages: await cl.Message(content=f"已处理前{max_pages}页,共{total_pages}页").send()5. 完整功能集成与测试
5.1 完整代码示例
整合所有功能的完整示例:
import chainlit as cl from PyPDF2 import PdfReader from io import BytesIO from typing import Optional async def extract_text_from_pdf(pdf_bytes): text = "" try: pdf_file = BytesIO(pdf_bytes) reader = PdfReader(pdf_file) for page in reader.pages: text += page.extract_text() + "\n" return text except Exception as e: return f"PDF解析失败: {str(e)}" @cl.on_chat_start async def start(): await cl.Message( content="Qwen3-4B模型交互系统已启动,请上传PDF文件或直接输入问题", actions=[ cl.Action(name="upload", value="upload", label="📁 上传PDF") ] ).send() @cl.on_file_upload(accept=["application/pdf"]) async def upload_file(files: Optional[list[cl.UploadedFile]]): if files: uploaded_file = files[0] content = await uploaded_file.read() cl.user_session.set("uploaded_file", content) await cl.Message(content=f"文件 {uploaded_file.name} 上传成功").send() @cl.on_message async def handle_message(message: str): if cl.user_session.get("uploaded_file"): pdf_content = cl.user_session.get("uploaded_file") extracted_text = await extract_text_from_pdf(pdf_content) # 这里添加实际模型调用 model_response = f"模型分析结果:\n基于PDF内容,这里是Qwen3-4B模型的详细分析..." await cl.Message(content=f"提取的文本内容:\n{extracted_text[:500]}...").send() await cl.Message(content=model_response).send() cl.user_session.delete("uploaded_file") # 清除已处理的文件 else: # 处理普通文本输入 model_response = "这里是模型对您问题的回答..." await cl.Message(content=model_response).send()5.2 测试流程
启动服务:
chainlit run app.py -w测试文件上传功能:
- 点击上传按钮选择PDF文件
- 确认系统正确接收并解析文件
- 检查提取的文本内容是否准确
测试模型交互:
- 直接输入问题验证基础功能
- 上传PDF后检查模型是否能正确处理提取的文本
6. 总结与进阶建议
通过本文的指导,我们成功在Qwen3-4B-Thinking模型的Chainlit前端中添加了文件上传与PDF解析功能。这一改进使系统能够直接处理PDF文档,大大扩展了模型的应用场景。
进阶改进建议:
性能优化:
- 对大PDF文件实现后台异步处理
- 添加处理进度指示器
功能扩展:
- 支持更多文件格式(Word、Excel等)
- 添加文件内容摘要功能
用户体验:
- 实现多文件批量上传
- 添加文件预览功能
错误处理:
- 增强对损坏PDF文件的容错能力
- 添加文件大小限制提示
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。