最近在折腾用 Llama 2 7B 做微调,看到 PyTorch 2.0 的 torch.compile 吹得很厉害,说能白嫖 30%-50% 的加速。但我试了下在单卡 A100 上跑 LoRA,torch.compile(mode="reduce-overhead") 反而比原生 torch 慢了一截,而且第一次编译要等好久。我用的 deepspeed stage2 加 bf16,是不是大模型场景下编译加速不明显,还是我哪里配错了?大佬们有没有实际对比过训练吞吐的?另外,编译后的显存开销好像也变大了,这正常吗?真心求教,不想把时间浪费在玄学调优上。
PyTorch 2.0 编译模式在大模型训练中真的比原生快很多吗?
全部回复
共 175 条试过跟你一样的配置,reduce-overhead在大模型上确实容易负优化,换mode="max-autotune"或者直接关掉编译反而稳。
编译后显存涨正常,CUDA graph会占额外缓存,小batch下尤其不划算。
同感,LoRA场景下torch.compile收益确实不明显,我试过7B全参微调反而能快10%左右,但小模型加LoRA经常是负优化。显存变大也正常,编译会额外保存一些中间张量,尤其reduce-overhead模式更吃显存。
你deepspeed stage2和bf16叠加时,建议试试把compile放到stage2外面包一层,或者换mode="max-autotune"对比下,有时候默认模式不如手动指定算子融合策略。另外第一次编译那十几分钟别省,多跑几个step后看稳定吞吐。
其实很多人吹的30%-50%是纯推理场景,训练里能稳定吃到20%就不错了,而且跟模型结构、batch size关系很大。建议直接用原生+flash attention试试,可能比折腾编译省心。
小模型上compile收益明显,7B这规模确实容易负优化,deepspeed和编译叠加反而互相干扰。
显存变大正常,reduce-overhead会缓存额外buffer,建议试试mode=max-autotune再对比下。
我A100上试过类似的组合,reduce-overhead对LoRA这种小batch场景确实不友好,编译开销反而盖过了收益。建议试试mode="max-autotune"或者干脆default,另外把dynamo的graph break检查下,deepspeed的stage2和torch.compile经常有算子冲突。显存变大正常,编译会保留一些中间buffer,我这边大概多了5%-8%。吞吐对比的话,纯原生加flash attention和deepspeed优化好,其实跟compile差距很小,不值得为那点提升折腾。
LoRA微调本身可训练参数就少,计算密度低,torch.compile那套算子融合的收益基本被吃掉了,减速不奇怪。reduce-overhead模式主要针对小batch推理场景,训练用它反而容易踩坑,试试default或者max-autotune。显存涨是正常的,编译会缓存一些中间结果和额外kernel,deepspeed stage2下更明显。真想压吞吐的话建议先关掉compile跑个baseline,再单独测max-autotune,别一上来就reduce-overhead。
LoRA微调本来计算量就小,编译开销摊不平,慢很正常,全参训练才明显。
LoRA微调本来可训练参数就少,计算密度低,torch.compile那套算子融合的收益基本吃不到,反而图捕获和重编译的overhead占比被放大了。reduce-overhead模式主要靠CUDA Graph省kernel launch,你这场景launch本来就不是瓶颈,慢是正常的。显存涨是因为编译缓存和graph pool会额外占一块,7B配A100应该扛得住。建议试试mode="default"或者干脆别compile,LoRA下deepspeed的通信优化比这实在多了。
我这边7B全参用torch.compile确实有20%左右的吞吐提升,但LoRA场景下反而经常负优化,感觉跟参数更新量小、图break多有关。reduce-overhead那个模式主要省kernel launch开销,单卡A100跑大模型本来就不是瓶颈,编译后显存涨个一两G挺常见的,因为要存guard和额外buffer。你可以试试default模式对比下,或者干脆把compile只加在forward上,别整个step都包进去。
我微调7B时也踩过这坑,torch.compile在LoRA这种小参数量更新场景收益确实有限,尤其配了deepspeed之后图优化空间被切得比较碎。reduce-overhead模式主要针对推理小batch,训练里反而容易因为CUDA graph反复捕获拖慢速度。显存涨是正常的,编译会缓存额外kernel和中间状态,A100 80G还能扛但小卡就难受了。建议试试mode="max-autotune"配合fullgraph=False,或者干脆关掉编译,LoRA本身瓶颈常在数据加载和通信上。
我在A100上拿7B模型对比过,reduce-overhead主要是给推理小batch用的,训练场景反而容易踩坑。你试试默认mode或者max-autotune,但首次编译确实要等,LoRA本身可训练参数少,图优化收益本来就被摊薄了。显存涨是正常的,编译会缓存一些中间结果和CUDA graph,A100 80G还好,40G就得留心了。deepspeed stage2跟compile的兼容性也一般,建议先关掉deepspeed单独测一波吞吐再叠。
我之前在7B微调上也踩过这个坑,torch.compile在LoRA这种小参数量更新的场景收益确实很有限,反而编译开销和额外显存容易把优势吃掉。reduce-overhead模式主要是给推理或小batch反复执行同一图用的,训练时梯度图一直在变,它那套CUDA graph缓存基本发挥不出来。你可以试试default模式,再配合mode="max-autotune"看看,但别期待太高。我现在训练基本不开compile,省下来的时间够多跑好几轮实验了。
我也踩过这个坑,LoRA微调本身计算量小,torch.compile的kernel融合收益很有限,反而overhead占比更高了。reduce-overhead模式主要适合推理或者小batch场景,训练时用它确实容易负优化。deepspeed stage2跟torch.compile的兼容性也一般,经常会有图断裂导致反复编译。建议你先试试mode="default",再对比下steps/sec,显存涨是正常的,编译会缓存一些中间结果。
torch.compile 在大模型训练里确实不是无脑开就完事的,你遇到的这个情况我一点都不意外。LoRA 微调本身可训练参数就少,前向反向的计算图跟全量微调差别很大,reduce-overhead 这个模式主要是给推理或者小 batch 场景设计的,放到训练里反而容易因为 CUDA graph 捕获和显存池管理拖后腿。deepspeed stage2 会插入一堆通信和 hook,torch.compile 对这些动态行为的图捕获经常力不从心,编译出来的图碎得跟饺子馅似的,加速自然就没了。A100 单卡跑 7B LoRA,瓶颈很多时候在 kernel launch 和优化器更新上,原生 PyTorch 的 eager 模式已经够用了,编译带来的收益被额外开销吃掉很正常。显存变大也是老问题,编译缓存和 graph 的静态内存池会多占一块,尤其你 batch size 稍微大点就很明显。建议试试 mode="max-autotune" 但关掉 cudagraphs,或者干脆别 compile,把 flash attention 和 gradient checkpointing 调好,收益可能更实在。这玩意儿目前还是看场景吃饭,不是万能丹。
LoRA微调本来计算量就小,编译开销根本摊不平,慢很正常。大模型全参训练才可能看到收益。
学到了,感谢分享!