提到 FFT 很多人想到的是信号处理——音频频谱、通信调制解调。AI 里也有 FFT 的用武之地:图像频域增强、语音特征提取、科学计算中的 PDE 求解。CANN 的 ops-fft 仓库在昇腾NPU 上实现了 FFT 的硬件加速。
FFT 为什么重要
DFT(离散傅里叶变换)把时域序列变换到频域。朴素 DFT 的复杂度是O(n²)——n 个输入点要算 n² 次复数乘法。FFT 用分治思想把复杂度降到O(n log n)。对于 1024 点的信号,O(n²)要 100 万次运算,FFT 只要约 1 万次。
FFT 的典型应用:
- 音频处理:频率滤波、MFCC 特征提取(语音识别的前置步骤)
- 图像处理:频域增强、傅里叶卷积(大卷积核场景)
- 科学计算:偏微分方程求解的谱方法
- AI 模型:FNO(傅里叶神经算子)、某些语音模型的前处理
AI 为什么用到 FFT
AI 中使用 FFT 的场景虽然不多,但每个场景都绕不开它:
傅里叶神经算子(FNO)。物理仿真中的 PDE 求解器。FNO 把输入信号变换到频域,在频域做学习后再逆变换回时域。每个训练步都要做多次 FFT 和 IFFT——FFT 是 FNO 的计算核心。
语音特征提取。MFCC(梅尔频率倒谱系数)是语音识别的前置步骤。MFCC 的核心步骤是 STFT(短时傅里叶变换),对每一帧音频做 FFT。语音训练数据的预处理大量依赖 FFT。
图像频域增强。某些图像预处理方法在频域上做——低通滤波(模糊)、高通滤波(锐化)、频域去噪。这些操作需要对整张图像做 2D FFT、频域处理、2D IFFT。
昇腾NPU如何加速 FFT
FFT 在 NPU 上的执行跟常规算子不同。它不用 Vector Vector 也不走 Cube Unit——FFT 的蝶形运算结构更适合在 Vector Unit 上用 SIMD 指令实现。
O(n log n)的 FFT 在硬件上分解为log n级蝶形运算,每一级对输入序列做特定的数据重排和复数乘加:
输入 [x0, x1, x2, x3, x4, x5, x6, x7] ↓ Stage 1(每 2 个元素一组做蝶形运算) ↓ Stage 2(每 4 个元素一组) ↓ Stage 3(每 8 个元素一组) 输出 [X0, X1, X2, X3, X4, X5, X6, X7]ops-fft 对每个 stage 生成一条 Vector 指令,连续 stage 之间通过 Vector Unit 的寄存器传递数据(不写 DDR)。n=1024的 FFT 只需要 10 级蝶形运算。
典型场景:图像 2D FFT
2D FFT = 对图像的每一行做 1D FFT + 对每一列做 1D FFT。
对于 1024×1024 的图像:
- 行 FFT:1024 行 × 1024 点 FFT
- 列 FFT:1024 列 × 1024 点 FFT
- 总计算量:约
2 × 1024 × 1024 × log2(1024) × 5FLOPs = 约 100M FLOPs
ops-fft 对 2D FFT 做了专门优化:
- 行 FFT 时利用 Vector Unit 的 SIMD 宽度同时处理多行
- 列 FFT 之前做一次矩阵转置,让列数据在内存中连续排列——避免跨步访问
- 行和列的中间结果在 L1 Buffer 中流转,不写 DDR
FFT 在 AI 训练中的实际用例
FNO(傅里叶神经算子)是 AI for Science 领域的一个重要模型,用于求解 PDE。FNO 的前向计算流程:
- 输入信号通过 FFT 变换到频域
- 在频域中做线性变换(学习频域权重)
- 通过 IFFT 变换回时域
- 叠加非线性激活函数
每个训练 step 需要执行多次 FFT 和 IFFT。对于 64×64×64 的三维网格,一次 3D FFT 的计算量约 100M FLOPs。FNO 的训练时间主要花在 FFT 上。
ops-fft 的优化策略
ops-fft 针对 2D 和 3D FFT 做了专门优化。二维 FFT 的优化核心是行-列分解后的内存连续性。ops-fft 会在行 FFT 完成后做矩阵转置,把列方向的 FFT 变为连续访问。转置的开销通过 Double Buffer 与 FFT 计算重叠——转置和下一行的 FFT 同时进行。
大尺寸 FFT(4096×4096)的优化更激进——把图像切分成 512×512 的子块,每个 Core 处理一个子块。四个 Core 并行做 512 点 FFT,再把结果合并。总计算时间从串行方案的 3.2ms 降到 0.9ms。
参考仓库
ops-fft FFT 算子库
ops-math 数学算子库