forked from microsoft/onnxruntime
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmoe_quantization.h
More file actions
118 lines (104 loc) · 6.1 KB
/
Copy pathmoe_quantization.h
File metadata and controls
118 lines (104 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "core/common/common.h"
#include "core/providers/cuda/cuda_kernel.h"
#include "contrib_ops/cuda/moe/moe_base.h"
#include "contrib_ops/cuda/llm/moe_gemm/moe_kernels.h"
#include "contrib_ops/cuda/llm/moe_gemm/moe_gemm_profiler.h"
#include <mutex>
namespace onnxruntime {
namespace contrib {
namespace cuda {
using namespace onnxruntime::cuda;
class QMoE final : public CudaKernel, public MoEBase {
public:
explicit QMoE(const OpKernelInfo& op_kernel_info);
Status ComputeInternal(OpKernelContext* ctx) const override;
Status PrePack(const Tensor& tensor, int input_idx, AllocatorPtr alloc,
bool& is_packed, PrePackedWeights* prepacked_weights) override;
private:
// PrePack helpers - each handles one category of input tensor.
void PrePackTransposeAndPack(const Tensor& tensor, cudaStream_t stream, AllocatorPtr alloc,
IAllocatorUniquePtr<void>& packed_buf, bool& is_packed);
void PrePackComputeBias(const Tensor& tensor, cudaStream_t stream, AllocatorPtr alloc,
const IAllocatorUniquePtr<void>& packed_scale,
IAllocatorUniquePtr<void>& packed_bias, bool& is_packed);
void PrePackCopyToGpu(const Tensor& tensor, cudaStream_t stream, AllocatorPtr alloc,
IAllocatorUniquePtr<void>& packed_buf, bool& is_packed);
void PrePackSwizzleBlockScales(const Tensor& tensor, cudaStream_t stream, AllocatorPtr alloc,
IAllocatorUniquePtr<void>& packed_buf, bool& is_packed);
void PrePackRepackFP4Weights(const Tensor& tensor, cudaStream_t stream, AllocatorPtr alloc,
IAllocatorUniquePtr<void>& packed_buf, bool& is_packed);
// Prepacks int4/int8 expert weights into the CUTLASS fpA_intB layout so the
// QMoE runner can consume them directly. Mirrors what MatMulNBits.PrePack
// does, looped over the E expert dimension. ``tensor`` is the 3-D
// ``[E, N, K / (8 / bits)]`` weight initializer; ``packed_buf`` receives a
// GPU buffer in the kernel-expected ``[E, K, N / (8 / bits)]`` layout.
void PrePackIntExpertWeights(const Tensor& tensor, cudaStream_t stream, AllocatorPtr alloc,
IAllocatorUniquePtr<void>& packed_buf, bool& is_packed);
int64_t expert_weight_bits_;
bool is_fp16_;
// When true (the schema default), the int4/int8 fc1/fc2 weight
// initializers are already in the CUTLASS fpA_intB layout — produced
// offline e.g. via ``pack_weights_for_cuda_mixed_gemm`` — and the
// compute path reads them as-is. When false, the raw schema-conformant
// ``[E, N, K/pack]`` layout (as produced by
// ``quantize_matmul_{4,8}bits``) is rewritten inside the PrePack hook
// via ``PrePackIntExpertWeights``, removing the offline prepack
// dependency. Only meaningful when ``quant_type_ == "int"``.
bool weights_prepacked_ = true;
// Cached source weight shapes captured at PrePack time. When the
// PrePack hook consumed and released the original int4/int8 weight
// initializers (``is_packed = true``), ``context->Input<Tensor>(2)``
// and ``(5)`` return nothing, so ``moe_helper::CheckInputs`` can no
// longer read the shapes from the live tensors. We feed it these
// cached shapes instead via the ``TensorShape*`` overload, matching
// how ``MatMulNBits`` caches ``N_`` / ``K_`` in its constructor.
TensorShape fc1_weights_shape_;
TensorShape fc2_weights_shape_;
bool use_fp4_dequant_fallback_ = false;
// Dequantizes FP8 weights to FP16/BF16 scratch buffers before invoking the A16 MoE runner.
bool use_fp8_dequant_fallback_ = false;
// WFP4AFP8 (W4A8) requires SM100+ (Blackwell) block-scaled tensor ops. On older GPUs we
// dequantize MXFP4 weights to FP16/BF16 and run the dense A16 MoE runner.
bool use_wfp4afp8_dequant_fallback_ = false;
std::string quant_type_; // "int", "fp4", "fp8", or "wfp4afp8"
std::unique_ptr<onnxruntime::llm::kernels::cutlass_kernels::CutlassMoeFCRunnerInterface> m_moe_runner;
// Pre-packed buffers
// Note: For QMoE, we need both Scales (for dequant) and Bias (derived from ZP/Scale) during inference.
// PrePack logic:
// - Copies scales to GPU buffer (if in CPU) or just keeps them. For simplicity, we allocate and copy.
// - Computes Bias from ZP and Scale using PrePack kernel.
// - For ``quant_type == "int"``, also prepacks the per-expert int4/int8
// weight tensors into the CUTLASS fpA_intB layout, mirroring
// ``MatMulNBits.PrePack_B``. Without this, callers would have to
// pre-prepack the weights offline using ``pack_weights_for_cuda_mixed_gemm``,
// which is asymmetric with how ``MatMulNBits`` is consumed and forces
// a CUDA-enabled ORT build for any offline quantization tooling.
IAllocatorUniquePtr<void> packed_fc1_weights_;
IAllocatorUniquePtr<void> packed_fc2_weights_;
IAllocatorUniquePtr<void> packed_fc1_scales_;
IAllocatorUniquePtr<void> packed_fc1_bias_;
IAllocatorUniquePtr<void> packed_fc2_scales_;
IAllocatorUniquePtr<void> packed_fc2_bias_;
// FP4 pre-packed buffers
IAllocatorUniquePtr<void> packed_fp4_fc1_weights_;
IAllocatorUniquePtr<void> packed_fp4_fc2_weights_;
IAllocatorUniquePtr<void> packed_fp4_fc1_block_scales_;
IAllocatorUniquePtr<void> packed_fp4_fc2_block_scales_;
// Per-expert global weight scales used by FP4 and FP8 modes.
IAllocatorUniquePtr<void> packed_fc1_global_scale_;
IAllocatorUniquePtr<void> packed_fc2_global_scale_;
// Per-tensor or per-expert FP8 activation global scales used by W4A8 (WFP4AFP8) Variant A.
// Inputs 17/18 in the QMoE schema. Optional; absent for the MXFP8 block-scaled variant.
IAllocatorUniquePtr<void> packed_fc1_act_scale_;
IAllocatorUniquePtr<void> packed_fc2_act_scale_;
mutable onnxruntime::llm::kernels::cutlass_kernels::MoeGemmProfiler mGemmProfiler;
mutable onnxruntime::llm::kernels::cutlass_kernels::MoeGemmId mGemmId1;
mutable onnxruntime::llm::kernels::cutlass_kernels::MoeGemmId mGemmId2;
mutable std::mutex mGemmProfilerMutex;
};
} // namespace cuda
} // namespace contrib
} // namespace onnxruntime