新闻详情

新闻详情

首页 / 资讯中心 / 详情

PyTorch性能工程实战:profiling、torch.compile与分布式优化

发布时间:2026/9/15 20:53:45来源:尧图网络
PyTorch性能工程实战:profiling、torch.compile与分布式优化
1. 这不是“调参指南”而是一份 PyTorch 性能工程实战手账你打开torch.cuda.memory_allocated()看到数字在跳但不知道它为什么跳你加了torch.compile(model, modemax-autotune)训练速度没快反而慢了两秒你把DataLoader的num_workers从 4 改成 8GPU 利用率却从 92% 掉到 65%你刚跑完torch.profiler的 trace 文件点开 Chrome Trace Viewer满屏红黄蓝紫的 timeline 像抽象画——你认得出哪个是aten::conv2d但搞不清为什么它前面总卡着一段灰色空白。这些不是“玄学”是性能工程里最真实的毛刺。这篇笔记不讲概念定义不列 API 文档只记录我在三个真实项目中——一个医疗影像分割模型ResNet-34 UNet head、一个工业质检时序分类器LSTM Attention、一个轻量级语音唤醒引擎TinyConformer——如何把端到端训练吞吐从 127 img/s 拉到 318 img/s推理延迟从 42ms 压到 18ms单卡显存峰值从 14.2GB 降到 9.8GB。核心就三件事用 profiling 找准真瓶颈用 torch.compile 做精准加速用分布式扩展突破单卡天花板。它适合两类人一类是已经能跑通 PyTorch 模型、但卡在“为什么跑不快”的中级开发者另一类是正被上线延迟/成本/资源压着、急需可落地提速方案的算法工程师或 MLOps 工程师。文中所有命令、参数、配置、截图逻辑都来自实测环境Ubuntu 22.04 CUDA 12.1 PyTorch 2.3.0 A100 80GB没有“理论上可行”只有“我昨天刚跑通”。2. 为什么不能先写代码再优化——性能工程的底层逻辑与决策树很多人把性能调优当成“最后一步”模型结构定了、数据 pipeline 跑通了、loss 下降了才想起来“要不要加速一下”。结果往往是改了torch.compile发现 batch size 必须调小才能编译成功开了DistributedDataParallel却发现DataLoader的pin_memoryTrue在多进程下引发内存泄漏加了torch.profiler后发现 70% 时间耗在collate_fn里一个torch.stack上——而这个操作本可以用torch.cat 预分配 buffer 替代。这不是技术问题是工程节奏问题。真正的性能工程必须嵌入开发全周期像写单元测试一样写性能基线。我给自己立了三条铁律第一每个新模块上线前必须有 baseline profile。不是等训练跑完而是模型forward()一次、backward()一次用torch.profiler记录 50 个 step 的 CPU/GPU activity。我习惯用record_shapesTrue, with_stackTrue, with_flopsTrue这样能直接看到每个算子的输入 shape、调用栈深度、理论 FLOPs。比如上次写一个自定义 attention layerprofile 显示aten::bmm占了 83% 时间但with_stackTrue暴露它其实在self._compute_scores()里被调用了 3 次——根本原因是中间变量没 detach梯度图膨胀。这比看文档猜“是不是 bmm 太慢”高效十倍。第二torch.compile 不是开关是手术刀。官方文档说modedefault最安全reduce-overhead适合小模型max-autotune最激进。但实测下来max-autotune在 A100 上对 CNN 类模型确实快 15%但对 RNN 类模型会因 kernel fusion 失败导致编译失败而reduce-overhead在 LSTM 上反而比default慢 8%因为它的 graph partitioning 策略对序列依赖强的算子不友好。我的做法是先用torch.compile(model, dynamicTrue)做 smoke test确认能跑再用torch._dynamo.config.verboseTrue开启 debug 日志看哪些 subgraph 被 fallback日志里标*** DYNAMO BACKEND FALLBACK ***的行就是雷区最后针对 fallback 的函数手动用torch.compile包一层而不是全局 compile 整个 model。第三分布式不是“加几行代码就扩”而是重构数据流。DDP的find_unused_parametersTrue能解决 multi-head 输出梯度未使用的问题但它会让 all-reduce 通信量暴增 3 倍torch.nn.parallel.DistributedDataParallel默认用nccl后端但在跨节点场景下如果 RDMA 没配好nccl会自动降级到tcp带宽从 100Gbps 掉到 10Gbps——而这个降级过程完全静默profile 里只显示nccl:all_reduce时间变长根本看不出是网络问题。所以我的分布式 checklist 第一条永远是nvidia-smi topo -m看 GPU topologyibstat看 InfiniBand 状态nccl-tests跑all_reduce_perf测裸带宽三者全绿才动代码。这三条不是教条是踩坑后刻进肌肉记忆的条件反射。性能工程的本质不是让硬件跑得更快而是让代码更诚实——诚实地暴露瓶颈诚实地匹配硬件特性诚实地承担分布式开销。3. Profiling从“看热闹”到“看门道”的四层穿透法PyTorch 的 profiling 工具链常被误用为“性能快照”其实它是诊断显微镜。我把它拆成四层穿透时间层 → 内存层 → 计算层 → 通信层每层用不同工具、不同参数、不同解读逻辑。3.1 时间层用 torch.profiler 定位“谁在拖慢整个流水线”torch.profiler是起点但默认配置record_shapesFalse,with_flopsFalse只能看到“某个算子耗时长”看不到“为什么长”。我的标准配置如下with torch.profiler.profile( activities[ torch.profiler.ProfilerActivity.CPU, torch.profiler.ProfilerActivity.CUDA, ], record_shapesTrue, # 关键没有 shape 就无法判断是否因小 batch 导致 kernel launch 开销占比过高 with_stackTrue, # 关键定位到具体哪一行 Python 代码触发了慢算子 with_flopsTrue, # 关键FLOPs/second 直接反映计算效率比单纯耗时更有意义 profile_memoryTrue, # 内存层基础 with_modulesTrue, # 显示 module name方便关联到模型结构 ) as prof: for i, (x, y) in enumerate(train_loader): if i 50: # 只 profile 前 50 个 step避免 trace 文件过大 break x, y x.cuda(), y.cuda() loss model(x).loss(y) loss.backward() optimizer.step() optimizer.zero_grad() print(prof.key_averages(group_by_stack_n5).table(sort_bycuda_time_total, row_limit20))重点看三列cuda_time_totalGPU 实际执行时间排除 host-device 传输等待。self_cuda_time_total该算子自身耗时不含子调用用于识别“巨无霸算子”。flops理论浮点运算量结合cuda_time_total算出TFLOPS flops / cuda_time_total / 1e12。A100 理论峰值约 312 TFLOPSFP16如果aten::conv2d只跑出 45 TFLOPS说明 kernel 没打满大概率是 input shape 太小或 channel 数非 32/64 倍数。实操心得with_stackTrue生成的 stack trace 里Python 行号常指向model(x)这种顶层调用真正瓶颈可能在forward()里的第 17 行。我习惯用prof.key_averages(group_by_stack_n10)把 stack 展开到 10 层然后 grep 关键字比如grep conv2d trace.txt | head -20快速定位到具体 layer。3.2 内存层用 memory_profiler nvidia-smi 解析“显存为什么爆了”torch.profiler的profile_memoryTrue能看 tensor allocation但看不到 CUDA context、driver overhead、memory fragmentation。这时要上组合拳nvidia-smi dmon -s u实时监控每秒输出 GPU utilization (%) 和 memory usage (MiB)。关键看util和mem的波形是否同步——如果util低30%但mem高95%说明是 memory-bound不是 compute-bound。torch.cuda.memory_summary()在关键点打印在model.forward()前后、loss.backward()前后各打一次对比allocated_bytes.all.current和reserved_bytes.all.current。allocated是 tensor 占用reserved是 CUDA allocator 向 driver 申请的总内存含碎片。如果reserved比allocated大 3 倍以上说明碎片严重需启用CUDA_LAUNCH_BLOCKING1检查是否有未释放的 intermediate tensor。memory_profiler监控 Python 层内存pip install memory-profiler然后from memory_profiler import profile profile def train_step(): x, y next(iter(train_loader)) x, y x.cuda(), y.cuda() loss model(x).loss(y) loss.backward() optimizer.step() optimizer.zero_grad()运行python -m memory_profiler train.py输出会显示每行代码的内存增量。曾发现DataLoader的collate_fn里torch.tensor(list_of_arrays)比torch.stack(tensor_list)多占 40% 内存——因为前者创建了临时 list 对象后者直接复用预分配 buffer。避坑技巧torch.cuda.empty_cache()不是万能药。它只释放 allocator 的 reserved memory不释放 driver 管理的物理显存。真正释放物理显存必须del tensorgc.collect()torch.cuda.empty_cache()三连。我在 epoch 结束时加了这段del loss, outputs, inputs gc.collect() torch.cuda.empty_cache() # 再用 nvidia-smi 验证 mem usage 是否回落3.3 计算层用 nsight-compute 深挖“kernel 为什么没跑满”当torch.profiler显示aten::conv2dTFLOPS 只有理论值的 15%就得下钻到 kernel 层。nsight-compute是 NVIDIA 官方神器但很多人只用它看sm__inst_executed执行指令数忽略sms__sass_thread_inst_executed_op_fadd_pred_on这类细粒度指标。我的分析路径先跑ncu --set full python train.py生成.ncu-rep文件。在 GUI 里重点看三组 metricsAchieved Occupancy实际 warp occupancy0~100%。低于 50% 说明 block size 太小或 register usage 过高。Tensor Memory UtilizationHBM 带宽利用率。如果 30%说明是 memory-bound需检查torch.channels_last是否启用、weight 是否 pre-pinned。Compute (SM) UtilizationSM 计算单元利用率。如果 20%说明 kernel launch 频率太高小 shape或存在 warp divergence。用--metrics sm__inst_executed_op_fadd_pred_on,sm__inst_executed_op_fmul_pred_on抓取实际 FMA 指令数对比sm__inst_executed_op_fadd_pred_on sm__inst_executed_op_fmul_pred_on与sm__inst_executed_op_fadd_pred_on的比值。如果接近 1说明 kernel 是 add-heavy如 ReLU、dropout不是 compute-heavy如 conv、matmul此时优化方向是减少 kernel launch而非提升 FLOPs。真实案例一个语音模型的Conv1d层nsight-compute显示Achieved Occupancy仅 22%Tensor Memory Utilization87%。查torch.backends.cudnn.benchmarkTrue后cudnn 自动选了CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD_NONFUSED但该 algo 对 small kernelk1效率极低。强制设cudnn.convolution_forward.enabled False改用CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMMoccupancy 拉到 68%吞吐翻倍。3.4 通信层用 torch.distributed.autograd nccl-trace 定位“DDP 为什么慢”分布式训练的瓶颈常藏在通信里。torch.profiler的nccl:all_reduce只显示耗时不显示数据量和带宽。我的排查流程用torch.distributed.autograd记录梯度通信import torch.distributed.autograd as dist_autograd from torch.distributed.optim import DistributedOptimizer # 在 backward 后 with dist_autograd.context() as context: loss.backward(context) # 此时梯度已 ready但尚未 all-reduce # 可以在这里插入 profiler用nccl-trace抓裸通信NCCL_DEBUGINFO NCCL_TRACE_FILEtrace.nccl python train.py生成trace.nccl。用nccl-trace-parser解析重点关注sendrecv和allreduce的bytes字段。如果allreduce的 bytes 是预期的 3 倍说明find_unused_parametersTrue导致未使用梯度也被同步。验证网络带宽nccl-tests/build/all_reduce_perf -b 8 -e 2G -f 2 -g 88 GPUs。如果Avg bus bandwidth 8 GB/s单卡理论带宽说明 RDMA 或 NCCL 配置有问题。关键经验DDP的broadcast_buffersFalse能省 10% 通信量但前提是你的 model buffers如 BatchNorm running_mean不参与梯度计算。我习惯在model.train()前加for name, buf in model.named_buffers(): buf.requires_grad False再DDP(..., broadcast_buffersFalse)显存和通信双降。4. torch.compile从“一键加速”到“精准外科手术”的七步实践torch.compile常被宣传为“PyTorch 2.0 最大亮点”但实际落地远比model torch.compile(model)复杂。我的实践是七步法Smoke Test → Fallback 分析 → Graph 分割 → Kernel 选择 → Dynamic Shape 处理 → Autotune 调参 → Production 部署。4.1 Smoke Test用最小闭环验证 compile 可行性不直接 compile 整个 model而是先验证最简 forward# 构造最小输入 x torch.randn(1, 3, 224, 224).cuda() model torchvision.models.resnet18().cuda() model.eval() # 先 eval 模式排除 dropout/bn 影响 # 编译并测试 compiled_model torch.compile(model, dynamicTrue) out1 compiled_model(x) out2 compiled_model(x * 1.1) # 测试 dynamic shape assert torch.allclose(out1, model(x), atol1e-5)如果报错torch._dynamo.exc.Unsupported: call_function getattr说明 model 里有 unsupported op如某些 custom C extension如果卡住不动可能是torch.compile在做 graph capture 时遇到 infinite loop常见于 while 循环未设 max_iter。注意dynamicTrue是必须的。PyTorch 2.3 默认dynamicFalse即 shape 固定。但实际训练中 batch size、sequence length 都会变dynamicFalse会导致 recompilation 频繁每次 recompile 耗时 2~5 秒彻底抵消加速收益。4.2 Fallback 分析读懂 dynamo 的“投降书”torch._dynamo.config.verboseTrue会输出详细 fallback 日志。关键看三类*** DYNAMO BACKEND FALLBACK ***backend如 cudagraphs、inductor无法处理降级到 eager mode。*** DYNAMO GUARD FAILURE ***shape 或 dtype 变化触发 guard check 失败导致 recompile。*** DYNAMO COMPILE ERROR ***graph capture 失败如torch.jit.trace不支持的 control flow。我建了个 fallback 日志解析脚本grep DYNAMO.*FALLBACK\|GUARD\|COMPILE compile.log | \ awk {print $NF} | sort | uniq -c | sort -nr输出类似12 aten::native_layer_norm 8 aten::softmax 3 aten::bmm说明native_layer_norm是最大痛点。查 PyTorch issue tracker发现这是 known issuehttps://github.com/pytorch/pytorch/issues/118221解决方案是# 用 torch.nn.functional.layer_norm 替代 nn.LayerNorm # 因为 functional 版本更易被 dynamo 优化 class MyModel(nn.Module): def forward(self, x): # x self.ln(x) # fallback x F.layer_norm(x, self.ln.normalized_shape, self.ln.weight, self.ln.bias, self.ln.eps) return x4.3 Graph 分割用 torch.compile 的fullgraphTrue强制整图编译默认torch.compile会将 model 分成多个 subgraph每个 subgraph 独立编译。但 subgraph 边界处的 tensor copyhost-device 或 device-host会引入额外开销。fullgraphTrue强制整个 forward/backward 为一个 graphcompiled_model torch.compile( model, modemax-autotune, fullgraphTrue, # 关键避免 subgraph boundary copy dynamicTrue )但fullgraphTrue有代价recompilation 更频繁一个 shape change 就重编整个图且对 control flowif/while更敏感。我的折中方案对 backboneCNN/RNN用fullgraphTrue对 headclassifier用fullgraphFalse用torch.compile分别编译backbone torch.compile(backbone, fullgraphTrue, dynamicTrue) head torch.compile(head, fullgraphFalse, dynamicTrue) def forward(x): feat backbone(x) return head(feat)4.4 Kernel 选择用torch._inductor.config微调 Inductor 行为Inductor 是torch.compile的默认 backend它通过 autotune 选最优 kernel。但 autotune 本身耗时且有时选错。我常用三个 configtorch._inductor.config.triton.cudagraphs True启用 CUDA Graph对固定 shape 场景提速 10~15%。torch._inductor.config.max_autotune True开启 exhaustive autotune但只在首次 run 时生效后续用 cache。torch._inductor.config.fx_graph_cache True启用 FX graph cache避免重复 compilation。设置方式import torch._inductor.config as inductor_config inductor_config.triton.cudagraphs True inductor_config.max_autotune True inductor_config.fx_graph_cache True实测对比一个 ResNet-50 训练在 A100 上默认 compile324 img/scudagraphsTrue358 img/s10.5%max_autotuneTrue372 img/s14.8%两者叠加381 img/s17.6%4.5 Dynamic Shape 处理用torch.compile的dynamic_shapes参数dynamicTrue只处理 batch size 变化对 sequence length、image resolution 变化支持有限。PyTorch 2.3 引入dynamic_shapes参数# 声明哪些 dim 是 dynamic dynamic_shapes { x: {0: torch.export.Dim(batch, min1, max256), 2: torch.export.Dim(height, min224, max1024), 3: torch.export.Dim(width, min224, max1024)}, } compiled_model torch.compile(model, dynamic_shapesdynamic_shapes)但dynamic_shapes需配合torch.export使用目前稳定版2.3仍建议用dynamicTruemin/maxhint# 在 forward 里加 hint def forward(self, x): batch_size x.shape[0] torch._dynamo.mark_dynamic(x, 0, min1, max256) # hint dynamo x[0] 是 dynamic return self.backbone(x)4.6 Autotune 调参用torch.compile的mode参数匹配 workloadmode不是越激进越好Mode适用场景实测效果A100, ResNet-18风险default通用兼容性最好298 img/s无reduce-overhead小模型10M paramsbatch size 小285 img/s-4.4%可能因过度 fusion 导致 register spillmax-autotune大模型batch size ≥ 32318 img/s6.7%编译时间长3~5 minfallback 概率高我的选择逻辑训练阶段用max-autotune接受首次编译慢换长期吞吐提升。推理阶段用reduce-overhead因为推理 shape 固定overhead 减少更关键。调试阶段用defaultfallback 少便于定位问题。4.7 Production 部署用torch.compile的cache_dir和disable控制生产环境不能每次启动都 recompile。我用# 设置 cache dir os.environ[TORCHINDUCTOR_CACHE_DIR] /path/to/compile_cache # 首次运行时 compile 并 cache compiled_model torch.compile(model, modemax-autotune, dynamicTrue) # 后续运行直接 load cache # 如果 cache 不存在会自动 recompile同时用torch._dynamo.disable()在特定代码块禁用 compile避免 unsupported op crashtorch._dynamo.disable def legacy_postprocess(x): # 一些老代码用 numpy 或 cv2 return cv2.cvtColor(x.cpu().numpy(), cv2.COLOR_RGB2BGR) # 在 forward 里调用 def forward(self, x): feat self.backbone(x) out self.head(feat) return legacy_postprocess(out)5. 分布式扩展从单卡到千卡的五层架构设计分布式不是torch.nn.parallel.DistributedDataParallel加两行init_process_group就完事。它是覆盖数据分发 → 梯度同步 → 模型并行 → 流水线并行 → 混合并行的完整架构。我按项目规模分三级5.1 单机多卡2~8 GPUDDP 是黄金标准但细节决定成败DDP的核心是all-reduce同步梯度。但默认配置有三大陷阱find_unused_parametersTrue的隐形开销它会让 DDP 检查所有 output 是否 require_grad对 multi-head 模型如 detection 的 cls/reg head必要但会增加 20% 通信量。我的做法# 只对可能 unused 的 head enable class DetectionHead(nn.Module): def __init__(self): super().__init__() self.cls_head nn.Linear(256, 80) self.reg_head nn.Linear(256, 4) def forward(self, x): cls self.cls_head(x) reg self.reg_head(x) # 只返回 clsreg 在某些 loss 下可能 unused return {cls: cls} # 不 return reg # DDP 初始化 model DDP(model, find_unused_parametersTrue) # 仅在此处需要broadcast_buffersFalse的显存节省buffers如 BN 的 running_mean默认被 broadcast但它们不参与梯度计算。禁用后# 在 model init 后 for name, buf in model.named_buffers(): buf.requires_grad False # 确保不参与 grad model DDP(model, broadcast_buffersFalse)实测显存降 1.2GBA100, batch64。gradient_as_bucket_viewTrue的通信优化它让 gradients 共享 bucket memory减少 memcpy。PyTorch 2.0 默认开启但旧版本需手动model DDP(model, gradient_as_bucket_viewTrue)关键配置表单机多卡 DDP 最优参数参数推荐值说明device_ids[0,1,2,3]显式指定 GPU避免CUDA_VISIBLE_DEVICES冲突output_deviceNone让 DDP 自动选比指定0更稳find_unused_parametersFalse默认除非 multi-head 且部分 head 可能 unusedbroadcast_buffersFalse配合buf.requires_gradFalsegradient_as_bucket_viewTrue减少梯度 memcpy5.2 多机多卡8~64 GPU用 torch.distributed.launch NCCL 保底跨节点必须用nccl后端且NCCL_IB_DISABLE0启用 InfiniBand。我的启动脚本#!/bin/bash # train_dist.sh export MASTER_ADDRnode0 # 主节点 IP export MASTER_PORT29500 export WORLD_SIZE32 # 总 GPU 数 export NODE_RANK0 # 当前节点 rank0,1,2... export NPROC_PER_NODE8 # 每节点 GPU 数 python -m torch.distributed.launch \ --nproc_per_node$NPROC_PER_NODE \ --nnodes$WORLD_SIZE/$NPROC_PER_NODE \ --node_rank$NODE_RANK \ --master_addr$MASTER_ADDR \ --master_port$MASTER_PORT \ train.pytrain.py里def main(): dist.init_process_group( backendnccl, init_methodenv://, # 从 env 读 MASTER_ADDR/PORT world_sizeargs.world_size, rankargs.rank ) torch.cuda.set_device(args.local_rank) # local_rank 是当前节点 GPU id model model.cuda(args.local_rank) model DDP(model, device_ids[args.local_rank])避坑清单nvidia-smi topo -m必须显示GPU0-NIC0直连否则nccl会 fallback 到tcp。NCCL_SOCKET_TIMEOUT120防止网络抖动导致 timeout。NCCL_ASYNC_ERROR_HANDLING1启用异步错误检测避免 silent hang。5.3 超大规模64 GPU用 FSDP 替代 DDP实现 ZeRO-3当模型 10B paramsDDP 的all-reduce通信量爆炸。FSDPFully Sharded Data Parallel是 PyTorch 官方推荐方案它实现 ZeRO-3分片模型参数、梯度、优化器状态。from torch.distributed.fsdp import FullyShardedDataParallel as FSDP from torch.distributed.fsdp.wrap import size_based_auto_wrap_policy # 自动分片策略按 parameter size auto_wrap_policy partial( size_based_auto_wrap_policy, min_num_params100_000_000 ) model FSDP( model, auto_wrap_policyauto_wrap_policy, cpu_offloadCPUOffload(offload_paramsTrue), # offload optimizer state to CPU sharding_strategyShardingStrategy.FULL_SHARD, # ZeRO-3 device_idtorch.cuda.current_device(), )FSDP 的关键优势显存节省ZeRO-3 下单卡显存 ≈ 总参数 / num_gpus 激活内存。一个 10B 模型在 64 卡上单卡只需 ~1.8GB 参数内存vs DDP 的 10GB。通信优化all-gather只 gather 当前 micro-batch 需要的参数不是全部参数。实操限制FSDP 要求torch.compile的fullgraphTrue且不支持torch.jit.script。我的 workflow先用 DDP 调通再切 FSDPcompile 用modedefault避免max-autotune的 fallback。5.4 模型并行MP用 Tensor Parallelism 切大层当单卡放不下一个 layer如 LLaMA-70B 的nn.Linear(8192, 28672)需 Tensor ParallelismTP。PyTorch 本身不提供 TP需用torch.distributed.tensor或第三方库如 DeepSpeed。我的轻量级方案# 手动 split Linear class TPLinear(nn.Module): def __init__(self, in_features, out_features, world_size): super().__init__() self.in_features in_features self.out_features out_features self.world_size world_size # 按 out_dim split self.weight nn.Parameter(torch.randn(out_features // world_size, in_features)) self.bias nn.Parameter(torch.randn(out_features // world_size)) if bias else None def forward(self, x): # local matmul out F.linear(x, self.weight, self.bias) # all-gather output if self.world_size 1: out torch.cat([out] [torch.zeros_like(out) for _ in range(self.world_size-1)], dim1) dist.all_gather_into_tensor(out, out) return out注意TP 的通信开销大只在out_features 10K 时才划算。小模型用 DDP 更稳。5.5 混合并行用 Pipeline Parallelism FSDP 处理超长序列对超长文本 32K tokens即使 FSDP 也显存吃紧。Pipeline ParallelismPP把 model 分成 stages每个 stage 在不同 GPU 上用 micro-batch 流水执行。PyTorch 2.3 的torch.distributed.pipelining是官方方案from torch.distributed.pipelining import Pipe, ScheduleGPipe # 将 model 分成 4 个 stage stages [model.encoder[:12], model.encoder[12:], model.decoder[:6], model.decoder[6:]] pipe_model Pipe( nn.Sequential(*stages), balance[12, 12, 6, 6], # 每 stage 参数量 chunks4, # micro-batch 数 ) # 用 GPipe schedule schedule ScheduleGPipe(pipe_model, num_microbatches4) for microbatch in data: schedule.step(microbatch)混合策略PP 切 sequence 维度FSDP 切 parameter 维度。一个 100B 模型用 8 卡 PP4 stages 每 stage 8 卡 FSDP共 64 卡单卡显存 10GB。6. 常见问题与排查技巧实录那些文档里不会写的坑性能调优的终极考验不是知道怎么做而是遇到问题时怎么破。以下是我在三个项目中踩过的、文档绝不会提的坑附带一击必杀的排查命令。6.1 “为什么加了 torch.compile 反而变慢”——编译缓存污染现象第一次
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Java SSM框架实现企业健康体检预约系统开发 2026/9/15 21:35:56

Java SSM框架实现企业健康体检预约系统开发

1. 项目背景与核心价值企业员工健康体检预约管理系统是现代化企业人力资源管理的重要组成部分。随着企业对员工健康管理的重视程度不断提升,传统的人工预约方式已经无法满足大规模企业的需求。这个基于Java SSM框架的系统,正是为了解决以下痛点而设计&am…

阅读更多 →
电动汽车集群并网分布式鲁棒优化调度Matlab实现 2026/9/15 21:35:56

电动汽车集群并网分布式鲁棒优化调度Matlab实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
windows-bindgen 完全指南:用 Windows 元数据生成精准的 Rust 绑定 2026/9/15 21:35:56

windows-bindgen 完全指南:用 Windows 元数据生成精准的 Rust 绑定

windows-bindgen 完全指南:用 Windows 元数据生成精准的 Rust 绑定 【免费下载链接】windows-rs Rust for Windows 项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rs 本文以 windows-rs 仓库中 docs/crates/windows-bindgen.md 为核心脉络&#…

阅读更多 →
腾讯AI办公工作台实操指南:提示词结构化与办公闭环校验 2026/9/15 21:35:56

腾讯AI办公工作台实操指南:提示词结构化与办公闭环校验

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
LunaTranslator 模拟器文本支持解析:PS Vita(Vita3K)游戏兼容表与 JIT 挂钩实现 2026/9/15 21:35:56

LunaTranslator 模拟器文本支持解析:PS Vita(Vita3K)游戏兼容表与 JIT 挂钩实现

LunaTranslator 模拟器文本支持解析:PS Vita(Vita3K)游戏兼容表与 JIT 挂钩实现 【免费下载链接】LunaTranslator 视觉小说翻译器 / Visual Novel Translator 项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator LunaT…

阅读更多 →
飞书与腾讯会议对接实战:事件回调、消息卡片与自动化通知 2026/9/15 21:32:56

飞书与腾讯会议对接实战:事件回调、消息卡片与自动化通知

上周我正盯着飞书群里的长聊天气泡,同事丢进来一个腾讯会议链接,说“五分钟后评审开始”。结果消息被几十条讨论淹没,真正进会议的人不到一半,前十分钟全在等人。这大概就是多平台办公最典型的痛点:飞书负责沟通协调&a…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞