☰
算能1684X部署qwen3-vl与weknora,实现多模态RAG知识库
2026/10/7 12:47:30 网站建设 项目流程

如果你的知识库里躺着几百张产品图纸、合同扫描件、带截图的故障单,而RAG只能搜出文字却"看不懂"图里的内容,你大概率会想:能不能让知识库自己"看图说话"?我最近就在折腾一条这样的链路——算能1684X上把qwen3-vl跑起来,边上再部署腾讯开源的知识库weknora,最后把两者接成一条"能看图的多模态RAG"流水线。这篇文章把我从环境准备、模型转换、服务封装到知识库对接的完整过程都记录下来,包括中间踩过的一些坑和取舍,给打算在国产算力上做视觉RAG的同学一个可参考的落地路线。

1. 为什么是这个组合:多模态问答、国产算力与知识库的结构化升级

任何部署项目,先想清楚"为什么这么搭"远比"怎么搭"重要。我不想一上来就贴命令,先说清楚这套架构解决的问题,这样后续每一步你都知道自己在干什么。

1.1 三样东西各管哪一段

算能1684X(BM1684X)是一颗国产AI加速卡,它的定位是边缘端和推理服务器场景,INT8算力大概是32 TOPS级别,性价比在那摆着,很多不想把数据送出本地的团队拿它做私有化推理。qwen3-vl是阿里的多模态大模型,能同时理解文本和图像内容,回答"图里有什么""这个截图说明了什么"这类问题。weknora是腾讯开源的RAG知识库框架,但它不是普普通通的"文档切块+向量召回"玩具,而是把"本体(Ontology)+知识图谱(KG)+向量检索"揉在一起的混合RAG方案。

三者的关系打个比方:1684X是发动机,qwen3-vl是能看懂路况的司机,weknora是这辆车的导航和数据仓库。没有司机,发动机空转;没有知识库,司机只能凭常识瞎答;没有本地算力,数据全得送到云端。

1.2 RAG的常见瓶颈:纯向量检索为什么不够用

网络热搜里"rag瓶颈"这个词反复出现,说明很多人都撞上了同一堵墙。传统RAG的流程是:文档切块→embedding转向量→相似度检索→拼Prompt→让LLM回答。这套做法的问题有三个:

  • 语义近似不等于逻辑正确。向量检索能找到"长得像"的内容,但找不出"A导致B,B依赖C"这样的因果链。
  • 跨文档聚合能力弱。一个问题涉及到三份文档里的五个实体,纯向量检索往往只能召回其中的一两段。
  • 可解释性差。就算答对了,你也说不出这个结论依据了哪条知识路径。

所以RAG领域这两年明显往"结构化"走。热搜里同时出现"kg知识库""rag知识库和结构知识库区分以及应用场景""ontology rag"这些词,本质上是同一件事:大家开始接受,光有非结构化文本的向量是不够的,还得把实体、关系、属性这些"结构知识"建出来,形成知识图谱,让问答能沿着图谱做多跳推理。weknora就是按这个思路做的——它先抽取文档里的人物、事件、指标、组织等实体和它们之间的关系,构建出知识图谱层,再配合文本向量做混合检索。

1.3 这一步的独特价值:RAG知识库能不能存图片

热搜里有个很具体的问题:"rag知识库能存储图片嘛"。常规答案是:可以存,但存了也没用,因为大多数RAG链路里的embedding模型和LLM都是纯文本的,图片在被切块时要么被丢弃,要么只保留图里的OCR文字,图片本身的视觉信息全丢了。

这套组合的差异化价值就在这里。weknora管理文档和知识结构,1684X上的qwen3-vl补充视觉理解能力。文档里的截图、图纸、表格扫描件,先通过视觉模型识别内容,再进入知识图谱和向量库;问答阶段遇到图片类内容,直接把图扔给qwen3-vl做多模态推理。这样知识库才算真正"存了图片且能用图片"。

2. 算能1684X部署前的基础设施:从驱动到模型转换的关键工序

确定组合之后,先把1684X的环境搞踏实。这一步跳过任何细节,后面全得返工。我按自己实际操作的顺序来讲。

2.1 硬件形态与SDK组件

1684X在部署形态上主要分两种:SoC盒子(比如SE5/SE8系列)和PCIe加速卡(SC5系列)。我在项目里用的是PCIe卡插在x86服务器上,理由很简单——weknora的中间件生态(图数据库、向量库、Web服务)都是标准x86环境,PCIe卡让AI算力和业务服务跑在同一台机器上,通讯走PCIe带宽,没有网络往返的开销。

装完物理卡,第一步先确认系统认到了设备:

lspci | grep -i sophon ls /dev/bm* # 应该能看到 /dev/bm-sochip 这类设备节点 bm-smi # 算能卡的状态监控命令,类似 nvidia-smi

如果bm-smi能列出设备温度、利用率、显存占用,驱动就绪。接下来是SDK包,主要装三样:libsophon(运行时库,包含bmrt、bmcv、bmvideo等)、sophon-opencv(算能优化的图像处理库)、sophon-mw(媒体SDK,处理视频流才需要,我这套不涉及视频可以先不装)。libsophon我用的是deb包直接装,装完记得确认/opt/sophon/libsophon-current下有没有include和lib目录,后面编译C++推理代码要用;如果走Python的sail接口,则在/opt/sophon/sail-<版本>-py3-none-linux_x86_64.whl路径下能找到安装包。

2.2 qwen3-vl模型转换链路:PyTorch到bmodel

1684X不能直接跑PyTorch的pt权重,它的推理引擎认的是自家bmodel格式。这一步是整条链路里最容易被卡住的环节,我先讲主干流程再讲坑。

标准工具链是TPU-MLIR,算能官方提供tpuc_dev容器,工作都在容器里做:

docker run -v $(pwd):/workspace -it sophgo/tpuc_dev:latest bash

流程分两段:先把PyTorch模型转成ONNX,再由ONNX转成bmodel。qwen3-vl这种多模态模型有视觉编码器(ViT部分)和语言模型两部分,转换时我倾向于把视觉部分和文本部分分别导出,后面单独转、单独量化和单独部署。这样做的好处是:如果视觉模块里遇到TPU不支持的算子,只需要单独处理视觉部分,不影响整个语言模型跑起来。

简化后的转换命令大致长这样:

# 先完成 PyTorch -> ONNX 导出,代码里确认输入输出命名 python export_qwen3vl_onnx.py \ --model_name qwen3-vl-4b \ --output_dir ./onnx_out # TPU-MLIR 容器内:ONNX -> MLIR 中间表示 model_transform.py \ --model_name qwen3_vl_4b \ --model_path ./onnx_out/model.onnx \ --input_shapes "[[1,3,448,448],[1,128]]" \ --mlir qwen3_vl_4b.mlir # MLIR -> INT8量化后的bmodel model_deploy.py \ --mlir qwen3_vl_4b.mlir \ --quantize INT8 \ --chip bm1684x \ --model qwen3_vl_4b.bmodel

这里的--input_shapes要严格对应用实际输入尺寸和最大序列长度,我是按448x448的图像输入和128的初始token长度(后面可动态延长)来定的。INT8量化这步要准备校准数据集,直接用几十条真实知识库里的图文数据做calibration比随便找通用数据集靠谱得多,量化后的精度损失更小。

2.3 多模态模型的算子兼容坑与备选路线

这一步我要重点说一个现实:qwen3-vl是较新的模型架构,1684X配套工具链的算子库未必第一时间全部支持,尤其是视觉模块里的某些attention变体、RoPE位置编码实现,在TPU上可能编译失败或精度掉得厉害。我实测中的经验是:先跑一次编译看日志,model_deploy.py会在终端明确告诉你哪个算子不支持,不要硬扛,绕过去。

我的备选路线是:视觉部分降级。不强行把完整的qwen3-vl一次转完,而是让1684X只跑语言模型部分做指令理解,图片的视觉特征用SigLIP或CLIP这类对TPU兼容性更好的视觉编码器提前抽好,图片转成特征向量后一起拼进Prompt。效果上损失一点端到端一致性,但工程上能快速跑通。后面第5节讲的连接方案里,我是以"qwen3-vl完整bmodel成功转换"为前提的,如果你的算子支持有问题,先按这个降级方案顶上,架构骨架完全不用改。

3. 在1684X上把qwen3-vl跑成服务

模型文件有了,就差让它变成能被外部调用的服务。这里说的"调用"不是命令行里问一句答一句,而是要提供HTTP接口,让weknora能按OpenAI的API规范来请求它。

3.1 推理引擎选型:sail接口还是底层bmrt

算能的Python接口里,sail是封装得比较完整的,能直接加载bmodel、管理输入输出Tensor、申请设备内存。另一个是C++的bmrt接口,性能最直接但要处理更多内存细节。我的选择是:服务主体用Python的sail快速实现,因为weknora对接时用的是HTTP层,瓶颈在网络和消息解析,不在Python这几毫秒的调度开销上。

sail加载bmodel并推理的核心代码逻辑大概是:

import sophon.sail as sail engine = sail.Engine("./qwen3_vl_4b.bmodel", 0) # 0号设备 graph_name = engine.get_graph_names()[0] input_names = engine.get_input_names(graph_name) output_names = engine.get_output_names(graph_name) # 按需填充 input_tensors,调用 process 接口 output_tensors = engine.process(graph_name, input_tensors)

这里有几个细节值得注意:一是输入Tensor要严格按模型转换时的layout来填,视觉模型的图像不仅要resize到448x448,还要做归一化,归一化的均值和标准差不同模型不一样,错了图像理解效果会非常差。二是多 batch 的问题,1684X的推理性能适合小batch并发,我封装的时候开了batch=4的内部缓冲,多个请求攒到4个再一起推理,吞吐比单请求逐条推理高一截。

3.2 封装OpenAI兼容的/chat/completions接口

weknora这类上层应用一般不会为每家推理后端定制客户端,大家都默认你提供一个OpenAI风格的推理服务。所以我在1684X这台机器上用FastAPI写了个几百行的适配层,暴露/v1/chat/completions和/v1/models两个端点。

  • /v1/models返回当前可用的模型名,比如qwen3-vl-4b,让weknora在模型列表里能自动发现。
  • /v1/chat/completions接收OpenAI格式的请求体,把messages里文本内容和image_url形式的图片取出来,组装成qwen3-vl的输入,推理完成后按OpenAI的响应格式返回。

请求体里的图片有两种处理方式:如果是url,服务端直接下载;如果是base64,解码后转成数组。我的建议是走base64,内网传输不受外网波动影响,而且weknora这种知识库里可能存的是私有文档,走url还得处理访问权限。

响应里的content字段直接回传模型的文本输出,usage里的token数我从sail的返回里解析不出来,就直接估一个数填进去,不影响主流程。反正weknora只关心content,usage是日志参考。

3.3 并发、显存与服务稳定性

1684X的板载内存是有限的,qwen3-vl的KV cache占得不少。跑起来之后我第一件事就是观察bm-smi里的显存占用,确认单实例KV cache上限设在哪不会OOM。我用的是固定长度的KV cache池,最大生成长度限制在2048个token,对知识库问答来说基本够用。

另一个经验是把推理服务丢到systemd守护,开机会自启,崩溃会自动拉起,因为weknora的问答链路是长连接等待,推理服务一旦挂掉,用户端就是"请求超时"这种最糟糕的体验。我还在服务里加了简单的并发锁:同一时刻只允许一个batch在推理,多余的请求排队等待,避免并发过高把设备内存挤爆。实测下来,把batch设成4、队列长度设成16,整机的稳定性和吞吐的平衡是最好的。

4. weknora知识库的部署与它的Ontology RAG设计

模型服务就绪,接下来是知识库本体。weknora这个项目之所以让我愿意花时间部署,不是因为它名字里带个RAG,而是它的检索架构和我前面说的RAG瓶颈是对应的。

4.1 weknora的核心思路:用图谱给向量检索当骨架

weknora在文档解析阶段不只是切块embedding,它会额外做一层实体和关系的抽取,构建出知识图谱。传统RAG和weknora的区别,我整理了个对比表:

维度传统向量RAGweknora的混合RAG
数据组织文档切块向量化向量 + 实体/关系图谱 + 本体定义
多跳推理弱,靠LLM自行拼凑强,可沿图谱边做路径推导
可解释性差可展示实体路径
实现复杂度低中等偏高

所以weknora在问答时不是只做"文本相似度topk",而是先尝试把用户问题映射到图谱里的实体和关系,再在图谱上做子图检索,同时也保留向量召回的结果,两者融合后交给LLM生成答案。它把"非结构化的文本知识"和"结构化的实体关系知识"拧到了一起,这就是热搜里"rag知识库和结构知识库区分以及应用场景"问题的落地答案。

4.2 部署步骤与组件清单

weknora官方提供docker compose方式一键部署。这一步比我想象的顺利,核心组件大概有这些:后端服务、前端界面、关系型数据库(存知识库配置、文档元信息)、向量数据库(存文本向量)、图数据库(存实体关系图谱)、以及模型服务对接层。

我用的是标准做法:

git clone https://github.com/Tencent/weknora.git cd weknora/docker # 修改 .env 里的数据库密码、端口映射 docker compose pull docker compose up -d

首次启动后要做的初始化工作有三个:创建知识库、配置模型Provider、上传测试文档。

配置模型Provider是关键。weknora支持对接Ollama、OpenAI兼容服务等。我要接的自然是前面在1684X上跑起来的那个OpenAI兼容服务,在配置项里填:

  • base_url:http://<1684X主机IP>:8000/v1
  • api_key:随便填一个占位符,本地服务不做鉴权
  • 聊天模型:qwen3-vl-4b
  • 向量化模型:这里我单独用了另一个embedding bmodel(我用的是bge-m3转出的1684X版本,同样暴露成OpenAI兼容的/v1/embeddings端点),配置成weknora的embedding模型

注意一个容易被忽略的点:weknora的文档解析阶段,实体抽取的效果直接决定了知识图谱的质量,而实体抽取通常也是由LLM完成的。如果这一步也走1684X的qwen3-vl,解析速度会对齐推理性能,大文档批量导入时要做好排队时间预期。如果想更快,可以把实体抽取用到的小模型单独转一个轻量bmodel专门跑抽取,1684X串行跑两个模型服务是没问题的。

4.3 上传文档与图片类型数据处理

关于"rag知识库能存储图片嘛",我实际在weknora里验证的结果是:文档解析器对图片不是简单丢弃,但也远没到"自动理解",更准确的说法是它会区分文本块和图片块,图片会被保存为一个独立的对象,在数据模型里可以索引和引用。

要让这些图片真正"可被回答",就需要把连接做好——问答链路发现这是一个图片块时,把它取出来,连同问题一起发给qwen3-vl的多模态接口。这个逻辑不属于weknora默认行为,属于改造点。我的做法是在weknora的外部问答编排层加了一个分支:当检索结果里出现图片类型的内容块时,走多模态请求;否则走纯文本请求。这个分支让整个系统在"图里有答案"的场景下不再哑火。

5. 把1684X上的qwen3-vl与weknora连接成完整流水线

前面各组件都是独立零件,这一步是总装。连接的价值在于形成一套"从文档入库到图文问答"的完整闭环。我按问题在系统里走的路径来讲。

5.1 入库链路:文档如何变成图谱和向量

用户把一批PDF和含截图的网页导入weknora后,内部大概经历四步:

  1. 文档解析:按版面抽取文本、表格、图片。
  2. 文本切块+向量化:调用我在1684X上封装的embedding服务,生成块向量入库。
  3. 实体与关系抽取:调用qwen3-vl或专门的抽取模型,识别文档里的实体和实体连接,写入图数据库。
  4. 索引构建:向量库、图谱库分别建索引,形成可检索的双通道。

这个过程中1684X承担了两个角色——embedding供给和抽取推理。这一步我建议异步化:文档导入队列先落库,后台任务慢慢做解析和抽取,避免用户上传文档时同步卡顿。我实测一份50页的混排文档,解析加抽取大概要几分钟,同步等会让人怀疑系统是不是坏了。

5.2 问答链路:向量召回与图谱召回双通道

用户提问"根据某设备型号的故障记录,说明温控异常的处理流程",weknora不会先去拼Prompt,而是先做问题理解,拆出关键实体比如设备型号、故障类型,再去图谱库和向量库分别检索。我观察到的完整链路是:

  • 向量通道:将问题embedding化,在文本块里召回相关段落。
  • 图谱通道:把问题里的实体映射到图谱节点,沿着关系边找关联子图,比如"温控异常→传感器读数→更换周期→处理记录"。
  • 融合排序:把两路结果合并,按相关度、路径长度、内容完整性重新排序。
  • 应答生成:把排序后的文本块+图谱实体路径拼入Prompt,交给qwen3-vl。

这里能明显看到qwen3-vl的作用不止回答问题,连"问题理解"和"实体抽取"也由它承担。多模态能力在图谱召回环节的额外好处是:如果文档里一张架构图直接展示了模块依赖关系,传统RAG只能用图片文件名当线索,而qwen3-vl能读图并生成"模块A依赖模块B"这类文本描述,从而顺利进入图谱关系抽取流程。

5.3 我实际跑通后的效果与调整

连通后的首轮实测,我拿的测试集是30份带截图的设备故障文档,问题分三类:纯文本事实型、跨文档推理型、图片内容型。纯文本型的回答质量提升最明显,原因是图谱通道找回了以前向量检索漏掉的关联片段;图片内容型是"以前完全答不了的问题",现在能给出和截图内容一致的答案;跨文档推理型是我最关注的,weknora沿图谱做了两步跳转后,回答的完整性有明显改善,但还是会出现图谱抽取时实体名不一致导致漏召回的情况。

针对实体名不一致,我在导入前做了一步预处理:同义词归并。比如"温控模块"和"温度控制单元"在抽取阶段被识别成两个节点,通过设置同义别名把它们合到同一个实体上。这一步对最终问答效果的提升,比调任何向量相似度阈值都管用。

6. 复盘与避坑:这套架构的适用边界

最后说点不能只靠搜教程就能拿到的经验。

6.1 转换过程最容易翻车的三个地方

第一个是模型转换时的算子支持。qwen3-vl这类新模型对TPU工具链来说存在兼容窗口期,转之前先去算能官方模型仓库看有没有现成的qwen3-vl bmodel或者类似架构的参考实现,能大幅减少自己踩编译坑的时间。第二个是量化精度。INT8量化后模型的图像理解能力可能下降,我遇到过一次量化后模型把"接线端子"认成"连接插头"的情况,不是完全错误,但专业场景里这种模糊很致命。解决方式是准备带领域标签的校准集,并在量化后用一套固定的测试图集做回归比对。第三个是Python环境版本不一致。sail接口对Python版本要求严格,我用的是3.8环境一次通过,换了3.10后各种so文件找不到,排查半天才发现是Python版本不匹配。

6.2 连接配置层面的几个小坑

weknora对接OpenAI兼容服务时,踩过两个具体问题。第一个是模型名不匹配,weknora会调用/v1/models来发现模型列表,有些对接框架会自动选择列表里的第一个模型,如果我的服务里同时暴露了chat模型和embedding模型,顺序不对就会导致weknora把embedding模型当chat模型调,报rate limit或者输入格式错误。解决办法是把embedding模型的模型名里加上-embedding后缀,让weknora在配置界面上能明确分开选。第二个是网络超时设置,长文档问答时qwen3-vl要生成较长上下文,单次请求耗时可能超过weknora默认的30秒超时,需要把对外接口的超时配到120秒以上。

6.3 这套组合真正适合的场景

折腾完这套架构,我的结论是它不适用于所有RAG场景,但有明确的主场:需要处理大量带图片、截图、表格扫描件的私有文档,同时对数据不出内网有硬性要求,并且对回答的可解释性有要求的场景。在这类场景里,用1684X跑视觉模型加weknora做结构化知识库,是目前成本可控、数据可控、效果也能打的一条路线。

反过来,如果只是纯文本问答、文档量巨大且对实时性要求苛刻,传统向量RAG会更省事;如果对视觉理解要求极高且不介意数据出网,直接调云端多模态API的效果大概率更好。部署这套方案前,先拿一个真实的图文文档集做端到端验证,别被"多模态RAG"这个词忽悠上头。

最后说一个我个人的实操体会:把模型部署到国产算力上,真正难的不是跑通demo,而是"配套工具链的成熟度管理和异构适配"。qwen3-vl不是为1684X设计的,weknora也不是为1684X设计的,把两个"不是"硬凑到一起的过程中,最值钱的产出其实是那套适配层的经验:哪些算子可以绕,哪些配置要提前改,哪些测试集要随身带。这些东西换到下一张AI加速卡、下一个新模型上,依然能用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询