ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

算能1684x上Qwen3-VL与WeKnora联动构建多模态RAG知识库

2026/10/7 5:36:58 拓冰建站 浏览量
算能1684x上Qwen3-VL与WeKnora联动构建多模态RAG知识库 最近在算能1684x上把Qwen3-VL和腾讯开源的RAG知识库weknora都跑起来了并且让它们两个真正联动做了一个能“看图查资料”的本地问答系统。整个过程踩了不少坑也积累了一些在国产AI芯片上落地多模态RAG的经验。这篇文章就围绕“算能1684x qwen3-vl weknora”这个组合把部署思路、关键细节、实操步骤和排查方案完整梳理一遍给正打算在边缘设备上做多模态知识库的朋友一个参考。先说下这个组合的价值点。算能1684x是国产边缘AI芯片能本地跑大模型不需要把数据送出去Qwen3-VL是多模态模型能看图、看文档、理解视频帧weknora提供知识库的解析、切分、向量检索和重排能力。三者连起来之后你的知识库就不仅仅是“文本问答”而是可以针对图片、图表、扫描件这类非结构化内容做检索和问答。适合的场景包括设备维修说明书问答、工单系统智能助手、企业内部资料库多模态检索、边缘网关上的智能客服等。文章面向的是有一定Linux和Python基础、想自己动手部署的开发者我也会把原理讲清楚新手也能跟上。1. 整体设计与思路拆解1.1 为什么选算能1684x qwen3-vl算能1684x在国产AI加速卡里属于出货量和生态都比较成熟的一款。它支持INT8量化16核ARM CPU内存带宽可观单卡能跑70B以下量级的量化模型。关键是它的工具链相对完整有libsophon运行时、tpu-mlir模型转换工具、docker开发镜像。对于不想依赖国外GPU、又有数据隐私要求的团队来说这是一个非常现实的选择。Qwen3-VL是通义千问的多模态系列除了常规文本理解它对图像的细节识别、图表分析、OCR能力都比较强。相比更重的GPT-4V或者闭源接口它最大的优势是可以本地部署配合1684x把推理留在本地。部署时通常需要把PyTorch权重转换成1684x支持的bmodel格式转换过程中要考虑量化精度损失、batch大小、序列长度等参数。我选的是Qwen3-VL-2B这个规格因为2B参数在1684x上推理延迟可控显存占用也比较友好。如果追求更高精度也可以试4B版本但需要更仔细调量化参数。1.2 weknora能解决什么问题weknora是一个开源RAG知识库框架它解决了“把文档变成可检索知识”的问题。传统搜索靠关键词匹配遇到同义词、复杂表述就容易漏检。weknora的做法是先把PDF、Word、Markdown、HTML等文档解析成纯文本切分成块然后做向量化把语义相近的内容映射到高维空间的相近位置。查询时它把用户的问题也向量化再通过相似度检索找到最相关的文档块最后把候选结果给大模型做答案生成。weknora比较吸引我的点在于它不是只做向量检索而是把解析、索引、检索、重排、生成这几个环节串成了一条完整流水线。它还有可视化管理界面可以管理多个知识库支持上传文件、测试检索效果。更重要的是它提供了Python API和类似OpenAI标准的接口这意味着可以让它统一管理知识库而把大模型推理代理给任意后端。这个特性正好是连接1684x上qwen3-vl的钥匙。1.3 架构设计部署形态与连接方式在开始动手之前我先画清楚架构。整个系统分成三层知识库服务层weknora负责文档上传、解析、分块、向量化、存储、检索。它通常部署在一台X86服务器或者云主机上数据库使用SQLite或PostgreSQL向量索引可以用内置的本地向量库也可以接外部向量数据库。模型推理服务层Qwen3-VL在算能1684x上跑通过bmodel加载到TPU对外暴露一个OpenAI兼容的HTTP接口。这个接口提供/v1/chat/completions可以接受文本和图片URL。编排层WeKnora在生成答案时会先检索知识库然后把检索到的文本块和图片相关元数据拼装成消息发给模型接口。这样用户只需要和WeKnora交互内部自动调用1684x上的模型。连接方式上我选择让WeKnora作为主入口把模型后端配置成1684x上的Qwen3-VL服务。实现的关键在于两点第一WeKnora需要支持自定义模型API地址第二当知识库中涉及图片时需要把图片的URL或Base64内容也传给模型。有些RAG框架只把图片当成附件不参与语义理解这样多模态就没有意义。我后面会详细讲如何处理图片存储和多模态调用。2. 核心细节解析与实操要点2.1 算能1684x部署qwen3-vl的关键模型转换与量化1684x不能直接运行PyTorch格式的模型必须使用tpu-mlir工具链把模型编译成bmodel。这个转换过程是整个部署中最容易出问题的环节我先梳理关键点。首先要拿到Qwen3-VL的原始权重。可以从HuggingFace下载准备好torch_model。然后需要用tpu-mlir提供的model_transform.py把PyTorch模型转换成MLIR中间表示。Qwen3-VL这类多模态模型包含视觉编码器、语言模型等多个部分在转换时要注意算子兼容性。1684x对Transformer的大部分算子支持良好但某些多模态特化算子比如图像旋转位置编码可能需要特殊处理建议先查看算能官方仓库里对Qwen系列的支持情况或者参考社区已有人转好的版本。量化方面1684x主要支持INT8和混合精度。默认情况下建议先做W8A8量化也就是权重和激活都是INT8。量化的关键是要准备校准数据集最好从真实业务数据里抽一些图文样本而不是随机文本。校准集太单一会导致量化后模型对某些图标、表格的识别能力下降。量化命令大致是model_transform.py --model_type qwen3_vl \ --model_path qwen3-vl-2b \ --input_shapes [[1,1,128,128]] \ --mlir qwen3_vl.mlir model_deploy.py --mlir qwen3_vl.mlir \ --quantize W8A8 \ --calibrate_dataset ./calib_set \ --chip bm1684x \ --output qwen3_vl_bmodel注意input_shapes这里我写了图片尺寸示例实际要按照你使用的分辨率设置。Qwen3-VL支持动态分辨率但为了在1684x上获得稳定性能我推荐固定输入尺寸比如选择[1, 3, 448, 448]。如果你需要处理大图可以使用--max_seq_len 2048来控制文本上下文长度。转换完成后可以先用sophon_router或者sail库写一个简单的推理脚本进行验证。验证时不要只测文本一定要测图像输入因为多模态模型在转换后视觉部分最容易出问题。一个常见现象是文本对话正常但一旦输入图片就输出乱码或者崩溃这多半是视觉编码器量化损失过大或者位置编码算子不兼容。2.2 weknora的知识库机制WeKnora的文档处理流程我拆解一下。它首先读取文件然后根据文件类型选择合适的解析器。对于PDF会提取文本层对于扫描图片型PDF需要本地OCR组件这点在后面的多模态场景尤其重要。解析完的内容会被切分成固定大小且带重叠的文本块默认块大小是512个token重叠32个token。这个参数直接关系到检索准确性块太大语义杂糅模型回答容易跑偏块太小上下文断裂模型缺少背景。建议根据你的文档类型调整比如技术规格书的块大小可以设成1024对话记录设成256。文本块随后输入嵌入模型生成向量。WeKnora默认支持多种嵌入模型选项比如bge系列。我建议在CPU上部署时选择bge-base-zh-v1.5它体积小中文检索效果好。向量存储方面WeKnora可以内置使用chromadb或者faiss也可以外部挂接milvus。数据量不大的情况下内置足够数据量超过几十万条再考虑外部向量库。检索的时候WeKnora支持混合检索也就是同时做向量召回和关键词精确匹配然后合并结果。这个特性很有用因为像设备型号“BM1684X”这种精确编码向量检索可能匹配到“算力芯片”之类的通用表述但关键词匹配能直接命中。合并后再经过重排序模型比如bge-reranker打分输出top-k结果。整个流程中重排是效果提升最明显的一环建议不要省略。2.3 RAG知识库能存图片吗这是最近我被人问得比较多的问题。答案是能但要看你怎么定义“存图片”。WeKnora本身不一定把图片的视觉特征做向量化它更多是把图片作为文档附件存储记录它的路径或对象ID。在纯文本RAG里图片会被忽略这显然不行。要支持图片问答需要两条路径路径一图片作为独立节点。我们把图片的元信息文件名、所属文档、页码、图片描述作为文本内容进行索引。查询“第三页的电路图说明了什么”如果能通过元信息召回这个图片节点就可以把图片发送给Qwen3-VL做视觉理解。路径二先对图片做离线识别。用Qwen3-VL提前把每张图片转成一段详细文字描述存入知识库。检索时只检索文本描述回答时引用描述内容。这种方式更稳定因为不依赖实时调用多模态模型但会丢失一些图片细节。我实际采用的是两者结合图片本身保留在本地目录WeKnora中存储一个包含图片路径和文本描述的条目。当召回结果命中图片节点时我们通过自定义回调函数读取图片并转成Base64拼接到发给模型的请求中。这样最灵活也是我认为多模态RAG目前比较合理的实现方式。2.4 连接两者API网关设计要让WeKnora和Qwen3-VL服务协同工作核心是写一个适配层。WeKnora通常通过配置接口来指定LLM服务但如果它的默认模型列表里没有Qwen3-VL我们就需要启动一个兼容服务。我采取的做法是在1684x的主机上启动一个FastAPI服务暴露OpenAI风格的/v1/chat/completions接口请求体为{ model: qwen3-vl, messages: [ {role: user, content: [ {type: image_url, image_url: {url: data:image/png;base64,....}}, {type: text, text: 请根据这张图片回答问题} ]} ] }在接口内部把OpenAI格式的消息转换成Qwen3-VL推理引擎需要的输入格式。然后把服务地址配置到WeKnora的模型配置中。这样WeKnora在生成答案时会先检索到的文本块和图片Base64合成消息再请求这个接口。需要特别处理的是图片Base64的传递。如果图片较大直接塞进JSON会导致请求体膨胀甚至触发网关超时。因此我建议在连接层增加一个文件缓存服务把图片放到本地HTTP静态目录给WeKnora返回图片URL然后Qwen3-VL服务内部再去拉取图片。这样既避免了大JSON传输又方便后续做日志审计。3. 实操过程与核心环节实现3.1 环境准备整个环境的准备涉及两台机器。第一台是算能1684x的宿主机器可以是算力服务器或者带有PCIe加速卡的边缘主机操作系统建议Ubuntu 20.04或22.04。第二台是一台普通的X86服务器用来部署WeKnora如果资源紧张也可以和1684x共用一台机器但要注意内存和磁盘占用。1684x机器上需要安装libsophon运行时和sophon-sail。我用的安装方式是wget https://sophon-file.../libsophon_0.4.9_amd64.deb sudo dpkg -i libsophon_*.deb pip install sophon-sail安装完成后用bm-smi验证驱动是否可见。如果bm-smi无法显示TPU信息多半是PCIe驱动没加载需要重启或者检查依赖。WeKnora的部署相对简单它提供Docker镜像。但为了方便二次开发我采用源码部署方式克隆仓库后创建Python虚拟环境并安装依赖git clone https://github.com/.../weknora.git cd weknora python3 -m venv venv source venv/bin/activate pip install -r requirements.txt启动前先配置.env文件设置数据库连接、向量数据库类型和模型配置。WeKnora默认有一个Web UI启动之后在浏览器里打开第一个任务是创建知识库并上传文档。3.2 部署qwen3-vl推理服务拿到bmodel模型文件后我推荐使用sophon-demo仓库里提供的Qwen示例作为基础来搭建服务。如果你的需求比较简单也可以直接用sail的Python接口写一个最小化推理流程。下面是我整理的最小代码逻辑import sophon.sail as sail import base64 import io from PIL import Image from fastapi import FastAPI from pydantic import BaseModel net sail.Engine(qwen3_vl_bmodel.bmodel, device_id0) handle sail.TpuMalloc() # 初始化TPU内存 def image_to_base64(img_path): with open(img_path, rb) as f: return base64.b64encode(f.read()).decode(utf-8) def generate_image_response(prompt, image_b64): # 将图像解码为PIL Image image_data base64.b64decode(image_b64) img Image.open(io.BytesIO(image_data)) # 完成图像预处理缩放、归一化、转换为模型输入格式 input_tensors prepare_visual_input(img) # 将文本和视觉特征输入网络得到输出token output_ids net.process([input_tensors, prompt]) return decode_tokens(output_ids)这个代码里prepare_visual_input是需要重点实现的部分主要是把图像缩放成模型要求的尺寸并做像素归一化。不同的bmodel转换方式可能要求不同的预处理参数比如是否除以255、是否需要标准化。我建议在转换模型时记录清楚预处理参数避免后续推理时踩坑。FastAPI接口封装好之后用uvicorn启动服务uvicorn qwen_server:app --host 0.0.0.0 --port 8000启动后测试一下纯文本接口和图片接口确认都能返回结果再进入下一步。3.3 部署weknora并创建知识库WeKnora启动后在Web界面里新建一个知识库取名为knowledge_qa。然后我需要准备一批测试文档。为了验证多模态能力我把一份设备维修手册的PDF以及若干张电路截图传到知识库。上传后WeKnora会自动解析并创建索引。我们用它的“测试检索”功能输入一个关于电路故障的问题看召回结果是否包含图片节点。如果不包含说明图片没有被索引需要配置图片解析插件。如果图片是以PDF里的图片形式存在可能需要让解析器额外导出图片文件。WeKnora本身不一定自动提取PDF中的图片这里我写了一个小的预处理脚本把PDF中每一页的图片剪切并保存到指定目录同时生成一个描述文本文件# 提取PDF图片的脚本 import fitz # PyMuPDF doc fitz.open(manual.pdf) for page_num in range(len(doc)): page doc[page_num] images page.get_images(fullTrue) for img_index, img in enumerate(images): xref img[0] pix fitz.Pixmap(doc, xref) if pix.n - pix.alpha 3: pix fitz.Pixmap(fitz.csRGB, pix) pix.save(fmanual_p{page_num1}_img{img_index1}.png)这样图片文件就落到了本地目录然后我把图片和描述文本一起手动上传到WeKnora。如果WeKnora支持自定义节点可以直接建一个图文关联文档在文本描述中标记图片路径。3.4 实现连接让RAG调用视觉理解连接部分是整个项目最有趣的地方。WeKnora提供了回调机制或者自定义模型接口配置可以让你在检索到结果后动态调整发送给LLM的内容。我的做法是写了一个独立的桥接服务它同时连接WeKnora的数据库和1684x上的模型服务。具体流程是用户向WeKnora提问WeKnora先做检索把候选结果返回给桥接服务。桥接服务遍历候选项如果某个节点带有image_path字段就读取该路径的图片并转为Base64。然后把所有文本内容和图片一起构造成多模态消息通过HTTP发送给1684x的qwen3-vl推理服务。拿到模型回答后再通过WeKnora的API把回答写回给用户。这个桥接服务的核心代码片段如下def build_multimodal_messages(query, retrieved_chunks): content [] content.append({type: text, text: query}) for chunk in retrieved_chunks: content.append({type: text, text: chunk[text]}) if chunk.get(image_path): b64 image_to_base64(chunk[image_path]) content.append({ type: image_url, image_url: {url: fdata:image/png;base64,{b64}} }) return [{role: user, content: content}]需要注意如果检索到的图片超过4张我建议只选择与问题最相关的前2张图片传给模型否则上下文过长、延迟飙升。排序可以用一个简单的启发式如果问题包含“图”或者“电路”等视觉词提高图片节点的权重。配置完成后我通过WeKnora的接口提交了一个测试问题“根据第3页的电路图指出电源模块的输出电压范围”。系统成功从知识库召回了第3页的电路图文本项和图片Qwen3-VL识别了图片中的电压标注返回了“12V到15V”的答案。这个结果说明整个链路是通的。4. 常见问题与排查技巧实录4.1 模型转换与推理报错转换过程中最常见的错误是算子不支持。比如某些版本的视觉编码器包含flash attention算子1684x的编译器会报不支持。遇到这类问题可以尝试以下顺序排查先用model_transform.py --debug生成算子列表查看是否有红色告警算子。尝试升级tpu-mlir到最新版本算能几乎每隔一段时间会增加新算子支持。如果某个算子始终不支持可以退而使用旧版本模型或者在转换时加入--op_split参数来拆解复杂算子。推理阶段如果出现“TPU memory exhausted”错误说明bmodel加载时需要的内存超过了卡上可用显存。此时可以减小max_seq_len或使用更小规格的模型。还可以用bm-smi查看显存占用确认是不是多进程加载导致的。4.2 检索效果差RAG瓶颈在哪很多人部署RAG后觉得回答不准确第一反应是换大模型其实大部分问题出在检索阶段。我遇到的典型案例是用户关于“卡扣断裂如何修复”的问题知识库里相关文本描述是“卡扣出现裂纹或断裂建议替换卡扣组件”。如果只用向量检索可能召回一堆不相关的内容因为“断裂”和“修复”的语义映射不够直接。此时需要做三件事一是调整分块策略把“问题描述解决方案”放在同一个块里二是开启混合检索模式让关键词匹配参与召回三是增加重排模型对候选集进行精细排序。做完这三步效果提升非常明显。另外查询改写也值得尝试WeKnora如果内置查询改写能力可以把“卡扣断裂”改写成“卡扣断裂原因 卡扣更换步骤”多路召回结果会更准。4.3 连接超时或并发不够WeKnora和1684x服务分属不同主机时网络延迟和请求体大小会影响连接稳定性。我第一次测试时图片Base64直接在JSON里传一张2MB的图转成Base64接近2.7MB导致整个请求超过10秒WeKnora默认等待时间不够报超时。解决方法有两个一是把超时参数调大比如在请求配置中设置timeout60二是改用图片URL方式让模型服务直接从本地文件系统或MinIO拉取图片大幅减小请求体积。我更推荐后者因为还能做图片缓存同一张图片不需要每次传一遍。并发方面1684x单卡同时推理多个请求时TPU会排队导致第二个请求延迟很大。我建议在推理服务外面加一层简单的信号量控制并发为1同时配合WeKnora的会话级缓存机制通过缓存命中来减少TPU压力。4.4 知识库与结构化知识的结合聊到RAG瓶颈时很多人会想到知识图谱。纯向量RAG的问题在于它无法理解实体之间的层次关系比如“A芯片是B芯片的升级版”向量检索可以在字面上关联但无法做多跳推理。如果要处理这类问题就要引入KG知识图谱。WeKnora如果未来支持知识图谱插件那么你可以把实体和关系单独存一份。比如芯片型号、参数、兼容关系构建成图谱。查询时先走图谱找相关实体再回到文档库获取详情最后让Qwen3-VL组织答案。这种ontology RAG的模式是目前RAG领域的一个重要方向特别适合工业知识库、医疗知识库等强结构化场景。在我的部署里由于数据量不大我暂时没有引入图谱而是通过在文档块中手工标注实体ID来模拟关系检索。如果后续知识库扩到几千条我会考虑引入独立的图数据库让WeKnora先做实体链接再走图查询。4.5 关于WeKnora与Dify、OIDC等扩展用了一段时间WeKnora后我试着把它和一些周边工具做了集成。WeKnora的API可以比较容易地和Dify这类低代码Agent平台对接。思路是让Dify充当智能体编排器负责意图识别和用户交互WeKnora负责知识检索1684x负责模型推理。这样用户可以拖拽式构建一套完整的客服机器人而不需要自己写前端。OIDC登录也是企业部署经常要的。WeKnora如果默认不支持OIDC可以加一层反向代理用oauth2-proxy做身份认证同时在WeKnora后面加一个内部白名单机制。我之前在测试环境用了一个轻量的方案在WeKnora前面挂NginxNginx配置auth_request指向一个OIDC验证服务验证通过再转发给WeKnora。这样不需要改WeKnora代码就能实现SSO登录。另外有朋友问能不能在Mac上搭建RAG知识库。WeKnora因为依赖项里有几个需要编译的包在Mac上安装确实会稍麻烦一些但也不是不行。主要问题是hnswlib和sqlite的版本兼容性。如果只是想快速体验建议直接使用Docker Desktop运行官方镜像省去编译的麻烦。如果用源码部署务必先安装好rust工具链和一系列构建依赖。5. 最后的实操建议整套系统跑了两个星期之后我最大的感受是硬件和软件框架的适配没那么恐怖真正的挑战在于数据预处理和接口联调。如果你也准备在1684x上做类似的项目我有几条建议供你参考。第一模型转换阶段不要追求一步到位先用小模型、小分辨率跑通全流程再逐步上大模型和高分辨率。我一开始想着直接用4B模型结果量化后视觉效果不理想排查了几天才发现是校准集问题。换回2B模型后用业务图片重新校准顺利跑通心态也稳了很多。第二把图片和文本分开管理比硬塞在一起更可控。图片路径、图片描述、文本块三者在知识库中保持引用关系这样不仅检索灵活后期做模型迭代也不用重新建库。第三接口设计时要考虑降级。如果1684x服务临时不可用WeKnora至少能返回检索到的原始文本块给用户而不是整个服务崩溃。我在桥接层加了一个异常处理当模型服务超时时会自动回复“暂时无法理解图片内容以下为相关文本资料”这样用户体验不会太差。第四多模态RAG的核心是“把正确的内容以正确的格式喂给模型”。不要指望模型有凭空理解能力知识库中每一张图片最好都配套一句简要的文字说明这样在纯文本检索阶段也能召回图片作为补充证据强化答案准确率会高很多。这套系统后续我准备继续做三件事一是接入更完善的KG知识图谱提升多跳推理能力二是优化性能尝试把WeKnora的向量化模型和重排模型也部署到1684x上彻底摆脱CPU性能瓶颈三是探索将WeKnora的检索日志和Qwen3-VL的推理日志合并做反馈评估持续优化检索策略。希望这篇分享能帮你少走一些弯路如果你也在折腾类似方案欢迎交流实践中遇到的具体问题。