反量化:反量化Q8零(q8_0)

反量化Q8零.h

cpp 复制代码
// 反量化Q8零.h ------ q8_0 量化块的反量化(8 位量化,无零偏移)
// 用途:把 q8_0 块(1 个 f16 缩放 + 32 个 int8 量化值)转为 f32 输出。
// 布局(实测确认):每块 32 元素、34 字节:d(f16, 2B) + q[32×int8, 32B]

#pragma once

// 引入基础类型(浮点/索引)
#include "公共/基础定义.h"

// 半精度转浮点:把 IEEE-754 半精度(16 位)位模式转为单精度浮点
// 说明:GGUF 文件里的缩放是 IEEE-754 半精度(1 符号位 + 5 指数位 + 10 尾数位),
//       C++ 不保证有原生的 _Float16,故用手动位操作实现(见 .cpp 内详解)
浮点 半精度转浮点(uint16_t 位);

// 反量化Q8零块:把一个 q8_0 量化块反量化为 f32
// 参数:块 = 量化数据起点(34 字节);输出 = f32 输出缓冲区(容量 ≥ 元素数);元素数 = 32
// 公式(文档注释):x_i = q_i · d,其中 q_i 是第 i 个 int8 量化值,d 是块缩放
void 反量化Q8零块(const uint8_t* 块, float* 输出, size_t 元素数);

反量化Q8零.cpp

cpp 复制代码
// 反量化Q8零.cpp ------ q8_0 量化块的反量化实现
// 用途:把 q8_0 块(1 个 f16 缩放 + 32 个 int8 量化值)转为 f32 输出。
// 布局:d(f16, 2B) + 32×int8 = 34 字节;每块 32 元素;x = q·d

#include "内核/反量化/反量化Q8零.h"

// 半精度转浮点:把 IEEE-754 半精度(16 位)位模式转为单精度浮点
// IEEE-754 半精度布局:1 符号位 | 5 指数位 | 10 尾数位
//   - 指数 = 0 且尾数 = 0:±0
//   - 指数 = 0 且尾数 ≠ 0:次正规数,值 = (-1)^符号 × 尾数 × 2^-24
//   - 指数 = 31 且尾数 = 0:±∞
//   - 指数 = 31 且尾数 ≠ 0:NaN(非数)
//   - 其余:正规数,值 = (-1)^符号 × (1 + 尾数/1024) × 2^(指数-15)
浮点 半精度转浮点(uint16_t 位) {
    // 符号位:第 15 位
    const 无符号 符号 = (位 >> 15) & 1;
    // 指数:第 14~10 位
    const 无符号 指数 = (位 >> 10) & 0x1F;
    // 尾数:第 9~0 位
    const 无符号 尾数 = 位 & 0x3FF;

    // 指数 0:零或次正规数(值 = 尾数 × 2^-24)
    if (指数 == 0) {
        // 5.9604645e-8 = 2^-24(单精度下的次正规最小步长)
        return 符号 ? -尾数 * 5.9604645e-8f : 尾数 * 5.9604645e-8f;
    }
    // 指数 31:无穷或 NaN
    if (指数 == 31) {
        if (尾数 == 0) {
            return 符号 ? -std::numeric_limits<浮点>::infinity()
                        : std::numeric_limits<浮点>::infinity();
        }
        return std::numeric_limits<浮点>::quiet_NaN();
    }
    // 正规数:(1 + 尾数/1024) × 2^(指数-15),符号另乘
    const 浮点 值 = (1.0f + 尾数 / 1024.0f) * std::pow(2.0f, static_cast<int>(指数) - 15);
    return 符号 ? -值 : 值;
}

// 反量化Q8零块:把一个 q8_0 量化块反量化为 f32
// 实现:读前 2 字节为 f16 缩放 d(小端),随后 32 字节为 int8 量化值;
//       对每个元素 x_i = q_i × d(int8 先有符号扩展到 f32 再乘)
void 反量化Q8零块(const uint8_t* 块, float* 输出, size_t 元素数) {
    // 解析 f16 缩放:小端两字节拼成 16 位模式
    const uint16_t 缩放位 = static_cast<uint16_t>(块[0] | (块[1] << 8));
    const 浮点 d = 半精度转浮点(缩放位);
    // 逐个元素反量化:q_i(int8 有符号)× d
    for (size_t i = 0; i < 元素数; ++i) {
        const int8_t q = static_cast<int8_t>(块[2 + i]);
        输出[i] = static_cast<浮点>(q) * d;
    }
}
相关推荐
Huazhongzhanhui4 分钟前
从柔性裁切到模内装饰!2026武汉国际汽车内外饰展会定档九月
人工智能
萝萝仔9 分钟前
02.人工智能训练师三级是什么?谁适合考?考了有什么用?
人工智能·深度学习·机器学习·ai·云计算
在学了加油9 分钟前
阿尔茨海默病诊断(优化特征选择版)
人工智能·python·dnn
水管在开花.13 分钟前
Agent范式与LangGraph-②零基础保姆级教程
人工智能·面试·langchain·agent
白色机械键盘25 分钟前
LangGPT结构化提示词工程:从手写提示词到模块化编程的范式升级
人工智能
熙丫 1338148238628 分钟前
AI前沿部署工程师(FDE)适合谁考?工信部教考中心高级证书,打通大模型落地最后一公里
人工智能
ShallWeL35 分钟前
RAG 文档变更后的检索回归清单
人工智能·agent·知识库·rag·检索
Hrain-AI36 分钟前
企业 AI 治理运营怎么做:分级授权、Token 用量可观测与模型统一纳管
大数据·人工智能·算法
2401_8652616340 分钟前
亦唐科技:创新驱动下的国产贴片机领航者
人工智能
Mr数据杨40 分钟前
【CanMV K210】硬件基础 面包板连通规则与无焊接电路搭建
人工智能·硬件开发·canmv k210