openJiuwen 是由华为 2012 实验室联合各产品线团队、以及高校、企业等广大开发者构建的开源 AI Agent 平台,社区代码仓 Star 数已超过 100K。让智能体持续自我改进,是 openJiuwen 重点投入的方向之一。从此前发布的双维度RSI框架,到本篇关注的 InferRSI,openJiuwen 的探索沿着一条清晰的主线展开:怎样把一次改进变成可验证、可保留、可继续使用的能力。前者聚焦智能体的工作方法与交付成果,后者把这一思路用于模型推理,探索更适合特定模型、任务和硬件的执行方式。

在此前发布的双维度 RSI 框架介绍中(https://mp.weixin.qq.com/s/jXZhv7tY2EniQdRs6XxoQA), openJiuwen 将 RSI(Recursive Self-Improvement,递归自我改进)落到两个方向:Harness 优化提示词、技能、工具及执行约束,改进智能体的工作方法;Artifacts 持续打磨科研论文和算法程序,提升实际交付成果。
这项能力已在 9 月发布的 WorkSwarm 0.2.6 中落地:依据真实任务反馈提出改进,执行验证,再保留有效经验。随后,WorkSwarm 0.2.7 加入基于执行轨迹的经验积累、可复用的 SkillPack 技能组合,以及面向多智能体团队的评价与优化闭环,进一步把一次任务中的有效做法用于后续任务。
沿着这条持续改进的主线,InferRSI 将关注点进一步转向模型背后的推理系统。在本文介绍的协同方案中,openJiuwen 组织任务与工具调用,InferRSI 管理实验并对比性能和输出质量,让代码改进接受实际运行结果的检验。面向昇腾 NPU,这条路线从算子调优、通用框架优化,延伸到专用引擎构建,目标是让每个模型都能拥有适合其任务和硬件的推理引擎。
两项 NPU 实践:图像延迟与语音吞吐的变化
据项目公开的测试记录,在单张 Ascend 910B1 上,基于 InferRSI 实验流程构建的 Qwen3-TTS 专用引擎吞吐最高是 SGLang-Omni 的 14.2 倍、vLLM-Omni 的 4.8 倍。最高倍数来自单并发测试:三轮平均值分别为 61.12、4.31、12.71 frames/s;语音内容的准确度和音色相似度也达到测试前定好的要求。
同样在 910B1 上,Qwen-Image 的用时从 3111.5 降至 2459.6 ms(−21.0%),生成图片的每个像素都与原来相同。再加上可选的 VAE 加速方案,用时降至 2425.5 ms(−22.0%);图片有细微差别,但仍达到测试前定好的画质要求。
这两项实践展示了 openJiuwen与 InferRSI 的分工:openJiuwen 安排任务、调用工具,InferRSI 管理实验并记录改动与结果;依据 NPU 上的实测决定保留哪些优化,再把经验用于下一轮。以下展开它们的实现方式、测试条件与适用范围。

图 1|主要通过 openJiuwen 发起任务,也支持其他 Agent 接入。

把输入变成图片或语音,这个使用模型的过程叫作推理。模型决定要算什么;推理框架把请求、计算步骤和内存安排起来;NPU 是面向神经网络计算的加速芯片,负责执行计算。模型能在 NPU 上运行,说明这条链路已经接通,但计算中仍可能有重复、等待和不必要的数据搬运。
这里说的“NPU 亲和”,就是让计算方式更适合 NPU:能复用的信息不重复算,能合并的小操作一起执行,数据布局和算子选择也与硬件匹配。优化最终要回答两个问题:用户少等了多久,同一张卡能多处理多少任务。
InferRSI 把这件事分成三个阶段,优化范围从局部逐渐扩大:

图 2|每个阶段做出什么:更快的算子、框架补丁、专用引擎。
算子级自主调优,先把一个计算环节做好,例如 KDA 等算子;框架级自主调优,沿用 vLLM、SGLang 及其 Omni 框架,改进模型在其中的执行路径;场景专用框架生成,则围绕特定模型、任务负载(输入长短、请求量、并发等)和硬件,构建自己的推理引擎。
前两步通常交付算子或框架补丁,第三步交付可独立运行的引擎。三者可以按需求选择,本文用 Qwen-Image 和 Qwen3-TTS 展示后两个阶段。

一次调优,需要读代码、提出改法、运行测试,再判断结果是否值得保留。RSI 在这里强调持续改进:下一轮尝试要用上上一轮学到的东西,成功方案和失败原因都要留下来。
在本文的组合方案中,openJiuwen 是主要任务入口,负责理解目标、规划步骤和调用工具。例如,接到“在画质不变的前提下降低图像生成延迟”后,组织代码修改、基准测试与结果分析。InferRSI 提供实验管理、结果检查和调优经验,让每次尝试都能回头核对。

图 3|先定要求 → 尝试改进 → 对比测试 → 决定是否保留 → 记住经验。
InferRSI 内部:把实验、模型和环境分开管理
前面的流程图说明“一轮优化怎么走”,下面这张架构图说明“这些工作由谁完成”。InferRSI 从入口接收本轮任务并检索已有经验,由 Harness 组织实验,再调用 Model 与 Infra 提供模型和运行环境能力。这里的 Harness 指 InferRSI 内部的实验管理与评测模块;前文双维度 RSI 中的 Harness 则指智能体的工作方法与执行机制,两者所处层次不同。

图 4|InferRSI 自身架构:入口与知识、实验管理、模型适配、运行环境,以及本轮交付的结果与报告。
图中的 Harness、Model、Infra 可以理解成三项分工:Harness 管“怎么公平地测、测完怎么判断”;Model 管“发什么请求、看什么指标、怎样检查输出”;Infra 管“代码版本、设备、进程和结果文件”。换模型或硬件时,公共的实验流程可以继续复用。
每轮先定好测试任务、质量要求和时间预算,再让 openJiuwen 组织尝试,调用 InferRSI 运行对比并查看结果。速度有提升、输出也符合要求,才保留改动;没提升、内存不够或算错了,也记下原因。
例如,缓存虽然可能省时间,但缓存内容一旦用错,模型就可能算错;换一个 NPU 算子,也可能因为计算规则不同而改变结果。把这些检查和经验接到下一轮,才让“自主调优”成为可积累的过程,而不是反复碰运气。

先看第二阶段:在 vLLM-Omni 的现有执行路径上优化 Qwen-Image。这条路线沿用框架,围绕具体模型减少额外开销。
Qwen-Image 要经过多个步骤生成图像。据项目调优记录,这项实践从三处入手:首先共享 modulation 准备,避免重复准备同一份输入;然后让提供位置信息的 RoPE 使用合适的 NPU 实现;最后尝试加速 VAE,也就是把模型内部的图像表示还原成图片的环节。每改一处,都单独检查速度和画质。
测试设置:单张 Ascend 910B1,BF16、eager、TORCH_SDPA、CFG=1,1280×704;保持模型原本的 8 步采样,sigmas 不变。预热 2 轮后,用相同提示词测 3 次,seed=42/43/44,取平均值。

图 5|逐项消融:每次只关闭一项优化,柱长为该项省下的时间;两项主要收益分别来自共享 modulation 准备 + decode broadcast(约 255 ms)和 NPU RoPE(约 194 ms);各项消融结果不直接相加。
图 5 用逐项消融看每项优化的贡献:在全栈开启的基础上,每次只关闭一项优化,看延迟回升多少。全栈参考延迟为 2280.44 ms(另一组对照为 2284.09 ms),每项测两次取平均。收益主要来自两项:共享 modulation 准备 + decode broadcast 省下 254.92 ms(10.05%),NPU 原生 RoPE + 表复用省下 193.95 ms(7.84%);模型内 attention 融合、NZ 格式权重、VAE 改动各省 27~49 ms,两次重复方向一致。只开 decode broadcast、MLP 中间结果复用都只省约 14 ms,与对照组漂移相当,这个负载下 fused SwiGLU 也没有生效;residual buffer 复用和请求 KV 复用两次重复方向相反,看不出稳定收益。各项单独测量,节省值不能直接相加。早期版本逐项叠加的结果:仅共享 modulation 准备,用时为 2654.3 ms(−14.7%);加 RoPE 后为 2459.6 ms;再加 VAE 为 2425.5 ms,额外省下 34.1 ms。前两项保持每个像素都相同;VAE 方案的像素有差别,但图像相似度达到 SSIM ≥ 0.99、PSNR ≥ 35 dB,符合测试前定好的画质要求。
这组结果也说明了怎么做取舍:主要收益来自减少重复计算和适配 NPU 算子。VAE 的额外收益较小,是否采用,要看业务能否接受图片差别。先保住输出,再讨论多快一点,结论更容易落地。
在 NPU 上提速,也要算对、保住画质

图 6|先减少重复计算,再确认 NPU 算子算得对,最后检查画质再决定是否启用 VAE 改动。图中选取三类代表性改动说明检查方法,不作为性能收益排序。
缓存要知道什么时候该更新,NPU 算子也要先核对计算规则。名字相近的两个 RoPE 算子,处理数据的配对方式可能不同;直接替换,即使跑得更快,也可能算错。图 5 中 NPU 原生 RoPE + 表复用省下约 194 ms,这类收益只有在确认算得对之后才能保留。
给开发者的细节:npu_rotary_mul 的 interleave 模式采用相邻配对;Atlas A2 的 npu_apply_rotary_pos_emb 只支持前后半段配对(half 模式),两者不能直接互换。cos/sin 表要跟着当前 freqs 更新,decode 时只取目标 token 对应的末尾部分(上游补丁见 [6])。
失败的尝试,也能让下一轮少走弯路

图 7|没提速、内存不够,都值得记下来;换设备或换引擎后再测一次。
一些改法没有带来收益,组合后还可能耗尽内存。InferRSI 把适用条件、改动和结果一起留下,让下一轮先排除已知问题;换设备或执行方式后,再重新验证。
具体记录:融合 attention 在 precise=0 时为 2623.7 ms,只快了约 1%,没有达到当时的保留要求;precise=2 为 2655.2 ms,缓存展开后的 mask 为 2667.5 ms。每轮实验的起点不同,不能把这些数字都直接拿来和最终的 2459.6 ms 比。

再看第三阶段。如果模型、任务负载和硬件相对固定,就可以进一步围绕这组需求设计调度、缓存和输出方式。对语音服务来说,既要尽早播出第一段声音,也要接得住多个同时到来的请求,优化范围因此扩展到了整个引擎。
qwen3-tts-engine就是这一阶段的实践产物:为 Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice 构建,在 910B1 上用 BF16 运行。它复用官方模型组件和权重,自己负责调度、NPU 图执行和流式语音输出,可以独立运行,不依赖 vLLM-Omni、SGLang-Omni 的运行时。

图 8|把请求组批、缓存管理、NPU 计算和语音输出连起来。
先看请求怎么走。输入先经过 prefill,也就是处理输入、准备模型的初始状态;随后进入逐步生成。调度器会把多个请求合成批次计算,并支持持续组批:已有请求运行时,新请求也能加入后续批次,提高计算资源的利用率。
每个请求分别保存 KV 缓存,也就是已经算过的注意力信息,后续生成可以接着用;音频解码状态也分别保存,codec 把模型输出逐段还原成声音,用户不用等整段生成完才开始听。Talker / Predictor 中可重复的计算过程会预先准备成 NPU 图,随后反复执行,减少发起计算的开销。
底层还会把多次投影计算打包,使用 NPU 原生的分组查询注意力(GQA)和归一化算子,并合并 RoPE、KV 更新、采样中的小操作。只有固定的 embedding 会缓存,文本和风格指令的投影仍逐次计算。
项目公开的交付内容包括可运行的引擎代码、固定启动配置、性能测试脚本、质量检查和逐个请求的记录,也标出了 InferRSI、Strata 与 Ascend 经验的来源。阶段三把调优经验变成了一套可以运行、测试和继续改进的软件。
这条路线适合需求相对集中的场景,同时也要承担维护专用引擎的工作。模型多、需求经常变化时,可以优先优化通用框架;确定了长期要服务的模型和负载,再评估专用引擎是否值得投入。
同一张 NPU 上比一比:跑得多快、多久听到第一段语音
读这组数据,先抓住三个指标:吞吐表示单位时间能生成多少语音,越高越好;首段语音时间(TTFA)表示用户要等多久才听到声音,越低越好;RTF 表示生成用时与音频时长的比值,低于 1 就是生成速度快于音频播放速度。
并发数表示同时处理的请求数:C1 更接近单个用户发起请求的情况,高并发则观察多人同时使用时的表现。三套引擎使用同一张 910B1、同一模型版本和 BF16,各跑 3 轮;并发设为 1/2/4/8/16/32/64,每档 128 个请求(64 英文、64 中文)。8,064 次计时请求全部完成,9 个服务进程都正常退出。

图 9|吞吐取三轮平均值,误差线表示轮次间的波动(样本标准差);下栏是 C1 等到首段语音的 p95 时间。
并发 1(C1)时,专用引擎、vLLM-Omni、SGLang-Omni 的吞吐分别为 61.12、12.71、4.31 frames/s。专用引擎首段语音等待时间的 p50/p95 为 50.41/51.97 ms,RTF=0.206;vLLM-Omni 为 263.51/273.21 ms,RTF=0.989。并发 64(C64)时,三者吞吐为 549.39、228.07、71.60 frames/s,RTF 为 1.212、2.477、9.386(越低越好)。
3 轮、7 档并发,共 21 组结果:专用引擎的吞吐都超过同并发下两套对比框架最快一次结果的 2 倍,最小比值为 2.047683×(C32)。这个倍数描述的是本次实测结果。
速度之外,还要检查有没有读错内容、音色有没有变。2,688 条语音都逐条做了自动检查:对比同并发下两套框架里最好的结果,英文单词错误率(WER)、中文字符错误率(CER)最多增加 1 个百分点,音色相似度最多降低 0.02。三轮、各档并发都满足这些要求,整体验证通过(PASS)。
怎么算:吞吐=音频总秒数×12.5/整组实际用时;TTFA 从发出请求算到收到首段语音,包含排队。p50/p95 先算每轮结果,再取三轮平均;RTF=完成请求用时/音频时长。测试在共享主机上依次运行,SGLang 加了类型导入兼容补丁,两套对比框架使用了绕过已知内存分配问题的设置。结果只适用于这里的模型、任务和配置;自动检查不能代替真人试听,也不说明音频波形完全一样。

下面两条路径互不依赖:路径 A 用 InferRSI 跑一次“基线 vs 候选”的对比实验;路径 B 直接启动本文测试的 Qwen3-TTS 专用引擎。两者都假设机器上已装好 Ascend 驱动、CANN 和 torch_npu;InferRSI 不负责安装模型、驱动或服务,也不会自动启动 Agent。InferRSI 的命令行工具名为 inferrsi。
路径 A:用 InferRSI 跑一次 A/B 对比
第 1 步,在 InferRSI 仓库根目录安装,并检查目标仓库和 NPU 环境:
python -m venv .venv && source .venv/bin/activatepython -m pip install .inferrsi --helpinferrsi doctor --repo /work/vllm-omni-baseline --repo-type vllm_omni–backend ascend --device-ids 0 --device-model 910B1
第 2 步,准备基线和候选两份代码,再写三个脚本:baseline.py、candidate.py 分别启动服务、预热,跑同一组固定输入,并把结果 JSON(例如 {“metrics”: {“latency_mean”: 0.1234}},单位为秒)写到 {result};validate_quality.py 把输出和参考结果对比,画质退化时返回非 0。这三个脚本需要自己准备,InferRSI 不会生成。
第 3 步,先用 plan 预览实验设置,确认无误后把 plan 换成 run,其余参数不变:
inferrsi plan–repo /work/vllm-omni-baseline --candidate-repo /work/vllm-omni-candidate–repo-type vllm_omni --backend ascend --device-ids 0 --device-model 910B1–scenario diffusion.image_generation --model Qwen/Qwen-Image-2.1-Turbo–baseline-command ‘python /work/trials/baseline.py --output {result}’–candidate-command ‘python /work/trials/candidate.py --output {result}’–validation-command ‘python /work/trials/validate_quality.py’–metric-key latency_mean --metric-unit s --direction minimize–repetitions 3 --min-improvement-pct 5 --max-minutes 120–output-dir /work/inferrsi-runs
–min-improvement-pct 按测试前定好的目标填写。run 的退出码 0、1、2 分别对应 PASS、FAIL、INCONCLUSIVE(或输入错误)。
第 4 步,查看报告,并检索已有的调优经验:
inferrsi report --run-id RUN_ID --output-dir /work/inferrsi-runs
inferrsi knowledge search ‘Qwen-Image-2.1’ --repo-type vllm_omni --backend ascend
路径 B:启动 Qwen3-TTS 专用引擎
项目记录中的已验证环境:单张 Ascend 910B1,Python 3.12,torch 2.10.0、torch_npu 2.10.0.post4,qwen-tts 0.1.1,transformers 4.57.3,并已装好 CANN 和 Triton Ascend。
第 1 步,安装引擎,下载固定版本的模型:
git clone https://github.com/InferMatrixLab/qwen3-tts-engine.gitcd qwen3-tts-engine && python -m pip install --no-deps -e .export QWEN_TTS_MODEL=/path/to/models/Qwen3-TTS-12Hz-1.7B-CustomVoicehuggingface-cli download Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice–revision 0c0e3051f131929182e2c023b9537f8b1c68adfe --local-dir $QWEN_TTS_MODEL
第 2 步,按项目此次测试所用配置启动服务(持续组批、流式输出、NPU 图和 Triton 算子都已打开)。LD_PRELOAD 是 ARM64 环境下绕过内存分配问题的设置,请换成本机的 jemalloc 路径:
export ASCEND_RT_VISIBLE_DEVICES=0 OMP_NUM_THREADS=4 HF_HUB_OFFLINE=1export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2python -m qwen3_tts_engine.server–model “$QWEN_TTS_MODEL” --port 8099–continuous --streaming --max-batch-size 64–codec-left-context 72 --codec-batch-size 4–incremental-codec --prewarm-codec --cache-codec-codebooks–pack-qkv --pack-mlp --native-kv-update–batch-prefill --prefill-per-tick 64 --text-only-rope–native-gqa --graph-embeddings --graph-prefill–rms-norm native --fused-swiglu --native-rope–graph-sampling --native-rope-scope predictor–triton-snake --triton-kv-update --triton-talker-rope–prewarm-prefill --triton-cdf --bucket-prefill --direct-prompt
服务监听 127.0.0.1:8099。首次启动会编译算子并预热 NPU 图,在另一个终端确认就绪后再发请求:
curl --fail http://127.0.0.1:8099/health第 3 步,生成语音。接口以 SSE 流式返回 base64 编码的 PCM,不直接返回 WAV;保存成 WAV 的完整客户端脚本见 [7]。
curl -N http://127.0.0.1:8099/v1/audio/speech -H ‘Content-Type: application/json’-d ‘{“input”: “你好,这段语音由 Ascend 专用引擎生成。”, “voice”: “Vivian”,“language”: “Chinese”, “response_format”: “pcm”, “stream_format”: “sse”, “seed”: 42}’
直接运行引擎命令、不加载上述配置时,默认参数不同,无法复现本文的性能数据。

前面的案例围绕服务器侧 NPU 展开。下一步,openJiuwen将尝试把“针对模型、任务和硬件生成专用引擎”的方法计划扩展到手机、汽车和机器人等设备,优化目标也会从速度扩展到内存、能耗与持续运行表现。以下方向仍处于规划阶段,具体效果有待相应设备上的测试验证。
手机与汽车端侧:响应快,也要用得久
从手机离线助手、车载语音和座舱多模态交互切入,探索适合端侧资源限制的专用引擎。把模型压缩、缓存和调度一起优化,在输出质量达标的前提下,减少内存占用和能耗。评测要贴近体验:多久听到第一句回答,连续使用后是否变慢,一次任务消耗多少能量,以及断网时哪些功能仍能使用。
具身智能端侧:让整条任务链反应更及时
机器人要持续处理摄像头、语音和其他传感器信息,再生成决策或动作。后续将围绕“感知—决策—执行”探索专用引擎,减少模型之间的等待和数据搬运,关注响应时间是否稳定,以及任务能否完成。先用仿真与录制数据回放筛选方案,再到真实设备上验证;涉及动作执行时,还要保留独立的安全约束与回退机制。
异构硬件组合:让不同处理器各尽所长
面对 CPU、GPU、NPU 的不同组合,探索自动决定计算放在哪里、如何切分、何时并行,并生成对应的专用推理引擎。评估时把数据传输、同步等待和内存开销一起算进去,以完整任务的结果判断方案好坏。对隐私和网络条件允许的任务,也可进一步探索端云协同,让本地响应与云端计算合理分工。
把优化流程做成可交付、可复用的能力
进一步完善 openJiuwen 与 InferRSI 的协同:由 openJiuwen 组织任务规划、工具调用和迭代,InferRSI 管理实验、核对性能与输出质量,为下一轮提供可追溯的结果和经验。先选少量代表性设备与任务,建立包含质量、时延、内存、能耗和长时间稳定性的评测,再逐步扩大覆盖范围。
这些探索计划交付专用引擎代码、部署配置、评测报告和回退方案。模型或硬件升级后,还需要重新测试、识别退化并继续迭代,让一次优化成为后续工作的起点。

从此前双维度 RSI 对智能体工作方法与成果的优化,到 InferRSI 对模型执行路径和专用引擎的探索,openJiuwen 正在把持续改进落到更具体的工程环节。持续积累的代码、测试记录与贡献,将推动这些探索成为可复用的能力。本篇的图像与语音案例提供了两个起点,也为 RSI 系列后续观察更多模型、硬件和任务留下了空间。

openJiuwen GitHub 仓:https://github.com/openJiuwen-ai/
openJiuwen AtomGit 仓:https://atomgit.com/openJiuwen
InferRSI:推理调优与实验管理
https://gitcode.com/openJiuwen/agent-infer/tree/main/inferrsi
qwen3-tts-engine:Qwen3-TTS 昇腾 NPU 专用引擎
https://github.com/InferMatrixLab/qwen3-tts-engine
对开发者而言,参与这条 RSI 实践路线可以从一个具体问题开始:选择自己的模型、任务和 NPU 环境,复现基线,提交候选改动,再用相同输入与质量要求验证结果。相关代码和记录已在上述仓库开放,读者可通过 Star 关注项目进展,也可通过 Issue、复现报告或代码贡献参与改进。







