Technical note
RTX4090解锁实测:矩阵翻倍之后,YOLO和VLM快了多少
最近看到一个给消费级NVIDIA显卡解除部分计算限速的开源项目。最吸引人的结果是:RTX4090的某些矩阵指令吞吐可以接近翻倍。问题也随之而来——如果服务器上实际跑的是YOLO训练和视觉语言模型,这个“两倍”能兑现多少?
2026年10月27日,在一台共享RTX4090服务器上做了一轮测试。矩阵指令确实接近翻倍,但最初的小模型训练和单请求推理几乎没有收益。随后用Profiler排查瓶颈,调整模型和batch,再切换解锁状态做同配置对比,才测到较大YOLO模型约10%~12%的训练吞吐提升。VLM则没有得到稳定的加速结果。
这几轮结果放在一起,比单独看一张翻倍的跑分图更有意思。
从20系测试转向4090
最初的打算是直接测试4090,随后先改用2080Ti验证。这里涉及两个不同项目:nlzy/turing-unlock用于Turing架构,JustAResearcher/gpu-unlock-ada则是这次4090使用的Ada实现。不能把一个项目直接换个设备ID,就当成另一张卡的适配版本。
2080Ti的经历也让后面的操作更谨慎:原驱动下,解锁模块报告成功,NVIDIA驱动却无法正常初始化显卡;换到该项目验证过的驱动后才通过。它说明“模块打印成功”与“显卡能正常工作”之间还有一段距离。
4090服务器还有其他人用于训练,已有CUDA、PyTorch和模型环境不能随意改动。因此,4090测试首先要回答的是:能不能在原驱动下工作,而不是先把软件栈升级到项目演示所用的版本。
本次固定使用gpu-unlock-ada的1.1.1版本,提交为d28c485。按该版本说明,它把公开的固件载荷接入Linux内核模块和开机流程,在原厂NVIDIA驱动启动前完成设置。上游已有4090验证记录,但那些数字只是开展测试的参考,下面的结果都来自这台机器。
它究竟解锁了什么
可以把显卡想成一座工厂。普通计算有自己的工位,大批矩阵乘法则有专门的流水线,也就是Tensor Core。模型训练和推理会经过这条流水线,也会花时间搬运数据、做其它运算以及等待下一项任务。
这次工具修改显卡内部的“速率选择”设置,让部分Tensor计算路径解除原来的吞吐限制。本次最明确的变化是FP16/BF16输入、FP32累加:乘法用较低精度的数据,许多乘积相加时,用精度更高的FP32保存累计结果。这里的FP32累加,不等于显卡上所有FP32计算都会加速。
它没有增加核心数量、显存容量或显存带宽,也不是超频。本次没有刷写VBIOS,450W功率上限保持原样。
实现时,需要在NVIDIA驱动接管显卡之前运行解锁模块。模块放在initramfs这个开机早期使用的准备包里,先运行固件载荷、写入并检查速率设置,再完成PCIe功能级复位和复查,最后交给原厂驱动。之后CUDA和PyTorch继续使用原来的环境。
所以它不是训练已经开始后,可以随手执行一下的Python加速插件。“开机默认解锁”也只是每次启动重新执行这个流程,并非永久刷入硬件。实现细节以本次固定版本的说明为准。
保留原环境,先确认真的生效
测试卡为24GB的RTX4090,AD102。Linux内核为6.14.0-27,NVIDIA闭源驱动为550.163.01,CUDA Toolkit为12.4.131。既有两套YOLO环境分别使用PyTorch2.5.0+cu124和2.5.1/CUDA12.4;VLM为Qwen3-VL-4B,采用NF4四比特量化、FP16计算、SDPA和双重量化。
这次4090在原550.163.01驱动下成功,没有升级CUDA或PyTorch。驱动接管之后,还检查了速率读回、实际计算和输出,而不是只看解锁日志。本机RM接口的fmla32读数从1变为0,对应本次未解锁和满速状态;它只是其中一项证据。
矩阵指令测试的变化很干净:
| 计算路径 | 未解锁 | 解锁 | 倍率 |
|---|---|---|---|
| FP16输入、FP32累加 | 167.3TFLOPS | 334.3TFLOPS | 1.998× |
| BF16输入、FP32累加 | 167.2TFLOPS | 334.0TFLOPS | 1.998× |
| FP16输入、FP16累加 | 336.1TFLOPS | 335.2TFLOPS | 0.997× |
| INT8/INT32 | 668.4TOPS | 668.3TOPS | 1.000× |
| 标量FP32 | 80.0TFLOPS | 80.0TFLOPS | 1.000× |
指令测试每轮测5次取最佳值,再取3轮中位数。相同驱动和功率策略下,两条目标路径接近两倍,其它对照基本不动,符合这次解锁的预期。
但换成cuBLAS矩阵乘法,提升已经不再整齐。FP16输入、FP32累加时,方阵边长1024、4096、8192的吞吐提升分别为17.0%、41.4%、9.8%。即使同样是矩阵乘法,换个尺寸和实际执行内核,也不会自动兑现两倍;矩阵越大,也不保证收益越大。
两种状态下的大矩阵输出和独立数值检查均通过,独立检查最大绝对差为0。
第一次跑真实模型,几乎没快
首轮使用YOLOv8s、batch16、imgsz640,以及70张训练图片和20张验证图片,保留实际训练流程。AMP开启和关闭分别测试,两种状态各跑3个独立进程。
| 配置 | 未解锁→解锁 | 变化 |
|---|---|---|
| YOLOv8s,AMP开启 | 149.37→141.94张/秒 | -4.98% |
| YOLOv8s,AMP关闭 | 144.42→150.23张/秒 | +4.02% |
| VLM单请求 | 4.238→4.351秒 | 延迟增加2.67% |
单请求VLM使用固定的4张图片和提示,表中是各图片服务端延迟中位数的平均值。这里没有得到模型明显加速的证据,也不能据此认定补丁一定让训练变慢。
AMP是PyTorch的混合精度开关,与补丁是否启用是两件事。比较补丁收益,必须保持AMP等配置一致,不能拿“未解锁、AMP关闭”和“解锁、AMP开启”作对照。
矩阵指令已经证明目标计算路径加速了,实际模型却没反应,接下来要找的是:模型到底把时间花在哪里?
Profiler找到了两种不同的瓶颈
这一阶段一直保持解锁状态,只调整执行配置。它用来诊断瓶颈,其中的提升不能算到补丁头上。
YOLO首先遇到了供数问题。YOLOv8s把batch增到64、workers仍为4时,吞吐只有167.29张/秒,DataLoader等待占比达到42.13%。将workers增到8,吞吐变为271.57张/秒,等待占比降至0.32%。
只改数据加载进程数,吞吐就增加了约62%。显卡在等下一批数据时,矩阵流水线再快也帮不上忙。
较大的m、l模型则不同。把输入常驻GPU、绕过增强和搬运后,YOLOv8l、batch16从99.86提高到102.21张/秒,差距已经很小。这个对照还改变了输入准备方式,不能单独算出搬运成本,但足以说明:继续只盯着DataLoader,收益可能有限。
GPU侧也不全是矩阵乘法。按内核名称分组,BatchNorm和布局转换合计约占所采集GPU内核累计时间的三分之一。这个比例不是整个训练的墙钟时间占比,但能解释为什么Tensor计算翻倍,训练仍有大量工作保持原速。
VLM的情况更偏向逐token解码和大量短小计算。固定生成64个新token的单请求约需5.19秒,首轮前向约0.168秒,后续63轮解码前向合计约4.98秒。一次任务约发起17万次GPU内核调用。
Profiler本身会拖慢请求,不能把采集窗口里的活跃时间直接当成正常GPU利用率。不过,大量短内核、调用间隙以及后面的合批结果,都支持一个判断:主机串行调度和量化路径的碎片化,是这套VLM的重要限制。
同一解锁状态下,batch从1增加到8,总生成吞吐从12.49提高到67.09token/秒,约为5.4倍。这衡量的是一次服务更多序列时的总吞吐,不能理解成每个请求都快了5.4倍。原接口还有串行锁,直接增加HTTP并发也不会自动变成GPU合批。
独立实例里关闭双重量化,单请求又降到约3.96秒,内核数也减少了。不过这改变了量化配置,尚未完成业务精度验收,没有应用到原服务,也没有计入补丁收益。
用更合适的配置,重新比较补丁
有了前面的诊断,再做一轮相同配置的未解锁/解锁对比。这次保留较大的m、l模型,并给s模型足够的workers;VLM则测试batch4和batch8。
两种状态分别启动后测量,使用相同软件包、权重、数据和脚本,不带Profiler,也不与其它CUDA计算混跑。每个配置跑3个独立进程,先取进程内中位数,再取3个进程中位数。
YOLO每个进程先预热32个完整batch,再测3组、每组10步,要求AMP的缩放系数在计时期间保持稳定。VLM固定1379个输入token和64个新token,预热2批后测3批,保留NF4、FP16、SDPA和双重量化。
| 训练配置 | 未解锁张/秒 | 解锁张/秒 | 吞吐变化 |
|---|---|---|---|
| YOLOv8m,batch32、workers4 | 139.80 | 153.81 | +10.02% |
| YOLOv8l,batch16、workers4 | 85.51 | 96.03 | +12.30% |
| YOLOv8s,batch64、workers8 | 268.09 | 278.32 | +3.82% |
m和l模型终于表现出了比较明确的收益。三次独立进程的吞吐范围也没有交叠:m模型未解锁为139.55~139.88张/秒,解锁为152.14~155.14张/秒;l模型分别为83.01~87.13和95.49~96.57张/秒。
VLM仍然没有同样清晰的变化:
| VLM配置 | 未解锁总生成token/秒 | 解锁总生成token/秒 | 变化 |
|---|---|---|---|
| batch4 | 36.54 | 36.32 | -0.59% |
| batch8 | 65.73 | 68.76 | +4.60% |
batch8看起来快了4.6%,但未解锁的三进程范围为57.16~67.25token/秒,解锁为57.94~69.40token/秒,波动明显重叠。这个结果不足以宣称稳定加速。表中的总生成吞吐包含预填充开销,也不是只计解码阶段的速度。
这一轮30个正式案例全部完成。9对训练最终模型状态摘要相同,loss项最大差值为0,VLM对应的生成token摘要也一致。没有观察到GPU错误,但这仍是固定步数和固定生成量的短测,不是完整长训或长期稳定性验收。
两倍的局部能力,如何变成一成的收益
假设一个任务原来需要100秒,其中20秒能够被补丁加速。如果这20秒缩短到10秒,剩下80秒不动,总耗时就是90秒,吞吐提升约11%。这只是说明原理的例子,20%不是本次Profiler测出的占比。
这次YOLO的结果与这个道理一致:较大模型把更多工作压到了GPU侧,补丁收益更容易显现,但归一化、布局转换、优化器、数据准备和调度仍占时间。VLM受大量短内核和串行解码限制,提高部分矩阵指令的峰值吞吐,未必能缩短主要等待。
因此,“是不是模型或batch太小”是值得验证的方向,却不是完整答案。batch增大以后还得有足够的数据供给,实际内核也得用到受影响的计算路径。更大的模型、更满的显存,都不能单独证明补丁会更有效。
这次没有锁定CPU/GPU时钟,每轮前后对比只有一次启动状态配对,3次进程重复也不等于3次独立启动。YOLO测到的约10%~12%应理解为本机这些配置下的训练吞吐收益,不能直接换算成所有完整训练任务都会节省相同比例的时间。
最后还有一个比跑分快慢更实际的问题:它运行在驱动接管前的内核和固件路径上,出错可能让GPU甚至远程维护暂时不可用。首次尝试按项目要求安排了现场配合,之后普通远程重启也成功,但这不代表异常总能靠SSH恢复。原启动项和回退镜像因此一直保留着。
对这台4090而言,结论已经足够具体:特定矩阵指令接近翻倍,较大YOLO训练得到了一成左右的吞吐提升,现有量化VLM没有稳定收益。真正值得优先处理的瓶颈,有时是补丁能改变的速率限制,有时只是喂不饱显卡的DataLoader,或一次请求里十几万次细碎的调用。