这是一个关于 国产算力适配(如华为昇腾 Ascend、海光 DCU、寒武纪 MLU 等)与异构计算架构 的深度面试题集。在当前地缘政治和供应链背景下,这项能力在很多中国头部互联网和 AI 公司变得极具价值。


176. 在将原先基于 NVIDIA CUDA 的训练代码迁移到昇腾/沐曦/XPU 时,你的整体迁移思路是什么?

核心思路:分层迁移,先跑通再优化。

  1. 环境与依赖层(Environment Setup):
    • 不再直接使用 NVIDIA 的 Docker 镜像。基于厂商提供的 Base 镜像(如 Ascend Hub)构建环境。
    • 替换核心库:将 torch 替换为适配版(如 torch_npu),将 deepspeed 替换为厂商适配的分支版本。
  2. 代码适配层(Code Adaptation):
    • 工具迁移: 使用厂商提供的自动迁移工具(如华为的 msittransfer_to_npu 脚本)扫描代码,自动将 .cuda() 替换为 .npu().to(device),将 torch.cuda.* API 映射到新后端。
    • 环境变量: 设置必要的后端初始化变量(如 HCCL_WHITELIST)。
  3. 算子兼容层(Operator Compatibility):
    • 先以 PyTorch 原生算子模式运行。如果遇到不支持的算子(Op not supported),寻找等价算子替换,或回退到 CPU 执行(仅用于调试)。
  4. 精度对齐(Precision Alignment):
    • 跑通一个小 Batch,对比 CUDA 和 XPU 的 Loss 曲线和梯度数值。如果不一致,开启确定性计算模式排查。
  5. 性能优化(Performance Tuning):
    • Profiling:使用厂商工具(如 Ascend Insight / MSPROF)分析热点。
    • 替换为融合算子(Flash Attention 的厂商实现)。

177. 你如何评估一个训练/推理框架在国产算力平台上的成熟度(功能、性能、社区支持)?

评估维度矩阵:

  1. 算子覆盖度(Operator Coverage):
    • 功能指标: 能否直接运行主流模型(如 Llama 3, Qwen, Stable Diffusion)而无需修改模型代码?
    • 关键点: 是否支持复杂的 Attention 变体、RoPE、RMSNorm 等大模型常用组件。
  2. 性能达成率(Performance Efficiency):
    • 基准对比: 对比同级别 N 卡(如 910B vs A100)。
    • HF32/FP16 算力: 理论 TFLOPS 是一回事,实测 MFU (Model FLOPs Utilization) 是另一回事。成熟的平台 MFU 应达到 40%-50% 以上。
    • 通信库效率: 多机多卡扩展性(HCCL vs NCCL),线性加速比如何。
  3. 生态与工具链(Ecosystem):
    • PyTorch 兼容性: 是必须重写代码用 DSL(如 MindSpore),还是只需 import torch_npu
    • Profiling 工具: 报错信息是否人类可读?有没有类似 Nsight 的可视化性能分析工具?
  4. 社区与文档:
    • Github Issue 响应速度、官方文档的更新频率(是不是还在看两年前的文档)。

178. 关于昇腾(Ascend)+ MindSpore 生态,你认为与 PyTorch + CUDA 相比主要差异在哪里?

差异分析:

  1. 编程范式(Dynamic vs Static):
    • PyTorch + CUDA: 动态图(Eager Mode)为主,调试灵活,所见即所得。
    • MindSpore + Ascend: 虽然也支持动态图(PyNative),但为了极致性能,核心推崇静态图模式(Graph Mode)。需要将 Python 代码编译成 IR 图下沉到芯片执行。这导致调试难度大,Python 的灵活性(如动态控制流)受限。
  2. 算子开发(Kernel Implementation):
    • CUDA: 使用 C++/CUDA C 编写,开发者众多,生态极度成熟。
    • Ascend: 底层算子开发使用 TBE (Tensor Boost Engine) 或 TIK,基于 Python DSL 或 C++,门槛相对较高,开发者社区较小。
  3. 硬件亲和性:
    • MindSpore 是专为昇腾达芬奇架构(Da Vinci)设计的,能更好利用其“Cube Unit(矩阵计算)”和“Vector Unit(向量计算)”的并行特性,以及特定的内存格式(5HD),理论上限更高,但通用性差。

179. 在多平台共存(GPU + 昇腾 + XPU)的环境下,你会如何抽象出统一的算子/后端接口?

设计模式:适配器模式 (Adapter Pattern) + 依赖注入。

  1. 统一设备抽象(Device Context):
    • 定义一个 DeviceManager 类,根据环境变量 BACKEND_TYPE=nvidia|ascend|hygon 动态加载对应的库。
    • 封装 get_device(), get_memory_status(), empty_cache() 等通用接口。
  2. 算子注册表(Operator Registry):
    • 对于标准 PyTorch 算子,直接透传。
    • 对于特殊算子(如 Flash Attention, Paged Attention),定义统一的函数签名 attention_forward(q, k, v, ...)
    • 在底层实现具体的分发逻辑:
      if backend == 'nvidia':
          return flash_attn_cuda.func(...)
      elif backend == 'ascend':
          return torch_npu.npu_fusion_attention(...)
      
  3. 配置解耦:
    • 训练脚本中不出现硬编码的 device 字符串(如 'cuda:0'),而是使用 args.device,由启动脚本统一注入。

180. 当某些算子在国产平台上没有高效实现时,你会如何绕过或实现自定义算子?

三级应对策略:

  1. Level 1: PyTorch 组合拼凑 (Composite Ops)
    • 如果缺失某个融合算子(如 SwiGLU),先用 PyTorch 原生基础算子(mul, sigmoid)组合实现。
    • 优点: 开发极快,保证功能跑通。
    • 缺点: 显存读写次数多,性能差。
  2. Level 2: 脚本级编译优化 (TorchCompile / JIT)
    • 利用 torch.compile (Inductor) 或国产平台的图编译能力,自动将上述组合算子融合,减少 Kernel Launch 开销。
  3. Level 3: 自定义算子开发 (Custom Kernel)
    • 如果性能是瓶颈(如 Attention Layer),必须手写。
    • 昇腾: 使用 Ascend CTIK 编写算子。
    • 通用: 尝试使用 OpenAI Triton(如果国产平台支持 Triton 后端,如 DeepSeek 目前就在推动 Triton 对国产卡的支持),这是跨平台开发算子的最佳路径。

181. 国产算力平台上常见的调优手段(如融合算子、图优化、内存复用)有哪些?

  1. 算子融合 (Operator Fusion):
    • 国产卡(如昇腾)的 Kernel Launch 开销通常比 CUDA 大。将 MatMul + Bias + Activation 融合成一个大算子至关重要。使用 torch_npu.npu_linear_with_bias_and_activation 等专有 API。
  2. 格式优化 (Format Optimization):
    • GPU 通常使用 NCHW/NHWC。国产卡内部可能有私有内存格式(如华为的 5HD, NZ)。
    • 手段: 减少 Format Cast 操作(TransData)。尽量让整个网络的数据流保持在私有格式下,避免频繁在 Host/Device 或不同格式间拷贝。
  3. AOE (Auto Optimization Engine):
    • 利用厂商提供的自动调优工具,对计算图进行子图调优,自动寻找最佳的 tiling 策略(切块策略)以适应片上缓存大小。
  4. 混合精度 (AMP):
    • 国产卡通常对 FP16/BF16 优化极佳,FP32 性能极差。必须 开启 AMP (Automatic Mixed Precision) Level O2 或手动指定 BF16。

182. 你在国产平台上做过哪些实际性能对比(吞吐、延迟、能耗)?有哪些经验教训?

(建议结合具体数字回答)

对比案例(以 Llama-3-70B 训练为例):

  • 吞吐 (Tokens/sec/gpu): 910B 约为 A100 的 80% - 95%(视算子优化程度)。
  • 互联带宽: HCCL 在大规模集群下(千卡)的线性度略低于 NVLink/NVSwitch,但在节点内(8卡)表现接近。

经验教训:

  1. Warmup 时间长: 国产平台通常需要编译算子(JIT Compile),导致第一个 Step 极慢(可能几分钟),甚至看起来像死机。教训: 耐心等待,做好 Log 记录,把编译缓存(Kernel Cache)保存下来。
  2. 显存虚标/碎片: 虽然显存也是 64G/32G,但由于底层 Runtime 占用和特殊的内存对齐要求,实际可用显存往往比 N 卡少。教训: Batch Size 设置要保守,比 N 卡小 10-20%。
  3. 环境脆弱: 驱动版本与固件版本必须严格对应,错一个版本号就可能导致计算错误或性能暴跌。

183. 如何在调度层(如 K8s 调度器)区分不同类型算力,并实现“就近/匹配”的资源调度?

  1. 节点打标 (Node Labeling) & 污点 (Taints):
    • Label: accelerator.type=huawei-ascend, chip.model=910b.
    • Taint: key=ascend:NoSchedule,防止普通 CPU Pod 占用。
  2. 设备插件 (Device Plugin):
    • 部署厂商提供的 K8s Device Plugin(如 ascend-device-plugin)。它会向 Kubelet 汇报扩展资源 huawei.com/Ascend910: 8
  3. 调度策略 (Affinity/Anti-Affinity):
    • 在 Deployment YAML 中指定 nodeAffinity,强制要求 Pod 调度到对应标签的节点。
  4. 拓扑感知 (Topology Aware Scheduling):
    • 对于多机训练,必须保证同一个 Job 的 Pod 分布在同一交换机下,或物理距离最近的机架,减少跨交换机通信延迟。

184. 跨平台训练带来的“数值差异”问题,你会如何定位和验证?

原因: 不同硬件的浮点数舍入策略(Rounding)、累加顺序(Accumulation Order)、以及内置函数的实现(如 exp, tanh 近似算法)不同。

定位流程:

  1. 固定随机种子: 确保初始化权重完全一致。
  2. CPU 基准对齐: 先确保两个平台的 CPU 版本代码跑出的结果一致。
  3. 逐层 Hook 对比 (Layer-wise Debugging):
    • 在 PyTorch 注册 register_forward_hook
    • 输入相同的 Dummy Data,打印每一层的 Output Mean/Var/Max。
    • 一旦发现某一层误差超过 1e−31e-31e3(FP16),定位该层算子。
  4. 算子隔离测试:
    • 单独拿出该算子,对比 Input 相同情况下的 Output。如果是 Attention 算子差异大,检查是否是 Flash Attention 的 Mask 处理逻辑不一致。

185. 对于异构集群(不同厂商 GPU/加速卡),你会如何设计容错和回退策略?

核心:Checkpoint 通用化。

  1. 统一 Checkpoint 格式:
    • 严禁保存包含硬件特定 metadata 的权重。
    • 统一保存为 PyTorch 标准 state_dictsafetensors 格式。
    • 这样,A 厂商卡训练出的模型挂了,可以用 B 厂商卡加载接着训(虽然 Optimizer 状态可能需要重置,但模型权重能保住)。
  2. 资源池隔离 (Pool Isolation):
    • 训练任务不要跨厂商混部(如一个 DDP Group 里既有 A100 又有 910B),通信库不兼容会导致立刻失败。
    • 将集群划分为 Pool_Nvidia, Pool_Ascend
  3. 自动降级 (Fallback):
    • 如果 Pool_Nvidia 满载或故障,调度器自动将新任务修改配置(如调整 Batch Size),投递到 Pool_Ascend

186. 当上层框架(如 Transformers、vLLM)对国产平台支持不完善时,你是怎么做集成的?

集成策略:

  1. 寻找 Fork 版本:
    • 国产厂商通常会在自己的 GitHub 组织下维护主流框架的 Fork 版。例如 Ascend/vllmDeepLink-org/vllm。优先使用这些 Fork。
  2. 插件化注入 (Monkey Patching):
    • 如果不希望修改库源码,可以在应用启动入口做 Monkey Patch。
    • import vllm; vllm.attention.ops = my_ascend_ops
  3. 实现 Backend 接口:
    • 以 vLLM 为例,核心需要实现 ModelExecutorWorker
    • 需要重写 PagedAttention Kernel。如果不会写 C++ Kernel,先用 PyTorch 原生算子实现一个慢版本的 PagedAttention 用于跑通流程。

187. 你如何看待“算力国产化”对工程架构的影响?为了适配国产算力,你会在哪些层次做抽象?

工程影响:

  • 复杂度爆炸: 以前只有 CUDA,现在是 CUDA + CANN + ROCm + …
  • CI/CD 压力: 需要为每种硬件维护独立的 Docker 镜像和测试流水线。

抽象层次:

  1. 镜像层: 建立 Base 镜像标准接口。所有镜像必须包含同样的监控工具、日志路径。
  2. 算子层 (HAL): 如前所述,封装 OPS_WRAPPER
  3. 通信层: 封装 dist.init_process_group。自动识别 backend 是 nccl 还是 hccl
  4. 配置层: 将模型超参(Micro Batch Size, Gradient Accumulation)与硬件解耦。根据硬件显存大小,动态计算最佳配置。

188. 请分享一次你在国产算力平台上排查性能问题或功能 Bug 的具体案例。

  • 案例: 在昇腾 910B 上训练 Llama2,Loss 突然变为 NaN,且训练速度比预期慢 50%。
  • 排查过程:
    1. NaN 问题: 开启 torch.autograd.set_detect_anomaly(True) 极其慢,没法用。于是使用溢出检测工具(Ascend 提供的 Hook),定位到是 RMSNorm 层在 BF16 下计算溢出。解决: 强制该层使用 FP32 进行累加。
    2. 速度慢问题: 使用 Profiling 工具查看 Timeline。发现大量的 HcomReceive 空隙(通信等待)。进一步发现是 CPU 数据处理太慢,导致 GPU 等待。
    3. 根因: 国产环境的 DataLoader num_workers 设置过大,加上 PyTorch 在该平台的多进程开销比 Linux x86 通用平台大,导致 CPU 争抢严重。
    4. 解决: 降低 num_workers,并开启 pin_memory=True(配合特定 NPU 标志),吞吐恢复正常。

189. 在采购和规划硬件资源时(GPU vs 国产卡),你会从哪些指标和维度做决策?

决策矩阵 (TCO 模型):

  1. 单位算力成本 (Performance/Dollar): 910B 的单卡价格是否仅为 A100 的几分之几?
  2. 迁移成本 (Migration Cost):
    • 是否有现成的算子?
    • 需要投入多少工程师人月去适配代码?(这是隐性且巨大的成本)。
  3. 供应链安全 (Supply Chain Security):
    • 对于核心战略业务,必须预留 30%-50% 的国产算力以防断供。
  4. 互联能力:
    • 不仅看单卡,要看集群。千卡集群的线性加速比能否达到 90%?这决定了能否训超大模型。
  5. 电力与散热 (PUE): 国产卡的功耗比(Perf/Watt)如何?机房是否需要改造液冷?

190. 如果要求未来系统可以“随时切换底层算力平台”,你现在在架构上会做哪些预留和抽象?

  1. 中间表示层 (IR Strategy):
    • 尽可能利用 ONNXTorchScript 作为模型交付的标准格式。推理引擎(如 TensorRT-LLM, MindSpore Lite)都支持从 IR 加载。
  2. 使用跨平台编译器 (Compiler-based Stack):
    • 引入 TVMOpenAI Triton。这些技术栈的愿景就是“Write Once, Run Anywhere”。尽量减少手写特定硬件的 Assembly/Intrinsics。
  3. 模块化后端 (Pluggable Backend):
    • 架构上强制分离 ModelLogicComputeKernel
    • 代码仓库结构:
      /models (Llama, Qwen)
      /backends
         /cuda
         /ascend
         /cpu
      
  4. 完备的单元测试集 (Unit Tests):
    • 这是切换的信心来源。必须有一套覆盖率极高的测试集,能在新硬件接入后 1 小时内跑完并给出红/绿灯。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐