智源研究院 AI Infra 一面


Q: 卷积算子如何高效实现?

卷积是CNN的核心算子,不同实现方式在不同场景下各有优势:

实现方式 原理 适用场景 优缺点
Im2col + GEMM 将卷积展开为矩阵乘法 通用(cuBLAS加速) 额外内存开销,但利用高度优化的GEMM
Direct Conv 直接滑窗实现 小kernel、特殊shape 灵活但难以优化到极致
Winograd 减少乘法次数 3×3 kernel 快2-4倍,但数值精度稍差
FFT 频域卷积 大kernel(>7×7) 大kernel快,小kernel开销大
隐式GEMM 不显式im2col 通用(cuDNN默认) 省内存+高效

Im2col + GEMM(最经典方法)

将输入按卷积窗口展开为2D矩阵,卷积变为矩阵乘法:

  • 展开后输入矩阵:[output_h×output_w, C_in×kH×kW]
  • 权重矩阵:[C_out, C_in×kH×kW]
  • 输出 = 权重 × 展开输入^T
  • 利用cuBLAS/Tensor Core的高度优化GEMM实现加速。
  • 代价:展开后矩阵比原始输入大 kernel_h×kernel_w 倍(3×3 conv展开9倍)。

Winograd(3×3卷积的王者)

原理:通过数学变换将3×3卷积的乘法次数从9减少到4(F(2,3))或2.25(F(4,3))次/输出元素。

  • F(m,r):在m×m输出tile上,用(m+r-1)×(m+r-1)的输入tile计算,减少乘法。
  • 代价:需要额外的变换矩阵乘法和加法;r越大数值稳定性越差。
  • 效果:3×3 conv配合Winograd在cuDNN中通常是最快的(比直接GEMM快30-50%)。
  • 限制:不适合stride>1、dilation>1的情况。

隐式GEMM(cuDNN的Implicit GEMM Precomputed)

不做显式的im2col(避免额外内存分配),而是在GEMM kernel内部通过索引计算隐式地从原始输入中读取数据,等效于im2col+GEMM但省去中间buffer。是cuDNN的默认高效实现。

选择建议

  • 3×3 conv + stride=1:Winograd(cuDNN自动选择)。
  • 1×1 conv:退化为GEMM,直接用cuBLAS。
  • 大kernel/任意参数:隐式GEMM。
  • 最佳实践:让cuDNN auto-tune选择(cudnnFindConvolutionForwardAlgorithm)。

Q: 端侧大模型部署的关键技术?

端侧(手机/车载/IoT)部署大模型面临严格的内存、功耗、延迟三重约束,需要综合多种技术:

1. 量化(最核心的技术)

  • INT4/INT8量化将模型体积压缩4-8倍:7B模型从14GB(FP16)→3.5GB(INT4),可放入手机RAM。
  • 方法:GPTQ/AWQ离线量化权重为4bit,推理时反量化后与FP16激活计算。
  • 精度影响:4bit量化通常perplexity增加0.5-2%,对大多数应用可接受。

2. 模型裁剪/压缩

  • 层剪枝:去掉不重要的Transformer层(如LLM-Pruner)。
  • 注意力头剪枝:减少attention头数(如从32头减到16头)。
  • 宽度缩减:减小hidden_size和intermediate_size。
  • 结构化蒸馏:用大模型蒸馏到小模型。

3. KV Cache优化(端侧内存限制的关键)

  • GQA/MQA:减少KV头数,如Llama-3用GQA(8个KV头 vs 32个Q头),KV Cache减少4倍。
  • KV量化:INT8存储KV Cache。
  • 滑动窗口注意力:只保留最近N个token的KV(如Mistral的4096窗口)。
  • Token剪枝:丢弃注意力权重低的历史token的KV。

4. 轻量模型选择

  • 1-3B参数的小模型:Qwen-1.5B、Phi-3-mini(3.8B)、Gemma-2B。
  • 这些模型专为端侧设计,在有限参数量下最大化能力。

5. 推理引擎优化

  • llama.cpp:C/C++实现,支持GGUF格式、2-8bit量化、ARM NEON/Apple Metal加速。iPhone上跑7B模型约5-10 tokens/s。
  • MLC-LLM:Apache TVM编译优化,支持多端(Android/iOS/Web)。
  • MediaPipe LLM:Google的端侧推理方案。

6. 投机解码(端侧适配版)

  • 用参数极少的draft model(如100M参数)配合主模型,加速1.5-2倍。
  • 或使用MTP头(主模型自带的额外预测头)。

7. 内存管理

  • mmap按需加载:不一次性将所有权重加载到内存,使用mmap让OS按需page in。减少峰值内存占用。
  • Layer-wise加载:每次只加载当前计算需要的层的权重。适合RAM极有限的设备。

端侧部署典型数据

  • 7B模型INT4量化:模型约3.5GB,推理需4-6GB RAM,iPhone 15 Pro约8-12 tokens/s。
  • 1.5B模型INT4:模型约1GB,推理需2GB RAM,中端手机约20-30 tokens/s。

Q: 手撕:树形DP?

(编程题)