文章摘要
本文围绕Qwen3.8 - 27B+DeepSeek Harness构建编程智能体展开测试。作者先对Qwen3.8 - 27B进行全流程实测,通过调整参数验证其性能,确定最优配置。随后将该模型接入DeepSeek Harness框架,完成API、工具调用等链路闭环。实际编码测试中,模型完成多项任务,整套测试链路打通,后续计划优化性能并展开更多测试。

前不久,Qwen3.8-27B正式开源,这款模型原生支持262K上下文长度,还搭载了MTP speculative decoding技术。笔者第一时间下载了这个总大小约52G、包含18个safetensors分片的模型,并在适配了96GB显存的专业显卡上完成了全流程实测,全程未做量化,直接使用原生BF16权重。

我们使用的宿主机搭载NVIDIA RTX PRO 6000 Blackwell Workstation Edition显卡,显存约96GB,驱动版本为580.159.03,通过nvidia-smi可查看到宿主CUDA版本为13.0。此前我们已经基于该硬件搭建了一套vLLM Docker镜像,运行环境包含vLLM 0.18.0、PyTorch 2.10.0+cu128、CUDA 12.8以及Transformers 4.57.6。本次测试没有重新构建镜像,而是通过软链接将模型目录指向新下载的Qwen3.8-27B权重,令人惊喜的是vLLM 0.18.0可以直接识别该新模型架构,无需修改Dockerfile。需要注意的是,官方针对完整多模态processor建议Transformers版本≥5.8.0,但本次仅测试文本处理场景,因此暂时没有更新Transformers版本。

我们保留了原有环境,仅对启动参数做了简单调整,具体配置如下:

模型软链接
qwenmodel -> Qwen/Qwen3.8-27B
容器启动参数
--model /model
--served-model-name qwenmodel
--dtype bfloat16
--max-model-len 16384
--max-num-seqs 32

第一轮测试我们设置了16K上下文长度,用于验证模型能否稳定加载。启动后18个safetensors分片全部顺利载入,耗时约22秒,模型占用显存51.08 GiB,剩余约28.27 GiB可用于KV Cache。vLLM识别出的模型架构为Qwen3_5ForConditionalGeneration,兼容接口也正常启动。

我们尝试让模型实现线程安全的LRU Cache,设置max_tokens为4096。请求没有报错,但finish_reason为length,最终没有输出任何可执行代码,所有4096个输出Token都用于思考过程。这符合官方给出的vLLM recipe说明:Qwen3.8支持low/medium/xhigh三档adaptive thinking模式,默认配置为xhigh,也可以完全关闭思考过程。

基础性能优化与MTP参数测试

我们先完成了基线性能测试,在1K输入、1K输出的单请求场景下,模型的生成速度为29.11 tok/s。由于Qwen3.8-27B本身搭载了MTP技术,可以一次预测多个Token再由主模型批量验收,我们尝试逐步调高MTP参数:

  • MTP=1:42.33 tok/s
  • MTP=2:51.14 tok/s
  • MTP=3:54.54 tok/s

当MTP设置为3时,单请求生成速度相比基线提升了87.4%。在并发测试中,8路并发总吞吐从191.66 tok/s提升至295.84 tok/s,32路并发总吞吐也从561.89 tok/s提升至723.13 tok/s。当MTP提升至4时,第三个预测位置的接受率已经降至约32%,继续提升参数的收益有限,因此我们最终将MTP参数固定为3。

长上下文测试与最优配置

在短请求场景调试完成后,我们开始测试模型的原生262K上下文能力。Coding Agent的对话、源码、命令输出和测试日志都会被存入KV Cache,上下文长度越长,显存压力也就越大。我们首先尝试使用FP8 KV Cache来节省显存,虽然容量层面取得了成功,但短请求性能出现了严重下滑:生成速度从54.54 tok/s降至25.85 tok/s,MTP接受率也从52.51%降至7.05%,节省的显存几乎完全抵消了生成性能的提升。

随后我们撤去FP8 KV,回到BF16/auto KV配置,同时保留max-model-len=262144,服务顺利启动,满长度请求的并发估计为1.56x,短请求速度恢复至52.79 tok/s。

我们分别测试了32K、64K和128K的真实输入场景:

  • 32K上下文:首Token加载耗时6.45秒,后续生成速度约37.1 tok/s
  • 64K上下文:首Token加载耗时14.65秒,后续生成速度约33.9 tok/s
  • 128K上下文:首Token加载耗时36.54秒,后续生成速度约18.8 tok/s

最终我们确定了最优配置:保留262K上下文上限,使用BF16/auto格式的KV Cache,MTP参数设置为3,日常Agent会话尽量控制在32K到64K区间,128K上下文场景虽然可以运行,但需要等待更长的首Token加载时间。最终的核心启动参数如下:

--dtype bfloat16
--max-model-len 262144
--max-num-seqs 32
--gpu-memory-utilization 0.90
--speculative-config '{"method":"mtp","num_speculative_tokens":3}'

接入DeepSeek Harness智能体框架

在模型服务调试稳定后,我们尝试将其接入DeepSeek Harness框架。此前我们已经测试过该框架,当时使用的是官方API对接deepseek-v4-pro。本次我们需要将本地部署的Qwen3.8-27B接入框架,首先需要在网页端打开设置,进入模型配置页面,添加自定义提供方。我们的配置文件基于局域网内的PRO 6000显卡机器,已经通过vLLM配置好了API密钥。

vLLM会将Qwen3.8-27B转换为OpenAI兼容的API接口,而DeepSeek Harness则负责维护任务历史,并为模型提供读文件、写文件、搜索和执行命令等工具能力,两者结合后,本地模型才能从单纯的聊天接口升级为Coding Agent。需要为vLLM补充三项工具调用相关的配置:

--reasoning-parser qwen3
--enable-auto-tool-choice
--tool-call-parser qwen3_coder

其中--reasoning-parser用于拆分模型的思考内容,--tool-call-parser用于将模型发出的工具请求转换为标准结构,--enable-auto-tool-choice则允许模型自主决定何时调用工具。我们在DeepSeek Harness的设置中新增了一个名为qwenlocal的自定义Provider,协议选择openai-completions,模型ID使用vLLM对外暴露的qwenmodel,同时配置上下文长度为262144,最大输出Token为32768,无需修改框架源码即可完成配置。

实际编码测试与效果验证

我们打开一个新的会话,选择本地部署的Qwen3.8-27B模型,首先询问“你是谁”,模型回答自己是千问,同时能够识别当前运行在编程智能体环境中,可以读取和编辑代码、执行命令以及搜索文件。随后我们要求模型查看当前工作目录,并明确说明必须调用工具而非直接猜测结果,模型成功发出了文件发现请求,框架执行后将结果返回给模型,最终模型列出了工作区中的8个文件,至此API、工具调用和结果回传的链路已经完全闭环。

我们选择了此前使用deepseek-v4-pro测试过的AINLP工作台项目,要求Qwen3.8-27B完成以下任务:先读取README和相关脚本理解项目用途,找到一个安全的改进点,说明理由后完成修改,检查diff并运行验证,且不触碰无关文件。模型在遍历几个文件后,将注意力放在了apply-welcome-copy.mjs脚本上。

该脚本的作用是将工作台中的旧文案替换为AINLP专属文案,README说明脚本可以重复执行,但原实现存在问题:第一次替换成功后,旧文案会被移除,第二次执行脚本时会因为找不到旧文案而报错。模型的第一版修复逻辑为:当找不到旧文案时,检查是否已经存在新文案,如果已经替换过则直接跳过,若新旧文案都不存在则报错。修改完成后,模型运行了语法检查,并构造了三种测试场景:首次执行、重复执行和传入无关内容,所有测试均通过,整轮测试共13步,耗时4分20秒,其中工具调用累计仅占0.9秒。

随后我们新增了一个测试场景:当文件中同时存在旧文案和新文案时,原修复逻辑会出现什么问题。模型很快构造了这种“只修改了一半”的文件场景,并对之前的补丁进行了优化,新的判断逻辑为:仅当存在1份旧文案且不存在新文案时才允许替换;当不存在旧文案但存在新文案时,说明已经完成过替换,直接跳过;若新旧文案同时存在、内容缺失或数量异常,则直接报错。本次测试还新增了回归测试,覆盖7对文案替换、干净首次运行、重复运行、全部混合状态和缺失状态,最终汇总的48项断言全部通过。

完整任务结束时,DeepSeek Harness共记录了5轮、23步操作,模型推理累计耗时16分18秒,工具调用总耗时仅2.7秒,平均首Token等待时间为6.8秒,生成速度约45 tok/s,缓存命中率为0%。页面上显示的累计输入Token约为736K,这个数字来自23个步骤的累加,单次请求并没有直接塞入736K Token,而是Agent每向前推进一步,都会将增长中的对话、系统提示词、工具说明和运行结果重新发送给模型,因此大部分耗时都消耗在反复读取上下文和生成内容上,文件操作本身的耗时可以忽略不计。后续我们计划优化prefix caching和上下文压缩来进一步提升性能。

从最初的旧Qwen3-32B Docker环境,到成功跑满Qwen3.8-27B的原生262K上下文配置,再到将其接入DeepSeek Harness并完成实际编码修改任务,整套测试链路已经完全打通。本次测试仅使用了单张显卡、一个小型项目和一组连续任务,还无法证明Qwen3.8-27B可以稳定处理所有大型代码仓库,但至少这台本地Coding Agent已经不再只会回答理论问题,而是真正完成了文件读取、代码修改和测试验证的全流程工作。关于Qwen3.8-27B的更多测试内容,我们会在后续逐步展开。

参考链接

以上内容不代表本平台立场,仅供读者参考