From 4c991b94c8aaa17677f5e6d0445b0765daa05b76 Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Mon, 21 Apr 2025 18:05:51 +0800 Subject: [PATCH 1/9] gptq docs --- infiniop/ops/matmul_gptq/README.md | 166 +++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 infiniop/ops/matmul_gptq/README.md diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md new file mode 100644 index 0000000..b2e642f --- /dev/null +++ b/infiniop/ops/matmul_gptq/README.md @@ -0,0 +1,166 @@ + +# `MatmulGptq` + +`MatmulGptq (Matmul Gradient Pre-Trained Quantization)`, 是一种针对大语言模型的高效后量化方法,旨在将模型权重从高精度(如 f16)量化为低精度(如 int4),同时最小化量化误差对模型性能的影响。 + +其中量化过程如下所示: + + $$ + q_{k,n} = clip\left( \left\lfloor \frac{w_{k,n}}{s_{g,n}} + z_{g,n} \right\rfloor, -8, 7 \right) + $$ + +- `Scale` 是一个形状为 `( num_groups, N )` 的张量,$s_{g,n}$ 是 Scale 的第 $(g, n)$ 个元素。 +- `Zero` 是一个形状为 `( num_groups, N )` 的张量,$z_{g,n}$ 是 Zero 的第 $(g, n)$ 个元素。 +- `W` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $k \in [g \times group\_{}size, (g + 1) \times group\_{}size)$成立,其中 $group\_{}size = 128, K = num\_{}groups \times group\_{}size$ 。 + +反量化过程如下所示: + + $$ + \hat{w}_{k,n} = (q_{k,n} - z_{g,n}) \times s_{g,n} + $$ + +最终得到计算结果,其中 $\hat{W}$ 是 $\hat{w}_{k,n}$ 构成的新矩阵。 + + $$ + C = A * \hat{W} + $$ + +- `A` 为左输入张量,形状为 `( M, K )`。 +- `C` 为输出张量,形状为 `( M, N )`。 + +实际操作过程中会将量化以后的结果以 int4 的方式存储在一个形状为 $(num\_{}groups, 2 \times N)$ ,数据类型为 int32_t 的中间矩阵中。 +## 接口 + +### 计算 + +```c +infiniStatus_t infiniopMatmulGptq( + infiniopMatmulGptqDescriptor_t desc, + void *workspace, + size_t workspace_size, + void *c, + const void *a, + const void *b, + const void *b_scale, + const void *zero, + void *stream +); +``` + +
参数:
+ +- `desc`: + 已使用 `infiniopCreateMatmulGptqDescriptor()` 初始化的算子描述符。 +- `workspace`: + 额外工作空间。 +- `workspace_size`: + `workspace` 的大小,单位:字节。 +- `c`: + 计算输出结果。张量限制见[创建算子描述](#创建算子描述)部分。 +- `a`: + 左输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b`: + 右输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b_scale`: + 缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `zero`: + 零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `stream`: + 计算流/队列。 + +
返回值:
+ +- [`INFINI_STATUS_SUCCESS`], [`INFINI_STATUS_NULL_POINTER`], [`INFINI_STATUS_INSUFFICIENT_WORKSPACE`], [`INFINI_STATUS_DEVICE_TYPE_NOT_SUPPORTED`], [`INFINI_STATUS_INTERNAL_ERROR`]. + +### 创建算子描述 + +```c +infiniStatus_t infiniopCreateMatmulGptqDescriptor( + infiniopHandle_t handle, + infiniopMatmulGptqDescriptor_t *desc_ptr, + infiniopTensorDescriptor_t c_desc, + infiniopTensorDescriptor_t a_desc, + infiniopTensorDescriptor_t b_desc, + infiniopTensorDescriptor_t b_scale_desc, + infiniopTensorDescriptor_t zero_desc +); +``` + +
参数:
+ +- `handle` + : 硬件控柄。详见 [`InfiniopHandle_t`]。 +- `desc_ptr`: + `infiniopMatmulGptqDescriptor_t` 指针,指向将被初始化的算子描述符地址。 +- `c_desc` - { dT | ( M, N) | (~) }: + 算子计算参数 `c` 的张量描述。 +- `a_desc` - { dT | ( M, K) | (~) }: + 算子计算参数 `a` 的张量描述。 +- `b_desc` - { dT | ( K, N) | (~) }: + 算子计算参数 `b` 的张量描述。 +- `b_scale_desc` - { dT | ( num_groups, N) | (~) }: + 算子计算参数 `b_scale` 的张量描述。 +- `zero_desc` - { dT | ( num_groups, N) | (~) }: + 算子计算参数 `zero` 的张量描述。 + +参数限制: + +- `dT`: (`Float16`, `Float32`) 之一。 + +
返回值:
+ +- [`INFINI_STATUS_SUCCESS`], [`INFINI_STATUS_BAD_PARAM`], [`INFINI_STATUS_BAD_TENSOR_SHAPE`], [`INFINI_STATUS_BAD_TENSOR_DTYPE`], [`INFINI_STATUS_BAD_TENSOR_STRIDES`], [`INFINI_STATUS_DEVICE_TYPE_NOT_SUPPORTED`]. + +### 计算额外工作空间 + +```c +infiniStatus_t infiniopGetMatmulGptqWorkspaceSize( + infiniopMatmulGptqDescriptor_t desc, + size_t *size +); +``` + +
参数:
+ +- `desc`: + 已使用 `infiniopCreateMatmulGptqDescriptor()` 初始化的算子描述符。 +- `size`: + 额外空间大小的计算结果的写入地址。 + +
返回值:
+ +- [`INFINI_STATUS_SUCCESS`], [`INFINI_STATUS_BAD_PARAM`], [`INFINI_STATUS_DEVICE_TYPE_NOT_SUPPORTED`]. + +### 销毁算子描述符 + +```c +infiniStatus_t infiniopDestroyMatmulGptqDescriptor( + infiniopMatmulGptqDescriptor_t desc +); +``` + +
参数:
+ +- `desc`: + 待销毁的算子描述符。 + +
返回值:
+ +- [`INFINI_STATUS_SUCCESS`], [`INFINI_STATUS_DEVICE_TYPE_NOT_SUPPORTED`]. + +## 已知问题 + +无 + + +[`InfiniopHandle_t`]: /infiniop/handle/README.md + +[`INFINI_STATUS_SUCCESS`]: /common/status/README.md#INFINI_STATUS_SUCCESS +[`INFINI_STATUS_BAD_PARAM`]: /common/status/README.md#INFINI_STATUS_BAD_PARAM +[`INFINI_STATUS_DEVICE_TYPE_NOT_SUPPORTED`]: /common/status/README.md#INFINI_STATUS_DEVICE_TYPE_NOT_SUPPORTED +[`INFINI_STATUS_BAD_TENSOR_SHAPE`]: /common/status/README.md#INFINI_STATUS_BAD_TENSOR_SHAPE +[`INFINI_STATUS_BAD_TENSOR_DTYPE`]: /common/status/README.md#INFINI_STATUS_BAD_TENSOR_DTYPE +[`INFINI_STATUS_BAD_TENSOR_STRIDES`]: /common/status/README.md#INFINI_STATUS_BAD_TENSOR_STRIDES +[`INFINI_STATUS_NULL_POINTER`]:/common/status/README.md#INFINI_STATUS_NULL_POINTER +[`INFINI_STATUS_INSUFFICIENT_WORKSPACE`]:/common/status/README.md#INFINI_STATUS_INSUFFICIENT_WORKSPACE +[`INFINI_STATUS_INTERNAL_ERROR`]:/common/status/README.md#INFINI_STATUS_INTERNAL_ERROR From 33930147db76a0abf89ca390f5f3c3eeff325263 Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Mon, 21 Apr 2025 18:12:52 +0800 Subject: [PATCH 2/9] modified gptq --- infiniop/ops/matmul_gptq/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md index b2e642f..b7f2493 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/matmul_gptq/README.md @@ -11,12 +11,12 @@ - `Scale` 是一个形状为 `( num_groups, N )` 的张量,$s_{g,n}$ 是 Scale 的第 $(g, n)$ 个元素。 - `Zero` 是一个形状为 `( num_groups, N )` 的张量,$z_{g,n}$ 是 Zero 的第 $(g, n)$ 个元素。 -- `W` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $k \in [g \times group\_{}size, (g + 1) \times group\_{}size)$成立,其中 $group\_{}size = 128, K = num\_{}groups \times group\_{}size$ 。 +- `W` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $k \in [g \times \text{group}\_{}\text{size}, (g + 1) \times \text{group}\_{}\text{size})$ 成立,其中 $\text{group}\_{}\text{size} = 128$, K = $\text{num}\_{}\text{groups} \times \text{group}\_{}\text{size}$ 。 反量化过程如下所示: $$ - \hat{w}_{k,n} = (q_{k,n} - z_{g,n}) \times s_{g,n} + \hat{w}_{k,n} = (q_{k,n} - z_{g,n}) \times s_{g,n} $$ 最终得到计算结果,其中 $\hat{W}$ 是 $\hat{w}_{k,n}$ 构成的新矩阵。 @@ -28,7 +28,7 @@ - `A` 为左输入张量,形状为 `( M, K )`。 - `C` 为输出张量,形状为 `( M, N )`。 -实际操作过程中会将量化以后的结果以 int4 的方式存储在一个形状为 $(num\_{}groups, 2 \times N)$ ,数据类型为 int32_t 的中间矩阵中。 +实际操作过程中会将量化以后的结果以 int4 的方式存储在一个形状为 $(\text{num}\_{}\text{groups}, 2 \times N)$ ,数据类型为 int32_t 的中间矩阵中。 ## 接口 ### 计算 From b124f3edb6106e3adb31181e53b1e1640b8eeade Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Mon, 21 Apr 2025 20:14:26 +0800 Subject: [PATCH 3/9] modified math --- infiniop/ops/matmul_gptq/README.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md index b7f2493..224f641 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/matmul_gptq/README.md @@ -9,26 +9,22 @@ q_{k,n} = clip\left( \left\lfloor \frac{w_{k,n}}{s_{g,n}} + z_{g,n} \right\rfloor, -8, 7 \right) $$ -- `Scale` 是一个形状为 `( num_groups, N )` 的张量,$s_{g,n}$ 是 Scale 的第 $(g, n)$ 个元素。 -- `Zero` 是一个形状为 `( num_groups, N )` 的张量,$z_{g,n}$ 是 Zero 的第 $(g, n)$ 个元素。 -- `W` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $k \in [g \times \text{group}\_{}\text{size}, (g + 1) \times \text{group}\_{}\text{size})$ 成立,其中 $\text{group}\_{}\text{size} = 128$, K = $\text{num}\_{}\text{groups} \times \text{group}\_{}\text{size}$ 。 +- `Scale` 是一个形状为 `( num_groups, N )` 的张量, $s_{g,n}$ 是 Scale 的第 $(g, n)$ 个元素。 +- `Zero` 是一个形状为 `( num_groups, N )` 的张量, $z_{g,n}$ 是 Zero 的第 $(g, n)$ 个元素。 +- `W` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $g \times$ group_size $\leq k < (g + 1) \times$ group_size 成立,其中 group_size = 128 , K = num_groups $\times$ group_size 。 -反量化过程如下所示: - - $$ - \hat{w}_{k,n} = (q_{k,n} - z_{g,n}) \times s_{g,n} - $$ - -最终得到计算结果,其中 $\hat{W}$ 是 $\hat{w}_{k,n}$ 构成的新矩阵。 +最终得到计算结果: $$ C = A * \hat{W} $$ +其中 $\hat{W}$ 是 $(q_{k,n} - z_{g,n}) \times s_{g,n}$ 构成的新矩阵。 + - `A` 为左输入张量,形状为 `( M, K )`。 - `C` 为输出张量,形状为 `( M, N )`。 -实际操作过程中会将量化以后的结果以 int4 的方式存储在一个形状为 $(\text{num}\_{}\text{groups}, 2 \times N)$ ,数据类型为 int32_t 的中间矩阵中。 +实际操作过程中会将量化以后的结果以 int4 的方式存储在一个形状为 (num_groups, $2 \times N$) ,数据类型为 int32_t 的中间矩阵中。 ## 接口 ### 计算 From bf1df65efb4120a3cb8653e66aa169e3230381d8 Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Tue, 22 Apr 2025 10:08:49 +0800 Subject: [PATCH 4/9] add compute --- infiniop/ops/matmul_gptq/README.md | 64 +++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md index 224f641..92b9c72 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/matmul_gptq/README.md @@ -6,14 +6,16 @@ 其中量化过程如下所示: $$ - q_{k,n} = clip\left( \left\lfloor \frac{w_{k,n}}{s_{g,n}} + z_{g,n} \right\rfloor, -8, 7 \right) + q_{k,n} = clip\left( \left\lfloor \frac{b_{k,n}}{s_{g,n}} + z_{g,n} \right\rfloor, -8, 7 \right) $$ - `Scale` 是一个形状为 `( num_groups, N )` 的张量, $s_{g,n}$ 是 Scale 的第 $(g, n)$ 个元素。 - `Zero` 是一个形状为 `( num_groups, N )` 的张量, $z_{g,n}$ 是 Zero 的第 $(g, n)$ 个元素。 -- `W` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $g \times$ group_size $\leq k < (g + 1) \times$ group_size 成立,其中 group_size = 128 , K = num_groups $\times$ group_size 。 +- `B` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $g \times$ group_size $\leq k < (g + 1) \times$ group_size 成立,其中 group_size = 128 , K = num_groups $\times$ group_size 。 +- `Q` 是一个形状为 `( K / 16, 2N )` ,数据类型为 int32_t 的张量,一个元素存储 8 个 int4 类型的量化结果 $q_{k,n}$ 。 -最终得到计算结果: + +`Scale` 和 `Zero` 是 `B` 根据对应量化策略生成的张量,然后通过反量化过程得到计算结果: $$ C = A * \hat{W} @@ -24,11 +26,42 @@ - `A` 为左输入张量,形状为 `( M, K )`。 - `C` 为输出张量,形状为 `( M, N )`。 -实际操作过程中会将量化以后的结果以 int4 的方式存储在一个形状为 (num_groups, $2 \times N$) ,数据类型为 int32_t 的中间矩阵中。 ## 接口 ### 计算 +```c +infiniStatus_t infiniopMatmulGptqQuant( + infiniopMatmulGptqDescriptor_t desc, + void *workspace, + size_t workspace_size, + void *q, + void *b_scale, + void *zero, + const void *b, + void *stream +); +``` + +
参数:
+ +- `desc`: + 已使用 `infiniopCreateMatmulGptqDescriptor()` 初始化的算子描述符。 +- `workspace`: + 额外工作空间。 +- `workspace_size`: + `workspace` 的大小,单位:字节。 +- `q`: + 输出量化结果张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b_scale`: + 输出缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `zero`: + 输出零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b`: + 输入权重张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `stream`: + 计算流/队列。 + ```c infiniStatus_t infiniopMatmulGptq( infiniopMatmulGptqDescriptor_t desc, @@ -36,9 +69,9 @@ infiniStatus_t infiniopMatmulGptq( size_t workspace_size, void *c, const void *a, - const void *b, - const void *b_scale, - const void *zero, + void *q, + void *b_scale, + void *zero, void *stream ); ``` @@ -55,12 +88,12 @@ infiniStatus_t infiniopMatmulGptq( 计算输出结果。张量限制见[创建算子描述](#创建算子描述)部分。 - `a`: 左输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 -- `b`: - 右输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 -- `b_scale`: - 缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `q`: + 输入量化结果张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b_scale` - { dT | ( K, N) | (~) }: + 输入缩放因子张量。 - `zero`: - 零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 + 输入零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `stream`: 计算流/队列。 @@ -76,7 +109,7 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( infiniopMatmulGptqDescriptor_t *desc_ptr, infiniopTensorDescriptor_t c_desc, infiniopTensorDescriptor_t a_desc, - infiniopTensorDescriptor_t b_desc, + infiniopTensorDescriptor_t q_desc, infiniopTensorDescriptor_t b_scale_desc, infiniopTensorDescriptor_t zero_desc ); @@ -92,8 +125,8 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( 算子计算参数 `c` 的张量描述。 - `a_desc` - { dT | ( M, K) | (~) }: 算子计算参数 `a` 的张量描述。 -- `b_desc` - { dT | ( K, N) | (~) }: - 算子计算参数 `b` 的张量描述。 +- `q_desc` - { dI | ( K / 16, 2N) | (~) }: + 算子计算参数 `q` 的张量描述。 - `b_scale_desc` - { dT | ( num_groups, N) | (~) }: 算子计算参数 `b_scale` 的张量描述。 - `zero_desc` - { dT | ( num_groups, N) | (~) }: @@ -102,6 +135,7 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( 参数限制: - `dT`: (`Float16`, `Float32`) 之一。 +- `dI`: `Int4` 。
返回值:
From 5bf7e9b17f9649227e7986b5b12b4c1b6c74e97b Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Tue, 22 Apr 2025 10:14:59 +0800 Subject: [PATCH 5/9] modified b --- infiniop/ops/matmul_gptq/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md index 92b9c72..c2e31ca 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/matmul_gptq/README.md @@ -57,8 +57,8 @@ infiniStatus_t infiniopMatmulGptqQuant( 输出缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `zero`: 输出零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 -- `b`: - 输入权重张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b` - { dT | ( K, N) | (~) }: + 输入权重张量。 - `stream`: 计算流/队列。 @@ -90,8 +90,8 @@ infiniStatus_t infiniopMatmulGptq( 左输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `q`: 输入量化结果张量。张量限制见[创建算子描述](#创建算子描述)部分。 -- `b_scale` - { dT | ( K, N) | (~) }: - 输入缩放因子张量。 +- `b_scale`: + 输入缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `zero`: 输入零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `stream`: From 1a4db3f114a5a7e36e9f4131f0d53979211af228 Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Sun, 27 Apr 2025 11:25:46 +0800 Subject: [PATCH 6/9] success gptq --- infiniop/ops/matmul_gptq/README.md | 31 +++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md index c2e31ca..c63d094 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/matmul_gptq/README.md @@ -6,29 +6,38 @@ 其中量化过程如下所示: $$ - q_{k,n} = clip\left( \left\lfloor \frac{b_{k,n}}{s_{g,n}} + z_{g,n} \right\rfloor, -8, 7 \right) + q_{n, k} = clip\left( \left\lfloor \frac{w_{n, k}}{s_{n, g}} + z_{n, g} \right\rfloor, 0, 15 \right) $$ -- `Scale` 是一个形状为 `( num_groups, N )` 的张量, $s_{g,n}$ 是 Scale 的第 $(g, n)$ 个元素。 -- `Zero` 是一个形状为 `( num_groups, N )` 的张量, $z_{g,n}$ 是 Zero 的第 $(g, n)$ 个元素。 -- `B` 是一个形状为 `( K, N )` 的张量,上面这个公式对于 $g \times$ group_size $\leq k < (g + 1) \times$ group_size 成立,其中 group_size = 128 , K = num_groups $\times$ group_size 。 -- `Q` 是一个形状为 `( K / 16, 2N )` ,数据类型为 int32_t 的张量,一个元素存储 8 个 int4 类型的量化结果 $q_{k,n}$ 。 +- `Scale` 是一个形状为 `( N, num_groups )` 的张量, $s_{n, g}$ 是 `Scale` 的第 $(n, g)$ 个元素。 +- `Zero` 是一个形状为 `( N, num_groups )` 的张量, $z_{n, g}$ 是 `Zero` 的第 $(n, g)$ 个元素。 +- `W` 是一个形状为 `( N, K )` 的权重张量,如果 num_groups > 1 ,上面这个公式对于 $g \times$ group_size $\leq k < (g + 1) \times$ group_size 成立,其中 group_size = K / num_groups 。当 num_groups = 1 时,上述公式对于 $0 \leq k \leq K - 1$ 成立。 +- `Q` 是一个形状为 `( 2N, K / 16 )` ,数据类型为 int32_t 的张量,一个元素存储 8 个 int4 类型的量化结果 $q_{n, k}$ 。 -`Scale` 和 `Zero` 是 `B` 根据对应量化策略生成的张量,然后通过反量化过程得到计算结果: +`Scale` , `Zero` 和 `Q` 是根据权重 `W` 和输入张量 `X` 生成的缩放因子和零点, `Scale` 和 `Zero` 的生成方式大体如下所示: $$ - C = A * \hat{W} + s_{n, g} = \frac{\max_{k} \{w_{n, k} \} - \min_{k} \{w_{n, k} \}}{15}, \\ + z_{n, g} = \left\lfloor \frac{- \min_{k} \{w_{n, k}\}}{s_{n, g}} \right\rfloor $$ -其中 $\hat{W}$ 是 $(q_{k,n} - z_{g,n}) \times s_{g,n}$ 构成的新矩阵。 +有了缩放因子和零点以后,量化过程还需要不断调整权重 `W` 的元素,具体调整方式参考 https://zhuanlan.zhihu.com/p/692338716 -- `A` 为左输入张量,形状为 `( M, K )`。 -- `C` 为输出张量,形状为 `( M, N )`。 +这个算法希望找到一个量化过的权重 $\hat{W}$ ,使得新权重和旧权重之间输出结果差别最小,即: + + $$ + \arg \min_{\hat{W}} || \hat{W}X - WX||^2 + $$ + +其中 $\hat{W}$ 是 $(q_{n,k} - z_{n,g}) \times s_{n,g}$ 构成的量化权重张量。 + +- `X` 为输入张量,形状为 `( K, M )`。 +- `C` 为输出张量,存储计算结果 $\hat{W}X$ ,形状为 `( N, M )`。 ## 接口 -### 计算 +### 量化 ```c infiniStatus_t infiniopMatmulGptqQuant( From f9586334fb4a924244610c734b9718c5c7dcd4bb Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Tue, 29 Apr 2025 17:22:04 +0800 Subject: [PATCH 7/9] modified docs --- infiniop/ops/matmul_gptq/README.md | 35 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/matmul_gptq/README.md index c63d094..bbd3d34 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/matmul_gptq/README.md @@ -12,17 +12,17 @@ - `Scale` 是一个形状为 `( N, num_groups )` 的张量, $s_{n, g}$ 是 `Scale` 的第 $(n, g)$ 个元素。 - `Zero` 是一个形状为 `( N, num_groups )` 的张量, $z_{n, g}$ 是 `Zero` 的第 $(n, g)$ 个元素。 - `W` 是一个形状为 `( N, K )` 的权重张量,如果 num_groups > 1 ,上面这个公式对于 $g \times$ group_size $\leq k < (g + 1) \times$ group_size 成立,其中 group_size = K / num_groups 。当 num_groups = 1 时,上述公式对于 $0 \leq k \leq K - 1$ 成立。 -- `Q` 是一个形状为 `( 2N, K / 16 )` ,数据类型为 int32_t 的张量,一个元素存储 8 个 int4 类型的量化结果 $q_{n, k}$ 。 +- `Q` 是一个形状为 `( N, K / 8 )` ,数据类型为 int32_t 的张量,一个元素存储 8 个 int4 类型的量化结果 $q_{n, k}$ 。 -`Scale` , `Zero` 和 `Q` 是根据权重 `W` 和输入张量 `X` 生成的缩放因子和零点, `Scale` 和 `Zero` 的生成方式大体如下所示: +`Scale` , `Zero` 是根据权重 `W` 生成的缩放因子和零点, `Scale` 和 `Zero` 的生成方式大体如下所示: $$ s_{n, g} = \frac{\max_{k} \{w_{n, k} \} - \min_{k} \{w_{n, k} \}}{15}, \\ z_{n, g} = \left\lfloor \frac{- \min_{k} \{w_{n, k}\}}{s_{n, g}} \right\rfloor $$ -有了缩放因子和零点以后,量化过程还需要不断调整权重 `W` 的元素,具体调整方式参考 https://zhuanlan.zhihu.com/p/692338716 +关于一些细节的补充可以参考 https://zhuanlan.zhihu.com/p/692338716 ,源代码参考 https://github.com/IST-DASLab/gptq 。 这个算法希望找到一个量化过的权重 $\hat{W}$ ,使得新权重和旧权重之间输出结果差别最小,即: @@ -40,13 +40,14 @@ ### 量化 ```c -infiniStatus_t infiniopMatmulGptqQuant( +infiniStatus_t infiniopMatmulQuant( infiniopMatmulGptqDescriptor_t desc, void *workspace, size_t workspace_size, - void *q, + void *packed_weights, void *b_scale, void *zero, + const void *a, const void *b, void *stream ); @@ -60,17 +61,21 @@ infiniStatus_t infiniopMatmulGptqQuant( 额外工作空间。 - `workspace_size`: `workspace` 的大小,单位:字节。 -- `q`: +- `packed_weights`: 输出量化结果张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `b_scale`: 输出缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `zero`: 输出零点张量。张量限制见[创建算子描述](#创建算子描述)部分。 -- `b` - { dT | ( K, N) | (~) }: +- `a`: + 输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 +- `b` - { dT | ( N, K) | (~) }: 输入权重张量。 - `stream`: 计算流/队列。 +### 计算 + ```c infiniStatus_t infiniopMatmulGptq( infiniopMatmulGptqDescriptor_t desc, @@ -78,7 +83,7 @@ infiniStatus_t infiniopMatmulGptq( size_t workspace_size, void *c, const void *a, - void *q, + void *packed_weights, void *b_scale, void *zero, void *stream @@ -97,7 +102,7 @@ infiniStatus_t infiniopMatmulGptq( 计算输出结果。张量限制见[创建算子描述](#创建算子描述)部分。 - `a`: 左输入张量。张量限制见[创建算子描述](#创建算子描述)部分。 -- `q`: +- `packed_weights`: 输入量化结果张量。张量限制见[创建算子描述](#创建算子描述)部分。 - `b_scale`: 输入缩放因子张量。张量限制见[创建算子描述](#创建算子描述)部分。 @@ -118,7 +123,7 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( infiniopMatmulGptqDescriptor_t *desc_ptr, infiniopTensorDescriptor_t c_desc, infiniopTensorDescriptor_t a_desc, - infiniopTensorDescriptor_t q_desc, + infiniopTensorDescriptor_t packed_weights_desc, infiniopTensorDescriptor_t b_scale_desc, infiniopTensorDescriptor_t zero_desc ); @@ -130,15 +135,15 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( : 硬件控柄。详见 [`InfiniopHandle_t`]。 - `desc_ptr`: `infiniopMatmulGptqDescriptor_t` 指针,指向将被初始化的算子描述符地址。 -- `c_desc` - { dT | ( M, N) | (~) }: +- `c_desc` - { dT | ( N, M) | (~) }: 算子计算参数 `c` 的张量描述。 -- `a_desc` - { dT | ( M, K) | (~) }: +- `a_desc` - { dT | ( K, M) | (~) }: 算子计算参数 `a` 的张量描述。 -- `q_desc` - { dI | ( K / 16, 2N) | (~) }: +- `packed_weights_desc` - { dI | ( N, K / 8) | (~) }: 算子计算参数 `q` 的张量描述。 -- `b_scale_desc` - { dT | ( num_groups, N) | (~) }: +- `b_scale_desc` - { dT | ( N, num_groups) | (~) }: 算子计算参数 `b_scale` 的张量描述。 -- `zero_desc` - { dT | ( num_groups, N) | (~) }: +- `zero_desc` - { dT | ( N, num_groups) | (~) }: 算子计算参数 `zero` 的张量描述。 参数限制: From 4507f8b97e4402f42715951b02da4cf4b85656a9 Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Mon, 12 May 2025 15:54:08 +0800 Subject: [PATCH 8/9] modified QuantizeGPTQ --- .../{matmul_gptq => QuantizeGPTQ}/README.md | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) rename infiniop/ops/{matmul_gptq => QuantizeGPTQ}/README.md (75%) diff --git a/infiniop/ops/matmul_gptq/README.md b/infiniop/ops/QuantizeGPTQ/README.md similarity index 75% rename from infiniop/ops/matmul_gptq/README.md rename to infiniop/ops/QuantizeGPTQ/README.md index bbd3d34..fd15cba 100644 --- a/infiniop/ops/matmul_gptq/README.md +++ b/infiniop/ops/QuantizeGPTQ/README.md @@ -1,7 +1,7 @@ -# `MatmulGptq` +# `QuantizeGPTQ` -`MatmulGptq (Matmul Gradient Pre-Trained Quantization)`, 是一种针对大语言模型的高效后量化方法,旨在将模型权重从高精度(如 f16)量化为低精度(如 int4),同时最小化量化误差对模型性能的影响。 +`QuantizeGPTQ (Quantize Gradient Pre-Trained Quantization)`, 是一种针对大语言模型的高效后量化方法,旨在将模型权重从高精度(如 f16)量化为低精度(如 int4),同时最小化量化误差对模型性能的影响。 其中量化过程如下所示: @@ -15,22 +15,20 @@ - `Q` 是一个形状为 `( N, K / 8 )` ,数据类型为 int32_t 的张量,一个元素存储 8 个 int4 类型的量化结果 $q_{n, k}$ 。 -`Scale` , `Zero` 是根据权重 `W` 生成的缩放因子和零点, `Scale` 和 `Zero` 的生成方式大体如下所示: +`Scale` , `Zero` 是根据权重 `W` 生成的缩放因子和零点,非对称量化对应的 `Scale` 和 `Zero` 的生成方式大体如下所示: $$ s_{n, g} = \frac{\max_{k} \{w_{n, k} \} - \min_{k} \{w_{n, k} \}}{15}, \\ z_{n, g} = \left\lfloor \frac{- \min_{k} \{w_{n, k}\}}{s_{n, g}} \right\rfloor $$ -关于一些细节的补充可以参考 https://zhuanlan.zhihu.com/p/692338716 ,源代码参考 https://github.com/IST-DASLab/gptq 。 - -这个算法希望找到一个量化过的权重 $\hat{W}$ ,使得新权重和旧权重之间输出结果差别最小,即: +`QuantizeGPTQ` 是在 `OBD (Optimal Brain Damage)` , `OBS (Optimal Brain Surgeon)` 和 `OBQ (Optimal Brain Quantizer)` 基础上,对所有的行使用同样的顺序量化,这个算法希望找到一个量化过的权重 $\hat{W}$ ,使得新权重和旧权重之间输出结果差别最小,即: $$ \arg \min_{\hat{W}} || \hat{W}X - WX||^2 $$ -其中 $\hat{W}$ 是 $(q_{n,k} - z_{n,g}) \times s_{n,g}$ 构成的量化权重张量。 +具体量化过程需要引入海森矩阵 $H = 2XX^T$ ,进而计算出 $H^{-1}$ ,假设权重矩阵分为若干块,每一块的大小为 $B \times K$ ,当更新到第 $i$ 块第 $j$ 行的时候,更新权重 $W_{:,i \times B + j :} -= ((W_{:,i \times B:(i + 1) \times B} - \hat{W}_{:,i \times B:(i + 1) \times B}) / H^{-1}_{:,i \times B:(i + 1) \times B}) H^{-1}_{i \times B:(i + 1) \times B, i \times B + j :}$ ,其中 $\hat{W}$ 是 $(q_{n,k} - z_{n,g}) \times s_{n,g}$ 构成的量化权重张量。 - `X` 为输入张量,形状为 `( K, M )`。 - `C` 为输出张量,存储计算结果 $\hat{W}X$ ,形状为 `( N, M )`。 @@ -40,8 +38,8 @@ ### 量化 ```c -infiniStatus_t infiniopMatmulQuant( - infiniopMatmulGptqDescriptor_t desc, +infiniStatus_t infiniopQuantizeGPTQ( + infiniopQuantizeGPTQDescriptor_t desc, void *workspace, size_t workspace_size, void *packed_weights, @@ -56,7 +54,7 @@ infiniStatus_t infiniopMatmulQuant(
参数:
- `desc`: - 已使用 `infiniopCreateMatmulGptqDescriptor()` 初始化的算子描述符。 + 已使用 `infiniopCreateQuantizeGPTQDescriptor()` 初始化的算子描述符。 - `workspace`: 额外工作空间。 - `workspace_size`: @@ -77,8 +75,8 @@ infiniStatus_t infiniopMatmulQuant( ### 计算 ```c -infiniStatus_t infiniopMatmulGptq( - infiniopMatmulGptqDescriptor_t desc, +infiniStatus_t infiniopQuantizeLinearGPTQ( + infiniopQuantizeGPTQDescriptor_t desc, void *workspace, size_t workspace_size, void *c, @@ -93,7 +91,7 @@ infiniStatus_t infiniopMatmulGptq(
参数:
- `desc`: - 已使用 `infiniopCreateMatmulGptqDescriptor()` 初始化的算子描述符。 + 已使用 `infiniopCreateQuantizeGPTQDescriptor()` 初始化的算子描述符。 - `workspace`: 额外工作空间。 - `workspace_size`: @@ -118,9 +116,9 @@ infiniStatus_t infiniopMatmulGptq( ### 创建算子描述 ```c -infiniStatus_t infiniopCreateMatmulGptqDescriptor( +infiniStatus_t infiniopCreateQuantizeLinearGPTQDescriptor( infiniopHandle_t handle, - infiniopMatmulGptqDescriptor_t *desc_ptr, + infiniopQuantizeGPTQDescriptor_t *desc_ptr, infiniopTensorDescriptor_t c_desc, infiniopTensorDescriptor_t a_desc, infiniopTensorDescriptor_t packed_weights_desc, @@ -134,7 +132,7 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( - `handle` : 硬件控柄。详见 [`InfiniopHandle_t`]。 - `desc_ptr`: - `infiniopMatmulGptqDescriptor_t` 指针,指向将被初始化的算子描述符地址。 + `infiniopQuantizeGPTQDescriptor_t` 指针,指向将被初始化的算子描述符地址。 - `c_desc` - { dT | ( N, M) | (~) }: 算子计算参数 `c` 的张量描述。 - `a_desc` - { dT | ( K, M) | (~) }: @@ -158,8 +156,8 @@ infiniStatus_t infiniopCreateMatmulGptqDescriptor( ### 计算额外工作空间 ```c -infiniStatus_t infiniopGetMatmulGptqWorkspaceSize( - infiniopMatmulGptqDescriptor_t desc, +infiniStatus_t infiniopGetQuantizeGPTQWorkspaceSize( + infiniopQuantizeGPTQDescriptor_t desc, size_t *size ); ``` @@ -167,7 +165,7 @@ infiniStatus_t infiniopGetMatmulGptqWorkspaceSize(
参数:
- `desc`: - 已使用 `infiniopCreateMatmulGptqDescriptor()` 初始化的算子描述符。 + 已使用 `infiniopCreateQuantizeGPTQDescriptor()` 初始化的算子描述符。 - `size`: 额外空间大小的计算结果的写入地址。 @@ -178,8 +176,8 @@ infiniStatus_t infiniopGetMatmulGptqWorkspaceSize( ### 销毁算子描述符 ```c -infiniStatus_t infiniopDestroyMatmulGptqDescriptor( - infiniopMatmulGptqDescriptor_t desc +infiniStatus_t infiniopDestroyQuantizeGPTQDescriptor( + infiniopQuantizeGPTQDescriptor_t desc ); ``` From d987819ca244cb5c02840214b96d8c9885a89df1 Mon Sep 17 00:00:00 2001 From: xgqdut2016 Date: Mon, 12 May 2025 16:33:26 +0800 Subject: [PATCH 9/9] modified math --- infiniop/ops/QuantizeGPTQ/README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/infiniop/ops/QuantizeGPTQ/README.md b/infiniop/ops/QuantizeGPTQ/README.md index fd15cba..7083159 100644 --- a/infiniop/ops/QuantizeGPTQ/README.md +++ b/infiniop/ops/QuantizeGPTQ/README.md @@ -28,7 +28,17 @@ \arg \min_{\hat{W}} || \hat{W}X - WX||^2 $$ -具体量化过程需要引入海森矩阵 $H = 2XX^T$ ,进而计算出 $H^{-1}$ ,假设权重矩阵分为若干块,每一块的大小为 $B \times K$ ,当更新到第 $i$ 块第 $j$ 行的时候,更新权重 $W_{:,i \times B + j :} -= ((W_{:,i \times B:(i + 1) \times B} - \hat{W}_{:,i \times B:(i + 1) \times B}) / H^{-1}_{:,i \times B:(i + 1) \times B}) H^{-1}_{i \times B:(i + 1) \times B, i \times B + j :}$ ,其中 $\hat{W}$ 是 $(q_{n,k} - z_{n,g}) \times s_{n,g}$ 构成的量化权重张量。 +具体量化过程需要引入海森逆矩阵 $H = (2XX^T)^{-1}$ ,假设权重矩阵分为若干块,每一块的大小为 $B \times K$ ,当更新到第 $i$ 块第 $j$ 行的时候,更新权重 + + $$ +W_{:,i \times B + j :} -= (E_{:, i \times B:(i + 1) \times B} / H_{:,i \times B:(i + 1) \times B}) H_{i \times B:(i + 1) \times B, i \times B + j :} + $$ + + $$ +E_{:, i \times B:(i + 1) \times B} = (W_{:,i \times B:(i + 1) \times B} - \hat{W}_{:,i \times B:(i + 1) \times B}) + $$ + +其中 $\hat{W}$ 是 $(q_{n,k} - z_{n,g}) \times s_{n,g}$ 构成的量化权重张量。 - `X` 为输入张量,形状为 `( K, M )`。 - `C` 为输出张量,存储计算结果 $\hat{W}X$ ,形状为 `( N, M )`。