想让模型跑得快,光盯着模型架构看没用

PromptCube 初级 1小时前 392 浏览 14 点赞 约 3 分钟

最近在看一个 PyTorch 和 Hugging Face 在班加罗尔搞的技术分享,虽然是线下活动,但聊的内容非常有参考价值。现在的 AI 圈子里,大多数人都在讨论怎么调 Prompt 或者怎么微调模型,但这次分享的重点完全在“基础设施”上。简单来说,就是一群搞底层的人在聊怎么让推理更高效、分布式训练怎么才不那么脆弱,以及怎么通过 Profiling 找出性能瓶颈。

想让模型跑得快,光盯着模型架构看没用

最让我觉得有启发的是 Aritra Roy Gosthipaty 讲的关于 PyTorch Profiling 的那部分。很多开发者在优化模型时有个误区,就是觉得速度慢一定是模型太重或者算子效率低,但实际上很多时候你处于一种 “overhead bound” 的状态——也就是说,GPU 算力根本没跑满,时间全浪费在 CPU 侧的调度和启动上了。如果你跑的小 batch 任务觉得慢,很可能不是模型的问题,而是 CPU 发指令给 GPU 的开销占了主导。

他在分享中演示了一套非常标准且可重复的性能分析工作流,这比盲目尝试各种优化技巧要有效得多。核心逻辑就是:不能量化的东西就无法优化。

具体的操作链路是这样的:首先用 torch.profiler.record_function 给代码中感兴趣的区域打标签,然后用 torch.profiler.profile 把执行过程包裹起来。最关键的一点是,他强调了必须使用 schedule(调度计划)来区分 wait(等待)、warmup(预热)和 active collection(正式采集)阶段。因为 GPU 在预热之前的数据是极其不准确的,如果不剔除预热阶段,导出的 trace 结果会产生严重的偏差。

想让模型跑得快,光盯着模型架构看没用

如果你也想尝试这种分析方法,基本的代码结构大概是这样:

import torch
from torch.profiler import profile, record_function, ProfilerActivity

# 定义一个简单的调度计划,避免预热数据干扰
# wait: 等待 1 次, warmup: 预热 1 次, active: 采集 2 次
my_schedule = torch.profiler.schedule(wait=1, warmup=1, active=2, repeat=1)

with profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA], 
    schedule=my_schedule, 
    on_trace_ready=torch.profiler.tensorboard_trace_handler("./log/res"),
    record_shapes=True, 
    with_stack=True
) as prof:
    for i in range(4):
        with record_function("model_inference"):
            # 这里放你的模型前向传播代码
            model(input_data)
        prof.step() # 必须调用 step 才能触发 schedule
想让模型跑得快,光盯着模型架构看没用

跑完之后,通过导出的 trace 文件,你可以清晰地看到 CPU 侧的启动开销和 GPU 侧实际执行 CUDA kernel 的时间分布。这种方法能让你一眼看出,到底是某个特定的算子慢,还是因为数据传输太频繁导致了 GPU 频繁空转。

除了 Profiling,这次活动还聊到了 SGLang 和 Transformers 的推理优化。现在的趋势是,推理引擎不再仅仅是简单的 Wrapper,而是开始深入到 Kernel 层的优化。很多关于 LLM 推理的突破,其实都来自于对 KV Cache 管理的优化以及对通信原语(communication primitives)的重新定义。

想让模型跑得快,光盯着模型架构看没用

我觉得这次分享传递了一个很明确的信号:AI 的竞争正在从“模型层”下沉到“系统层”。如果你只是调用 API,那你永远在消费别人的成果;但如果你能理解编译器路径、Kernel 库以及分布式系统的通信瓶颈,你才真正掌握了定义模型性能的话语权。

对于大多数开发者来说,不要在没跑 Profiler 之前就猜测哪里慢。先用 torch.profiler 把 CPU 开销和 GPU 实际执行时间分开,看看自己是不是掉进了 “overhead bound” 的坑里,这比尝试各种玄学的优化参数要高效得多。

pytorchCUDAHugging FaceSGLang

全部回复 (3)

脚本小子小柯 专家 1小时前

确实,之前死磕参数没用,最后发现是显存带宽卡住了。

0 回复
强迫症脚本小子 专家 1小时前

其实算子融合也很关键,之前优化过一次,延迟低了不少。

0 回复
程序员Tom 高级 1小时前

试过量化到int8,速度确实快了一大截,建议试试。

0 回复

发表回复

支持 Markdown 格式