「赤兔」Chitu 框架深度解读(十四):核心算子优化

「赤兔」Chitu 框架深度解读(十四):核心算子优化 (RoPE, RMSNorm, SiLU, Sampling)

除了 Attention 和 GEMM 等计算密集型算子外,Transformer 模型中还包含许多其他关键算子,如位置编码(RoPE)、归一化(RMSNorm)、激活函数(SiLU/SwiGLU)和采样(Sampling)。对这些算子进行优化同样能带来显著的性能提升。「赤兔」Chitu 框架在其 ops/ 目录下提供了多种优化实现。

旋转位置编码 (RoPE - ops/rotary.py)

RoPE 是目前主流大模型使用的位置编码方式。其核心操作是将输入向量的一部分维度进行旋转。

  • apply_rotary_pos_emb: 核心函数接口。
  • 后端实现 :
    • apply_rotary_pos_emb_cuda : 调用 CUDA C++ 扩展 (chitu_backend.apply_rotary_pos_emb) 实现。这是 NVIDIA GPU 上的主要优化路径。代码位于 csrc/cuda/rotary/rotary_pos_emb_llama.cu。
    • apply_rotary_pos_emb_npu : 调用昇腾 NPU 的特定算子 (torch_npu.npu_rotary_mul)。
    • apply_rotary_pos_emb_cpu : 调用 CPU C++ 扩展 (chitu_cpu_backend.apply_rotary_pos_emb)。代码位于 csrc/cpuinfer/rotary.cpp,使用了 llamafile 中的优化代码。
    • apply_rotary_pos_emb_triton : 调用 chitu.ops.triton_ops.rotary.apply_rotary_pos_emb 实现的 Triton 内核。
    • apply_rotary_pos_emb_torch: PyTorch 原生实现,作为 fallback。
  • 动态调度 : 函数内部会根据当前设备类型 (is_cuda, is_npu, is_cpu) 和配置选择合适的后端实现。
  • BatchedFreqsCIS (batched_freqs_cis.py) : 用于预计算和缓存 RoPE 所需的 cos 和 sin 值,避免在每次 Attention 计算时重复生成,特别是在批处理和 Paged KV Cache 场景下优化 freqs 的构造。

RMSNorm (ops/norm.py)

RMSNorm 是一种轻量级的归一化方法。

  • rms_norm: 核心函数接口。
  • 后端实现 :
    • rms_norm_cuda : 调用 CUDA C++ 扩展 (chitu_backend.rms_norm)。代码位于 csrc/cuda/norm/rms_norm.cu。
    • rms_norm_npu : 调用昇腾 NPU 的 torch_npu.npu_rms_norm 算子。
    • rms_norm_cpu : 调用 CPU C++ 扩展 (chitu_cpu_backend.rms_norm)。代码位于 csrc/cpuinfer/rmsnorm.cpp。
    • rms_norm_triton : 调用 chitu.ops.triton_ops.norm.rms_norm 实现的 Triton 内核。
    • rms_norm_torch: PyTorch 原生实现,作为 fallback。
  • 动态调度: 同样根据设备类型和配置选择后端。

SiLU / SwiGLU 激活 (ops/activation.py)

SiLU (Sigmoid Linear Unit) 及其变种 SwiGLU 是 Llama 等模型 MLP 层常用的激活函数,通常涉及两个线性层的输出和一个逐元素操作 (SiLU(gate) * up)。

  • silu_and_mul : 计算 SiLU(x) * y。
  • fused_gate_up_proj_and_silu: 尝试融合 Gate 和 Up 两个线性投影以及后续的 SiLU 激活和乘法操作。
  • 后端实现 :
    • CUDA C++ : chitu_backend.silu_and_mul (可能实现融合)。
    • NPU : torch_npu.npu_silu 和逐元素乘法。融合实现可能依赖特定 NPU 算子。
    • CPU C++ : chitu_cpu_backend.silu_and_mul (csrc/cpuinfer/silu_and_mul.cpp)。
    • Triton : chitu.ops.triton_ops.activation.silu_and_mul。
    • Torch: PyTorch 原生实现。
  • 动态调度: 根据设备类型和可用性选择实现。

Logits 处理与采样 (ops/sampling.py)

生成下一个 Token 涉及对模型输出的 Logits 进行处理(如应用温度、Top-K/Top-P、重复惩罚等)和采样。

  • apply_logits_constraints : 应用各种约束(Repetition Penalty, Frequency/Presence Penalty, Temperature, Top-K, Top-P)。
    • apply_penalties_cuda : 调用 CUDA C++ 扩展 (chitu_backend.apply_penalties) 处理 Frequency 和 Presence Penalty。代码位于 csrc/cuda/frequency_penalty/frequency_penalty.cu。其他约束通常在 PyTorch 或 Triton 中实现。
    • apply_logits_constraints_triton : 调用 chitu.ops.triton_ops.sampling.apply_logits_constraints 实现的 Triton 内核,可能融合多种约束处理。
    • apply_logits_constraints_torch: PyTorch 原生实现。
  • sample : 从处理后的 Logits/Probabilities 中采样下一个 Token ID。
    • sample_cuda: 调用 CUDA C++ 扩展。
    • sample_triton: 调用 Triton 内核实现。
    • sample_torch : PyTorch 原生实现 (torch.multinomial)。
    • Greedy Search: 也提供了 Argmax 实现。

特点:

  • 融合优化: 尝试将多种 Logits 处理步骤(惩罚、温度、Top-K/P)融合到单个 CUDA 或 Triton 内核中,减少内存读写和 Kernel Launch 开销。
  • 后端多样性: 为关键的惩罚计算和采样提供了 CUDA/Triton/Torch 实现。

总结

「赤兔」对 RoPE, RMSNorm, SiLU/SwiGLU, Sampling 等核心算子进行了细致的优化。通过提供包括 CUDA C++ 扩展、NPU 特定算子、CPU C++ 扩展、Triton 内核以及 PyTorch 原生实现在内的多种后端,并根据运行环境动态选择最优路径。「赤兔」确保了这些看似"辅助"的算子不会成为推理流程中的性能瓶颈。特别是对 RoPE 的预计算缓存、激活函数的融合尝试以及 Sampling 约束处理的融合优化,都体现了其追求端到端高性能的设计理念。# 「赤兔」Chitu 框架深度解读(十四):核心算子优化 (RoPE, RMSNorm, SiLU, Sampling)

除了 Attention 和 GEMM 等计算密集型算子外,Transformer 模型中还包含许多其他关键算子,如位置编码(RoPE)、归一化(RMSNorm)、激活函数(SiLU/SwiGLU)和采样(Sampling)。对这些算子进行优化同样能带来显著的性能提升。「赤兔」Chitu 框架在其 ops/ 目录下提供了多种优化实现。

旋转位置编码 (RoPE - ops/rotary.py)

RoPE 是目前主流大模型使用的位置编码方式。其核心操作是将输入向量的一部分维度进行旋转。

  • apply_rotary_pos_emb: 核心函数接口。
  • 后端实现 :
    • apply_rotary_pos_emb_cuda : 调用 CUDA C++ 扩展 (chitu_backend.apply_rotary_pos_emb) 实现。这是 NVIDIA GPU 上的主要优化路径。代码位于 csrc/cuda/rotary/rotary_pos_emb_llama.cu。
    • apply_rotary_pos_emb_npu : 调用昇腾 NPU 的特定算子 (torch_npu.npu_rotary_mul)。
    • apply_rotary_pos_emb_cpu : 调用 CPU C++ 扩展 (chitu_cpu_backend.apply_rotary_pos_emb)。代码位于 csrc/cpuinfer/rotary.cpp,使用了 llamafile 中的优化代码。
    • apply_rotary_pos_emb_triton : 调用 chitu.ops.triton_ops.rotary.apply_rotary_pos_emb 实现的 Triton 内核。
    • apply_rotary_pos_emb_torch: PyTorch 原生实现,作为 fallback。
  • 动态调度 : 函数内部会根据当前设备类型 (is_cuda, is_npu, is_cpu) 和配置选择合适的后端实现。
  • BatchedFreqsCIS (batched_freqs_cis.py) : 用于预计算和缓存 RoPE 所需的 cos 和 sin 值,避免在每次 Attention 计算时重复生成,特别是在批处理和 Paged KV Cache 场景下优化 freqs 的构造。

RMSNorm (ops/norm.py)

RMSNorm 是一种轻量级的归一化方法。

  • rms_norm: 核心函数接口。
  • 后端实现 :
    • rms_norm_cuda : 调用 CUDA C++ 扩展 (chitu_backend.rms_norm)。代码位于 csrc/cuda/norm/rms_norm.cu。
    • rms_norm_npu : 调用昇腾 NPU 的 torch_npu.npu_rms_norm 算子。
    • rms_norm_cpu : 调用 CPU C++ 扩展 (chitu_cpu_backend.rms_norm)。代码位于 csrc/cpuinfer/rmsnorm.cpp。
    • rms_norm_triton : 调用 chitu.ops.triton_ops.norm.rms_norm 实现的 Triton 内核。
    • rms_norm_torch: PyTorch 原生实现,作为 fallback。
  • 动态调度: 同样根据设备类型和配置选择后端。

SiLU / SwiGLU 激活 (ops/activation.py)

SiLU (Sigmoid Linear Unit) 及其变种 SwiGLU 是 Llama 等模型 MLP 层常用的激活函数,通常涉及两个线性层的输出和一个逐元素操作 (SiLU(gate) * up)。

  • silu_and_mul : 计算 SiLU(x) * y。
  • fused_gate_up_proj_and_silu: 尝试融合 Gate 和 Up 两个线性投影以及后续的 SiLU 激活和乘法操作。
  • 后端实现 :
    • CUDA C++ : chitu_backend.silu_and_mul (可能实现融合)。
    • NPU : torch_npu.npu_silu 和逐元素乘法。融合实现可能依赖特定 NPU 算子。
    • CPU C++ : chitu_cpu_backend.silu_and_mul (csrc/cpuinfer/silu_and_mul.cpp)。
    • Triton : chitu.ops.triton_ops.activation.silu_and_mul。
    • Torch: PyTorch 原生实现。
  • 动态调度: 根据设备类型和可用性选择实现。

Logits 处理与采样 (ops/sampling.py)

生成下一个 Token 涉及对模型输出的 Logits 进行处理(如应用温度、Top-K/Top-P、重复惩罚等)和采样。

  • apply_logits_constraints : 应用各种约束(Repetition Penalty, Frequency/Presence Penalty, Temperature, Top-K, Top-P)。
    • apply_penalties_cuda : 调用 CUDA C++ 扩展 (chitu_backend.apply_penalties) 处理 Frequency 和 Presence Penalty。代码位于 csrc/cuda/frequency_penalty/frequency_penalty.cu。其他约束通常在 PyTorch 或 Triton 中实现。
    • apply_logits_constraints_triton : 调用 chitu.ops.triton_ops.sampling.apply_logits_constraints 实现的 Triton 内核,可能融合多种约束处理。
    • apply_logits_constraints_torch: PyTorch 原生实现。
  • sample : 从处理后的 Logits/Probabilities 中采样下一个 Token ID。
    • sample_cuda: 调用 CUDA C++ 扩展。
    • sample_triton: 调用 Triton 内核实现。
    • sample_torch : PyTorch 原生实现 (torch.multinomial)。
    • Greedy Search: 也提供了 Argmax 实现。

特点:

  • 融合优化: 尝试将多种 Logits 处理步骤(惩罚、温度、Top-K/P)融合到单个 CUDA 或 Triton 内核中,减少内存读写和 Kernel Launch 开销。
  • 后端多样性: 为关键的惩罚计算和采样提供了 CUDA/Triton/Torch 实现。

总结

「赤兔」对 RoPE, RMSNorm, SiLU/SwiGLU, Sampling 等核心算子进行了细致的优化。通过提供包括 CUDA C++ 扩展、NPU 特定算子、CPU C++ 扩展、Triton 内核以及 PyTorch 原生实现在内的多种后端,并根据运行环境动态选择最优路径。「赤兔」确保了这些看似"辅助"的算子不会成为推理流程中的性能瓶颈。特别是对 RoPE 的预计算缓存、激活函数的融合尝试以及 Sampling 约束处理的融合优化,都体现了其追求端到端高性能的设计理念。

相关推荐
冬奇Lab1 小时前
开源项目第241期:YuE2 —— 用符号乐谱当“白盒“接口的开源音乐生成模型,SongBench 超越 Suno v5/v6
人工智能
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 14 章 MCP 服务端(上):注解式实现与工具来源
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 15 章 MCP 服务端(下):三种协议形态、Streamable 传输与状态管理
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 16 章 向量存储(上):`VectorStore` 接口体系、`BatchingStrategy`
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 12 章 工具循环的流式形态、Usage 累加与扩展体系
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 23 章 模型供应商实现:从 `OpenAiSetup` 到 Bedrock
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 06 章 内置 Advisor 全景:13 个实现逐个剖到源码级
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 03 章 消息体系与 Prompt:不可变模型、`ChatOptions` 与模板渲染
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 24 章 生产实践与 2.x 迁移:陷阱清单、AOT 与调优
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 10 章 工具调用(中):执行链路、结果转换与工具限制
java·人工智能·开源