两张32GB加起来能干什么——蓝戟Arc Pro B65 32G双卡推理测试

一、前言

在前不久的蓝戟Arc Pro B65单卡评测里我曾过,虽然B65仅有20个Xe核心、197 TOPS INT8算力,但它的价值远不在此,而在32GB大显存。27B级别的FP8模型在一张B65上刚刚能装下,权重之外留给KV Cache的余量只够约8K上下文。再长,就是Out Of Memory。

于是便产生了一个问题:把两张B65插在同一台机器上,显存是不是简单地变成64GB?同样的Qwen3.8-27B-FP8能不能从8K一路跑到128K?而在桌面平台没有NVLink、卡间只能走PCIe的前提下,张量并行(TP)、流水线并行(PP)、数据并行(DP)这三种模式,到底哪种真的好用?

本次我将用两张蓝戟Arc Pro B65 32G显卡,把上面这些问题逐一回答。

二、运行环境

(一)硬件环境:双直通PCIe插槽的主板

在张量并行模式下,每一层的前向计算都要在两张卡之间交换激活值与KV Cache,通信量随batch与层数线性放大;流水线并行按层切段,每生成一个微批次也要在卡间send/recv。真正跑起来之后,两张卡不是各干各的,而是每算一步都要互相喊话,这条 “喊话” 的通道,就是PCIe。

而桌面平台的PCIe插槽却有两种常见形态,CPU PEG通道直连处理器、延迟最低;而走PCH的槽全部共享DMI上行。然而值得注意的是,虽然Intel在CPU层面支持将5.0 x16拆分为8+8,然而目前主流的Z790/Z890出于设计难度与制造成本考虑,大部分都只提供一条直连CPU的PCIe插槽,只有部分旗舰型号才会设计两条直连PCIe插槽,我经手过的Z890主板也不算少了,只有华硕ROG Maximus Z890 Extreme和七彩虹iGame Z890 Vulcan X 火神才有这样的配置,而本次测试使用的主板便是后者。

(二)软件环境:Ubuntu+Docker+llm-scaler-vllm

Intel显卡的多卡推理栈,一年前还只是散落在各个仓库里的实验性补丁,如今已经有了相对完整的官方路径。

目前vLLM上游已经把Intel XPU列为一等公民后端,与CUDA、ROCm、Apple Silicon并列。对B系列专业卡,Intel主推的发行方式不是让用户自己pip install,而是容器。LLM Scaler就是面向Arc Pro B系列的预装推理镜像套件:llm-scaler-vllm内部是在vLLM之上叠加了Intel定制patch与定制ESIMD kernel,卡间通信走oneCCL。启动时必须带VLLM_WORKER_MULTIPROC_METHOD=spawn、–shm-size 32g(给CCL进程间通信预留共享内存),BKC基线是Ubuntu 25.04 + kernel 6.14、BIOS开Resizable BAR、P2P最佳性能需要GRUB里intel_iommu=off。

软件栈采用了Ubuntu 26.04环境下Docker拉取intel/llm-scaler-vllm:1.5镜像,容器以–net=host --device=/dev/dri --shm-size=32g启动,容器内设置VLLM_TARGET_DEVICE=xpu、VLLM_WORKER_MULTIPROC_METHOD=spawn。单卡直接vllm serve;张量并行加–tensor-parallel-size 2;流水线并行加–pipeline-parallel-size 2;数据并行则加–data-parallel-size 2。

(五)三种并行模式:原理与取舍

TP(张量并行):把模型权重按层内切到两张卡上,每一层前向都要allreduce一次。好处是两张卡的显存真正叠加——权重各背一半,KV Cache也分摊,上下文容量接近翻倍,代价是每一步都有卡间通信。在跑单并发的时候双卡的显存和TBP功率基本打满,负责状态良好。

PP(流水线并行):把模型按层切成前后两段,第一张卡管前几层、第二张管后几层,请求按微批次在流水线上传递。显存也是叠加的(只切层不分片),但存在 “流水线气泡”,也就是第一个微批次流经前段时,后段卡在等,反之亦然;单请求要串行穿过两段,天然更慢。从下面的xpu-smi监控图可以看到,单并发不能让双卡都跑满,TBP功率只跑到了60%左右。

DP(数据并行):两张卡各自加载一份完整模型、各自对外提供服务,前面挂一个负载均衡。显存不叠加(每张卡仍是完整32GB负担),好处是零卡间通信、部署最简单;坏处是上下文没有扩容,且两实例一旦负载不均,性能就会抖动。从下面的xpu-smi监控图可以看到,单并发完全是一张显卡满载,而另一张则在看戏。

三、实测

(一)测试方法与模型

使用自编python脚本,压测脚本本身不起vLLM server,只做客户端打流,逐次调用vllm bench serve(backend vllm、host 127.0.0.1),日志全部落盘,再从vLLM统计块里抠指标。

并发测试的构造是:随机token数据集(–dataset-name random),输入长度固定2048、输出固定128(–ignore-eos强制生成满128);并发点取c=1/2/4/8,request-rate inf打满队列;prompt数= max(40, 并发×10),即c=1/2/4各40条、c=8为80条;每个点重复两轮。prefill扫描则是输出压到1个token、并发1、10条prompt,长度梯度512/1024/2048/4096/6144,单轮,目的是把TTFT主要归因于prefill计算。

模型选Qwen3.8-27B-FP8,理由很直接:27B稠密模型FP8量化后权重约28GB,单张32GB B65刚好装下、KV余量撑约8K;双卡并行时KV与权重分摊,上下文可以开到128K以上。它正好卡在 “单卡顶到天花板、双卡才够用” 的甜点位。

(二)并发吞吐:聚合decode随并发变化

表1四模式聚合decode吞吐(Output token throughput,tok/s;两轮成功记录取算术平均)

并发 单卡r1/r2 单卡均值 TP r1/r2 TP均值 PP r1/r2 PP均值 DP r1/r2 DP均值
c1 15.51/15.50 15.51 21.00/21.05 21.02 13.80/13.80 13.80 13.87/14.13 14.00
c2 15.52/15.52 15.52 31.72/31.72 31.72 19.95/19.99 19.97 21.87/28.45 25.16
c4 15.52/15.52 15.52 46.37/46.73 46.55 24.04/24.04 24.04 36.78/37.16 36.97
c8 15.52/15.52 15.52 61.36/61.39 61.38 45.69/45.66 45.67 32.98/32.96 32.97

这张表里最扎眼的是单卡一行:从c1到c8,聚合吞吐15.51 → 15.52 tok/s,几乎纹丝不动。这不是测量误差,而是结论:27B-FP8在单张B65上,c=1时decode算力就已经打满,再加并发只是在排队——mean TTFT从1.40s线性膨胀到56.25s,而mean TPOT恒定53.96ms、p99 ITL恒定约55.9ms,没有任何调度尾延迟。加并发只排不跑,就是这个意思。

TP是四条线里最漂亮的:21.02 → 31.72 → 46.55 → 61.38 tok/s,c1到c4近乎线性,c4到c8开始边际递减(+32%),代价是c8时mean TPOT从37.08ms涨到78.52ms。PP起步13.80 tok/s甚至低于单卡——这是流水线气泡在单并发下的直接体现,c4到c8才靠batch变大摊薄气泡,跳到45.67。DP的c8出现了反常:36.97 → 32.97不升反降,后面节会专门拆解。

(三)延迟与单请求速度

表2 mean TPOT与单请求decode估算(单请求= 1000/mean TPOT,tok/s)

并发 单卡TPOT/单请求 TP TPOT/单请求 PP TPOT/单请求 DP TPOT/单请求
c1 53.96ms/18.53 37.08ms/26.97 60.51ms/16.53 58.43ms/17.11
c2 53.95ms/18.53 46.81ms/21.36 81.01ms/12.34 65.87ms/15.18
c4 53.95ms/18.53 51.41ms/19.45 126.29ms/7.92 90.82ms/11.01
c8 53.95ms/18.53 78.52ms/12.74 113.37ms/8.82 129.27ms/7.74



单请求速度(c1,也就是一个用户独占服务时)是真正拉开差距的地方:TP 26.97 tok/s > 单卡18.53 > DP 17.11 > PP 16.53。TP把单请求decode速度拉高了+45.5%(26.97/18.53)——这是因为张量并行下两层权重同时在两张卡上算,单token的算力直接翻倍。PP反而比单卡慢了 −10.8%,流水线气泡让每个token都要串行穿过前后两段;DP与单卡基本持平(−7.7%),因为单请求本来就只打到一张卡上。

mean TPOT随并发恶化的幅度也值得记一笔:单卡0%(它根本不调度,请求一律排队),TP 37.08 → 78.52ms(2.1×),PP 60.51 → 113.37ms(1.9×),DP 58.43 → 129.27ms(2.2×)。

表3 TTFT分布(mean/p95/p99,ms;两轮均值)

并发 单卡mean 单卡p95/p99 TP mean TP p95/p99 PP mean PP p95/p99 DP mean DP p95/p99
c1 1402.3 1412.6/1417.8 1378.9 1381.5/1394.3 1590.4 1598.9/1627.6 1722.8 1681.6/3763.7*
c2 9439.0 9662.6/9674.9 2123.1 2811.5/2834.7 2527.6 3358.9/3424.6 1875.8 2458.2/2467.7
c4 24905.8 26173.5/26190.0 4467.6 5592.1/5592.3 5256.2 6586.2/6586.6 2138.4 3538.3/3546.3
c8 56246.2 59171.9/59185.2 6705.3 9588.8/10906.7 8004.0 11479.7/12864.0 12687.6 35036.5/35639.6

注:DP c1 p99被r1的5862.6ms单点离群拉高。

TTFT这张图把 “排队” 两个字看得清清楚楚:单卡c8的mean TTFT是56.25秒,而TP只有6.71秒。原因前面已经说了,单卡加并发只排队,请求在队列里等前面的生成完才轮到prefill;TP算力翻倍,排队长度自然短得多。延迟的长尾也要点名:TP c8两轮的p99 ITL是1438.52/1438.64ms(mean ITL只有78.5ms),PP c8是1730.23/1728.63ms,DP在c4/c8也出现约1703/1723ms的p99 ITL。这种 “均值正常、p99突然1.4~1.7秒” 的尖峰,典型指向跨卡通信(TP的allreduce、PP的send/recv、DP的两实例调度)在高并发下偶发阻塞。

(四)c8加速比:相对单卡到底快多少

模式 c8聚合decode(tok/s) 加速比 理论2×达标?
张量并行TP 61.38 3.95× 超额(通信未成为瓶颈)
流水线并行PP 45.67 2.94× 超额(气泡随batch摊薄)
数据并行DP 32.97 2.12× 未达标且c8已回撤

理论上两张卡理想加速就是2×。TP 3.95×、PP 2.94×都超额了——这说明在27B-FP8这个规模、c8的batching下,PCIe x8之间的allreduce没有把算力吃回来,BMG架构+vLLM XPU的通信效率尚可。DP 2.12×未达标,而且它是四条线里唯一在c8不升反降的,后面细说。

(五)prefill:长输入的第一道坎

输入长度 单卡 吞吐/TTFT TP吞吐/TTFT PP吞吐/TTFT DP吞吐/TTFT
512 1313.9/389.3 1380.4/370.8 1100.7/465.0 1097.2/465.6
1024 1467.7/697.6 1457.2/702.6 1265.5/809.0 1262.5/809.8
2048 1444.3/1417.7 1487.0/1377.2 1279.1/1601.0 1265.1/1618.5
4096 1424.9/2874.4 1501.1/2728.5 1267.8/3230.8 970.5/4220.2
6144 1408.4/4362.4 1499.5/4097.1 1253.5/4901.2 662.2/9277.9


prefill吞吐排序很干净:TP约1490 > 单卡约1417 > PP约1254 tok/s。脚本用512→6144两端点算出的TTFT斜率(1511/1418/1270 tok/s)与服务级估算互相吻合,说明这个排序是可靠的。在单卡/TP/PP上,TTFT随输入长度近似线性增长(每token约0.66~0.79ms),没有出现非线性爆点。

DP在这里掉了链子:4096时prefill吞吐掉到970.5、6144更是只有662.2 tok/s(TP同长度仍有约1500);6144时mean TTFT 9278ms、median 11619ms,实测持续时长92.78秒。前2048长度内DP与PP几乎重合,一到长prompt就明显退化——怀疑是单引擎显存/KV压力或路由倾斜,这也与 “DP上下文上限约8K” 的判断互相印证。

测试过程中还遇到有三类异常,一并写出来,避免只看均值被误导:第一是高并发长尾,TP c8的p99 ITL两轮1438.52/1438.64ms(mean仅78.5ms)、PP c8 1730.23/1728.63ms、DP c4/c8约1703/1723ms——跨卡通信在c8下的偶发阻塞;第二是DP c2的轮次间波动,r1=21.87 vs r2=28.45 tok/s,相差30%;第三是DP c8的回撤与双峰:聚合decode 32.97低于c4的36.97,mean TTFT 12688ms但median只有5883ms、p95 TTFT高达35037ms——典型的两引擎负载不均、其中一个变慢,请求被分到慢引擎上就形成双峰分布。

(六)显存质变:8K与128K的区别

单卡与DP部署下,32GB装进27B-FP8权重后,KV余量大约只够8K上下文,再往上直接OOM;本次prefill扫到6144 + output 1仍在8K以内,DP在4096/6144的退化也与这个上限吻合。

即使用8K的上下文勉强启动,在接入Deepseek Harnes这类智能体之后也很难正常使用。

而TP/PP把权重与KV切到两张卡,单卡负担减半,上下文可以一路开到128K以上,这对长文档RAG、长代码库分析这类场景,这才是双卡真正的理由,而不是把15.5 tok/s堆到61 tok/s。接入Deepseek Harness智能体之后也可以长时间稳定运行,不过我们也可以发现的单个任务是无法达到刚才测试的理论上限,还可以给多个用户提供余量。

这也从侧面进一步说明了双卡真正的理由,并不仅仅是把理论的吞吐量从15.5 tok/s堆到61 tok/s,更大的上下文长度同样重要。

四、总结

看完上面的测试,想必大家心里都有了一杆秤。

追求单请求速度,选TP:26.97 tok/s,比单卡+45.5%;追求稳定的高并发吞吐,还是选TP,c8聚合61.38 tok/s、相对单卡3.95×,两条关键档位它都是最优。

PP的定位是 “用单请求慢换上下文长”,它也是显存叠加、能开128K,但c1单请求只有16.53 tok/s、比单卡还慢,只适合对单token延迟不敏感、主要跑长文档的离线批处理。

DP在这套B65环境下的数据不支持推荐——轮次间30%波动、c8回撤、长序列退化三项异常同时出现,“每卡一份整模” 的简单架构并没有换来简单的稳定性。

单卡则回到它本来的位置,32GB够用、8K以内、算力打满就排队的桌面推理。

两张蓝戟Arc Pro B65 32G组双卡,拿到的是 “64GB可用显存+约1.9倍单请求算力+ c8约4倍聚合吞吐”,在这个显存贵上天的时代已经显得弥足珍贵。虽然桌面PCIe 5.0 x8+x8(约31.5GB/s×2)的互联,远不如NVLink,但在27B-FP8这个规模上allreduce没有成为瓶颈。它最适合的人群是本地跑27B及以上量化模型、需要128K以上的上下文长文档/RAG用户,以及想在工作站上低成本堆显存、而不是买一张天价的专业大显存卡的人。