Home AI Infra 面试题(十):框架运行时与底层契约
Post
Cancel

AI Infra 面试题(十):框架运行时与底层契约

本文是AI Infra 面试题系列的 Level 10,覆盖 Q116-Q145。重点是Process group、stream、FSDP 状态机、KV 抢占和 kernel 资源证据。

上一篇:工程实现与实验深挖 · 系列总索引


11. Level 10:框架运行时与底层契约

这一层不再满足于“知道某框架用了哪个 collective”。回答必须落到 communicator、rank、sequence、stream、内存生命周期、调度状态机和 profiler 证据。每题都可以沿“为什么没有报错”“哪个 rank 先异常”“哪一个指标能证伪”继续追问。

Q116. 如何从 TP=2, PP=2, DP=2 推导每个 rank 的坐标和三类 group?

高分回答要点

  • 先声明 rank layout。本实验 tp_local 使用 rank=((dp*PP)+pp)*TP+tp,所以 rank 0-7 坐标依次为 (dp,pp,tp),TP 是最内层连续维度。
  • 固定另外两维枚举 TP 得到 (0,1),(2,3),(4,5),(6,7);固定 DP/TP 枚举 PP 得到 (0,2),(1,3),(4,6),(5,7);固定 PP/TP 枚举 DP 得到 (0,4),(1,5),(2,6),(3,7)
  • 必须校验 TP*PP*DP=world_size、每个 rank 在每一维恰好属于一个 group、group 无重复 rank,并给 planner 确定性排序。
  • group 逻辑正确不代表 placement 最优;还要把 rank 映射到 PCIe/NUMA/NIC 拓扑,按通信频率和关键路径计算成本。

追问:若 world size 不能整除三维乘积怎么办?生产 planner 应拒绝非法配置,或明确引入 standby/replica 维,不能悄悄遗漏 rank。

Q117. 为什么通常优先把 TP group 放在最快链路?本机证据是什么?

高分回答要点

  • TP collective 位于每层 forward/backward 关键路径,调用频率通常远高于每 step 一次的 DP gradient sync;PP P2P 又可能随 schedule 与 compute 交叠。
  • 本实验每 phase 64 MiB,TP 做 4 次 AllReduce。TP 用 PIX 时 25.55 ms;换到 SYS pair 后 77.92 ms,慢 3.05x,串行总工作负载慢 1.62x。
  • placement 目标不能只最小化单次 collective latency,应使用 frequency x bytes x exposed_fraction,再考虑共享 PCIe root/NIC contention。
  • 在 NVSwitch 节点、跨节点 TP 或大 EP All-to-All 中优先级可能改变,必须按真实通信图重算。

追问:为什么不是永远把 DP 放最慢链路?DP bucket 也可能很大且 exposed;当 PP/TP 有更好 overlap、DP world size 很大时,DP 可能成为主瓶颈。

Q118. 为什么两种 mapping 的三类 collective 并发时间几乎相同?

高分回答要点

  • tp_localtp_cross 只是把 TP/PP/DP 标签在 PIX/PHB/SYS 三类 pair 间置换;一次三类各一个并发时,物理流量集合基本相同。
  • 因此两者分别是 37.46 与 37.42 ms,不能据此说 mapping 无影响。真实训练中三类通信次数、bytes、依赖点和可重叠窗口并不相同。
  • 并发 wall time 也不是三个 phase 时间的最小值;共享 PCIe/CPU root、NCCL stream 排队和最慢 peer 都会影响 critical path。
  • 正确实验需要构造与真实 schedule 接近的调用频率,记录每个 communicator 的 interval 和依赖,而不是只做对称的一次并发。

陷阱:只比较 aggregate bandwidth 会丢失 logical critical path。面试时应主动解释“同物理流量 multiset”这个控制变量。

Q119. new_group() 为什么要求所有进程按一致顺序创建 group?

高分回答要点

  • group 创建涉及全局 rendezvous 和 communicator 唯一标识分配;即使某 rank 不属于目标 group,也应进入调用并按同一全局顺序执行。
  • 若不同 rank 用本地条件分支创建不同顺序,可能让 communicator identity 不一致,表现为初始化 hang、后续 collective 匹配错误或难以复现的并发问题。
  • 本实验先生成 canonical TP、PP、DP group 列表,再让所有 8 rank 完整遍历,只有返回 handle 的使用按 membership 决定。
  • 多线程创建或多个 overlapping process group 并发 collective 时,还要保证全局一致的执行顺序;业务层 mutex 只能解决本进程线程竞争,不能自动解决跨 rank 顺序。

现场题:给一段 if rank in ranks: new_group(ranks) 的代码,要求指出为什么危险,并改成所有 rank 都调用、成员只保存 handle。

Q120. 为什么 collective 调用顺序错配可能静默错误,而不一定 hang?

高分回答要点

  • communicator 按 sequence 匹配 collective,不知道 Python tensor 叫 A 还是 B;只要 op、shape、dtype 等兼容,两侧第 N 次调用就会彼此配对。
  • 本实验 ordered 期望 rank 0 得到 A=2001,B=4001;rank 1 反转顺序后两次调用都完成,却得到 A=3001,B=3001
  • 这比 hang 更危险,因为 timeout、HTTP 状态和 loss_is_finite 都可能正常;需要 logical checksum、sequence logging 或框架层 collective fingerprint。
  • 根因定位应比较各 rank 的 group id、sequence number、op、numel、dtype、调用栈和 logical step,而不是先调大 timeout。

追问:为什么测试必须让 A/B shape 相同?这是为了隔离“逻辑身份错配”,避免 shape mismatch 先触发显式错误。

Q121. 如果错配 collective 的 shape 或 op 不同,系统会怎样?

高分回答要点

  • 可能在 PyTorch/NCCL 参数检查阶段报 mismatch,可能某些 rank 等待超时,也可能因不同 count 导致未定义结果;具体表现取决于 backend、debug mode 和调用组合。
  • 不应把“会 hang”背成唯一答案。先说明兼容错配可静默损坏,不兼容错配更容易显式失败,但仍需以日志为准。
  • 开启 distributed debug/detail、NCCL debug 和 flight recorder,收集 sequence/fingerprint;在最小 world size 上缩小到第一个分歧调用。
  • 修复应回到控制流一致性:相同数据依赖、异常/empty batch 分支、gradient hook 顺序和 communicator 使用,而不是依赖 watchdog 兜底。

工程追问:某 rank 因 NaN 跳过 backward,其他 rank 继续 AllReduce,会发生什么?应先全局同步 skip 决策,不能让 rank-local 分支改变 collective 序列。

Q122. async_op=True 返回后,collective 到底完成了吗?

高分回答要点

  • 返回的是 Work handle,通常只表示操作已排入 backend/stream,不表示 GPU 数据可被任意 stream、CPU 或下一个 communicator 安全消费。
  • work.wait()、CUDA event/stream wait、torch.cuda.synchronize() 和跨 rank barrier 的作用不同;应按数据依赖建立最小必要同步。
  • Work 过早丢失、输出 tensor 被复用、默认 stream 未等待通信 stream,可能造成竞态;过度全局同步又会消灭 overlap。
  • benchmark 必须把要测的异步工作真正包含进计时窗口,退出前必须保证所有 peer 的 GPU work 与 communicator 生命周期闭环。

追问:为什么 barrier() 不能自动替代所有 stream dependency?它解决进程组同步,不等价于为任意用户 CUDA stream 上的数据读写建立正确 event 依赖。

Q123. FSDP smoke run 已写出正确 JSON,为什么退出时仍会有 NCCL proxy Close error?

高分回答要点

  • 结果正确只证明主训练路径完成,不证明最后一个 default-group GPU collective 已在所有 rank/stream 上完成,也不证明 peer 同时进入 communicator 销毁。
  • 本实验末尾收集结果后,非 rank 0 可能更早 destroy_process_group(),导致代理连接关闭时仍有 peer work/lifecycle 未闭环。
  • 修复为结果写出后 torch.cuda.synchronize(),再执行带 device_ids 的最终 barrier,最后所有 rank 统一 destroy;复跑日志干净。
  • 生产 runner 还要 wait 子进程、检查退出码和日志,不可只凭 artifact 存在判定 job 成功。

4 分答案特征:能区分 host API return、GPU completion、peer completion、barrier 和 communicator teardown 五个时刻。

Q124. 多个 process group 并发 collective 时,为什么 stream 顺序也属于正确性协议?

高分回答要点

  • 每个 communicator 可能使用独立 NCCL stream;同一 rank 的 Python 发起顺序、CUDA stream dependency 与其他 rank 的顺序必须形成一致的 happens-before。
  • 跨 communicator 没有天然全局序列。若 overlapping groups 的 rank 以不同顺序发起 blocking collective,可能形成循环等待;async 发起则可能暴露 tensor 生命周期竞态。
  • 应定义 deterministic schedule,用 event 连接 producer/collective/consumer,保留 Work,并在日志记录 communicator id 和 logical sequence。
  • performance 上要区分“允许并发”与“实际重叠”;共享 PCIe 链路可能让并发更慢,应从 trace interval 和端到端 critical path验证。

追问:为什么单 rank trace 不足以证明无死锁风险?死锁和最慢 peer 依赖跨 rank 相对顺序,需要分布式对齐日志或多 rank trace。

Q125. 你会怎样实现一个 topology-aware rank planner 的成本函数?

高分回答要点

  • 输入包含 GPU-GPU/NIC 带宽与延迟矩阵、NUMA、故障域,以及每类 edge 的 bytes、频率、collective 算法和 exposed fraction。
  • 目标可近似为关键路径通信成本加共享链路 contention penalty,再加跨节点/故障域约束;TP、PP、DP、EP 不能用同一个常数权重。
  • 先用启发式把高频紧耦合 group 放局部,再局部搜索/模拟;输出必须 deterministic,并附合法性和预估误差。
  • 用本机 tp_local/tp_cross 做回归 oracle:planner 至少应偏好 PIX TP,并预测 SYS TP 显著更慢;再用真实 run 校准模型。

边界:collective microbenchmark 是链路先验,不包含完整 compute overlap 和多流竞争,planner 必须持续用运行 telemetry 校准。

Q126. FSDP FULL_SHARD 的一个 unit 在一次 iteration 中经历哪些状态?

高分回答要点

  • 稳态存 sharded parameter;forward 前 AllGather 得到完整参数,执行计算,按 reshard policy 释放/重新分片。
  • backward 需要参数时可能再次 AllGather,计算参数梯度后 ReduceScatter,把完整 gradient 归约并只保留本 rank shard。
  • optimizer 更新本地 shard;临时 full parameter、prefetched next unit、gradient 和 allocator reserved 决定峰值,不是简单 参数/world_size
  • root 与 nested unit 的 forward/backward hook 顺序、prefetch policy 和 use_orig_params 会改变具体事件数与驻留窗口。

追问:为什么 AllGather 与 ReduceScatter bytes 相同也不代表耗时相同?算法、链路方向、并发 peer wait、overlap 窗口和 kernel protocol 都可能不同。

Q127. 13 个 FSDP unit 为什么 trace 中是 25 次 AllGather 和 13 次 ReduceScatter?

高分回答要点

  • 本模型 auto-wrap 12 个 GPTBlock,外层 root 还管理 embedding/head,共 13 units。
  • trace 观察到 forward 路径 13 次参数 AllGather;backward 中 12 个已 reshard block 再聚合参数,所以总 AllGather 为 13+12=25
  • 每个 unit 的 gradient 最终做一次 ReduceScatter,因此是 13 次。root-only wrap 则只有 1 次 AllGather/1 次 ReduceScatter。
  • 这是当前 graph、wrap policy 和版本的观测,不是 FSDP 永恒公式;activation checkpoint、no-reshard、shared params 或 FSDP2 都可能改变计数。

现场验证:要求从 Chrome trace 按 kernel name 分类,并把事件顺序映射回 module pre/post-forward/backward hook。

Q128. BACKWARD_PREBACKWARD_POST 和 NONE 的差异如何从 trace 证明?

高分回答要点

  • PRE 在当前 unit backward compute 期间预取下一个 unit 参数,目标是让下一次 AllGather 与 compute 重叠;POST 等当前 compute 后再发,NONE 不主动预取。
  • block+PRE 的 NCCL union 85.53 ms,与 POST/NONE 近似,但 overlap 13.08%、exposed 74.34 ms;POST/NONE 本 trace overlap 为 0。
  • 稳态吞吐 PRE 比 POST 高 8.8%、比 NONE 高 5.9%,支持“重叠而非通信字节减少”的解释。
  • 不能只看 profiler step wall time,因为 instrumentation overhead 很大;绝对吞吐使用非 profiler 三次重复,trace 用于事件结构。

追问:PRE 为什么可能更占显存?被预取 unit 的 full params 与当前 unit 的 params/grad/activation 同时驻留,扩大 live set。

Q129. limit_all_gathers 限制的是什么?为什么关闭后可能略快但更占 reserved memory?

高分回答要点

  • 它是 host-side rate limiter,限制过多 AllGather 提前发出导致 full-parameter allocation 堆积;不是减少模型所需的逻辑 AllGather 次数。
  • 本实验关闭后 25/13 次计数不变,吞吐提高 2.5%,reserved peak 从 1.174 增到 1.269 GiB,约 8.1%。
  • 小模型/短 run 上调度更激进可能略快;大模型接近容量边界时,额外峰值可能直接 OOM,trade-off 完全不同。
  • 观测要同时看 allocated、reserved、inactive split、cudaMalloc retry/OOM 和 timeline 中 in-flight AllGather,不能只看 nvidia-smi

追问:为什么 allocated 不变而 reserved 增加?caching allocator 保留了更大的 segment/high-watermark;reserved 不是当前活跃 tensor bytes。

Q130. root wrap 为什么更快却更占显存?什么时候仍会选 block wrap?

高分回答要点

  • root wrap 每 step 只有 1 次 AllGather/1 次 ReduceScatter,launch 和 communicator 调度更少;本机 26.1k tok/s,是 block+PRE 的 1.24x。
  • 代价是整模型 full params 的驻留窗口更大,allocated peak 0.981 GiB,是 block+PRE 的 1.82x;模型放大后可能不可行。
  • block wrap 让 full params 逐层 materialize/reshard,降低峰值并提供 prefetch overlap,但增加 collective 数和小消息/launch 开销。
  • 选择依据是容量硬约束、unit 大小、计算窗口、链路、prefetch 峰值和吞吐,不是“越细分片越好”。

设计追问:应按 Transformer block、若干 block 一组还是 size-based wrap?做候选 unit 大小 sweep,联合看峰值、collective size distribution 与 exposed time。

Q131. 怎样正确测 FSDP 峰值显存并解释 allocated/reserved?

高分回答要点

  • 在初始化、warmup 后明确 reset peak,计量窗口结束同步 GPU,再读取每 rank max_memory_allocated/reserved,最后取 max rank。
  • allocated 是活跃 tensor allocation 高水位;reserved 是 caching allocator 向 CUDA 保留的 segment 高水位,两者都不含全部 driver/context/NCCL 外部内存。
  • 模型初始化、sync_module_states、optimizer state 首次 materialization 和 profiler buffer 是否在窗口内,会显著影响口径。
  • 生产 OOM 调试还需 memory snapshot、allocation stack、fragmentation、non-releasable memory 和瞬态 rank skew。

陷阱:把 nvidia-smi used 减去模型参数当 activation,或把 rank 0 峰值当全局峰值,均不可靠。

Q132. use_orig_params=True 改变了什么?为什么 optimizer 构造顺序重要?

高分回答要点

  • 它向用户暴露原始 parameter 对象视图,支持更灵活的 per-parameter hyperparameter、冻结和某些编译路径;底层仍由 FSDP 管理 sharded storage/view。
  • 参数在不同阶段可能呈现 sharded/full view,用户不应缓存不受管理的 data pointer 或在 hook 中假设 shape 永久不变。
  • optimizer 应基于 FSDP 包装后暴露的参数构造,确保 state 与 FSDP 管理对象对应;state-dict 保存/加载也要使用对应 FSDP API/上下文。
  • 这不自动解决 shared parameter、mixed frozen params 或跨 world-size optimizer reshard,需要按版本文档验证限制。

追问:为什么不能只检查 optimizer parameter 数量?对象 identity、flatten/view、state key 和 shard ownership 都可能出错。

Q133. sync_module_states=True 与 device 初始化有哪些底层要求?

高分回答要点

  • 它从 rank 0 广播 module parameters/buffers,确保各 rank 初始状态一致;通信需要 module 已在 GPU,或通过 device_id/param_init_fn 正确 materialize。
  • 若先在每 rank 用不同 seed 初始化且不同步,loss 有限仍可能训练不同模型;DDP/FSDP 后续 gradient collective 不能修复第一次 forward 的状态差异。
  • 大模型常用 meta-device 初始化避免每 rank CPU 完整副本,再由 FSDP materialize/shard;此时初始化顺序、tied weights 和 buffer 都需测试。
  • oracle 应比较初始化后跨 rank parameter/buffer checksum,而不是等到 loss 发散才发现。

追问:为什么 broadcast 也可能制造启动峰值?rank 0 完整参数、materialization、flatten/shard 和通信 buffer 的生命周期可能重叠。

Q134. FSDP checkpoint 为什么不能直接沿用单 rank torch.save(model.state_dict())

高分回答要点

  • FSDP 参数与 optimizer state 是分片/flatten 管理的;full、sharded、local state dict 语义和内存/IO 成本不同。
  • full state 在 rank 0 聚合可能造成 CPU/GPU 峰值与串行 IO;sharded state 便于并行写,但恢复到不同 world size 需要 reshard planner。
  • checkpoint 还要保存 scheduler/scaler/RNG/data cursor/framework metadata,使用原子 manifest/checksum 防止 partial version 可见。
  • 当前实验只做同 world-size 教学协议,没有证明 FSDP/DCP sharded state 或 8-to-4 reshard,面试必须主动说明。

追问:optimizer state reshard 为什么比参数更复杂?Adam 有多个 state tensor、参数 key 映射、dtype/flatten metadata 与 ownership 重分配。

Q135. FSDP rank 0 trace 能证明什么,不能证明什么?

高分回答要点

  • 能证明该 rank 一个 profiled step 的 NCCL kernel 类别/次数、stream interval,以及按非 NCCL kernel union 定义的局部 overlap/exposed time。
  • 不能直接证明跨 8 rank 全局 critical path、网络纯传输时间或整轮稳态吞吐;collective duration 包含 peer wait,profiler 也有 overhead。
  • 本实验用三次非 profiler run 报 tokens/s,用 trace 解释 PRE/POST 事件结构;两类证据不能互相替代。
  • 更完整做法是多 rank 时间对齐、NVTX 标注 FSDP unit、CPU/CUDA/NCCL trace 与 rank skew,再关联 step max-rank wall time。

追问:为什么 sum(kernel duration) 也不可靠?同 stream/跨 stream 可能重叠,必须先做 interval union,再算与 compute 的 intersection。

Q136. 1 GiB KV cache 为什么在 C=16 时不是一开始就 OOM,而是在 decode 中发生抢占?

高分回答要点

  • cache 容量是 18,720 tokens;16 个 prompt 各 1,024,初始约 16,384 tokens,仍能 admission。
  • decode 每轮继续为 active sequence 增加 KV,工作集越过容量后 scheduler 需要释放受害 sequence 的 blocks,并在恢复时重计算其上下文。
  • C=8 峰值 KV 65.7% 且无抢占;4 GiB/C=16 容量 74,896、峰值 32.8%,也无抢占;这个双对照支持容量因果。
  • OOM、waiting 和 preemption 是不同状态:调度器可通过 admission/抢占避免 allocator OOM,但请求时延和吞吐仍受损。

手算追问:忽略 block rounding,18,720-16,384=2,336 只够每个请求平均再增长约 146 tokens,远小于目标 512。

Q137. vLLM preemption 的 recompute、swap 和 reject/admission control 有什么区别?

高分回答要点

  • recompute 释放某 sequence KV,恢复时重做 prefill/已生成上下文计算,省主机传输但消耗 GPU compute。
  • swap 把 KV 移到 CPU/其他层级,恢复时传回,代价受 PCIe/内存容量和实现支持影响;不等价于 prefix cache eviction。
  • admission/reject 在请求进入或运行前限制工作集,保护已接收请求 SLO;preemption 是已运行 sequence 的运行时资源回收。
  • 比较策略要看 preemption 次数、recomputed/swapped tokens、TTFT/TPOT/E2E、throughput、KV waterline、waiting 和 OOM/reject。

边界:本实验直接观测 preemption counter 和性能,未单独解析每个受害请求或重计算 token 数,不能宣称精确的 victim policy。

Q138. 为什么发生抢占的 1 GiB/C=16 TTFT 反而比 4 GiB/C=16 低?

高分回答要点

  • 1 GiB mean TTFT 2,601 ms,4 GiB 为 2,931 ms;与此同时 1 GiB throughput 只有 66.0%,mean TPOT 慢 11.0%。
  • 小 cache/抢占限制了实际可持续并发,部分 prefill 面临的同时 GPU 竞争更少,可能让首 token 更早;代价转移到被暂停请求和 decode/recompute。
  • TTFT 是分布统计,不能说明同一请求 cohort 谁受益;应看 per-request timeline、victim 标记和 p95/p99,而不是只解释均值。
  • 正确结论是“单指标有 trade-off 且需要更细 trace”,不是“小 cache 能优化 TTFT”这一因果宣称。

面试陷阱:若候选人只用 TTFT 选 1 GiB,说明没有把用户体验、完成率、吞吐和 TPOT 联合建模。

Q139. 为什么要每 250 ms 抓 metrics time series,而不能只保存 server 结束时快照?

高分回答要点

  • requests_running/waiting、KV usage 是 gauge,结束后通常回到 0;只看 final snapshot 会丢失峰值和饱和过程。
  • preemption 是 counter,应对起止或相邻样本做 delta;本实验两次 1 GiB/C=16 都增加 4,其他 case 为 0。
  • 250 ms 采样仍可能漏掉更短 gauge spike,因此“观测峰值”是下界;counter 不会因短事件漏计,但要处理 server restart/reset。
  • 应保存采样时间、标签、原始 exposition text 和 benchmark 时间边界,避免 parser 把不同 server/case 混在一起。

追问:若 scrape 本身影响服务怎么办?降低频率、独立 exporter、测 overhead,并用 counter 与 trace 交叉验证。

Q140. max_num_seqsmax_num_batched_tokens、KV 容量和 waiting queue 各控制什么?

高分回答要点

  • max_num_seqs 限制一个调度批次/engine 可并行管理的 sequence 数;它不是 KV 的 token 容量。
  • max_num_batched_tokens 限制一次 iteration 调度的 token budget,影响 chunked prefill 与 decode 共存、TTFT/TPOT trade-off。
  • KV blocks 是跨 iteration 的状态容量;即使 sequence/token budget 合法,长期 decode 增长仍可能触发抢占。
  • waiting 表示已接收但当前未运行的请求,来源可以是 sequence/token budget、KV pressure、优先级或调度策略;需要结合 running、KV 和 preemption 才能归因。

设计追问:怎样避免 C=16 抢占?增大 KV、降低 admission concurrency、缩短 max output、采用更小 KV dtype/模型并行布局,或基于预计总 tokens 做准入。

Q141. num_warps 为什么会显著改变同一个 Triton RMSNorm 的 registers/thread?

高分回答要点

  • 一个 program 处理整行 reduction。warp 数改变 lane 间工作划分、部分和数量、shuffle/shared reduction 路径及每线程 live values。
  • hidden=8192 时 1 warp 每线程承担更多元素,编译结果 255 registers/thread、384 B stack;8 warps 为 54 registers、无 stack。
  • 1 warp kernel 0.5707 ms,8 warps 0.3323 ms,慢 1.72x;这支持 register pressure/并行度机制,但仍需硬件 counter 区分 spill、latency hiding 和 memory stalls。
  • hidden=4096 的 2/4/8 warps 性能只差约 0.7%,说明提高理论 occupancy 不保证线性收益,带宽/指令路径可能已饱和。

追问:为什么 255 registers 是警示值?它接近架构每线程上限并限制每 SM resident blocks/warps,还伴随 stack,需检查 local-memory spill 指令和实际 occupancy。

Q142. “理论 occupancy 上界”是怎样算的,为什么不能当 achieved occupancy?

高分回答要点

  • 用每 block threads/registers/shared memory 分别除 V100 每 SM 的 2,048 threads、65,536 registers、96 KiB shared,再受 32 blocks/64 warps 上限约束,取最小 resident blocks。
  • occupancy 上界是 resident_blocks * warps_per_block / 64;hidden8192/1warp 为 12.5%,8warps 为 50%。
  • 这是静态资源容量模型,不含动态调度、依赖 stall、实际 active cycles、编译器隐藏资源、cache miss 或 block 分布尾部。
  • achieved occupancy、eligible warps、stall reason 需要 Nsight Compute hardware counter;即使 achieved occupancy 高,memory-bound kernel 也未必更快。

现场题:给 registers/thread、threads/block、shared/block,要求手算三个资源限制并指出哪个是 bottleneck。

Q143. cuobjdump 和 Nsight Compute 分别能回答什么?

高分回答要点

  • cuobjdump --dump-resource-usage 对 cubin 做静态分析,给函数 registers、stack、shared、local 等编译资源;适合无性能计数权限时做资源回归。
  • 反汇编还能检查 load/store、local memory、Tensor Core 等指令,但不能告诉执行次数、cache hit、dram bytes 或 stall 占比。
  • Nsight Compute 采运行时硬件 counter,可看 achieved occupancy、memory throughput、L2、warp stall、instruction mix;采集有权限和 replay overhead。
  • 端到端 trace/Nsight Systems 负责 CPU/CUDA/NCCL 时间线。三类工具回答不同层级,不能互相替代。

追问:为什么本实验的 808 GB/s 也不是 Nsight dram throughput?它是按 input read+output write+weight read 一次的最小字节模型除以时间。

Q144. ncu --query-metrics 文本报 ERR_NVGPUCTRPERM,退出码却是 0,自动化应怎么处理?

高分回答要点

  • CLI exit code 只说明命令进程完成,不保证请求的 capability 可用;必须保存 stdout/stderr 并匹配结构化错误或已知诊断文本。
  • runner 同时写 .status 和完整 log,parser 以 ERR_NVGPUCTRPERM 判定 counter 权限失败,不能把 status 0 误记成 profiler 成功。
  • CI 应验证预期 metric 列和非空 kernel report;缺 counter 时标记 unsupported/blocked,而不是生成 0 值继续计算。
  • 修复需要管理员按 NVIDIA 指引开放 profiling 权限;容器内无权时应诚实降级到 static resource + wall time,并记录证据边界。

工程追问:类似问题还会出现在什么地方?编译器 warning、benchmark 跳过全部 case、HTTP 200 内业务 error、测试框架 zero tests collected 都不能只看退出码。

Q145. 如何设计一套能防守底层追问的 kernel/profile 实验?

高分回答要点

  • correctness 先行:独立 FP32 oracle、多 shape/dtype/stride/极值、有限值和误差分布;异步 kernel 必须同步后检查。
  • 性能控制:预分配输出、warmup/JIT 分离、固定 clocks/负载、CUDA event、足够 iterations/repeats,并报告方差和 launch floor。
  • 机制证据:最小 bytes/FLOPs 模型、编译资源、SASS/PTX、hardware counter 和 timeline 分层收集;每个指标注明“估算、静态、实测”之一。
  • 反例与边界:warp/stage/shape sweep、资源拐点、无权限/unsupported path、端到端集成收益;不能从单一最快点推广。
  • artifact 链:命令与版本 -> raw JSON/log/cubin/trace -> parser -> validation -> report,任何数字都能手工复算。

4 分答案特征:能用 hidden8192 的 255 registers、12.5% 理论上界、0.5707 ms 和 ERR_NVGPUCTRPERM 同时说明“我们知道什么、为什么这样解释、还缺什么”。



上一篇:工程实现与实验深挖 · 系列总索引

This post is licensed under CC BY 4.0 by the author.

AI Infra 面试题(九):工程实现与实验深挖

AI Infra 面试实战:上机题、岗位选题与六周训练计划