反量化:反量化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;
    }
}
相关推荐
释厄6236 分钟前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
xzlAwin27 分钟前
Win10 安装OpenClaw 龙虾
ai·openclaw·龙虾
老金带你玩AI1 小时前
集万家所长,一键复制的Agent.md!
人工智能
ZhuoAIStage1 小时前
舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线
人工智能·自动化·工作流编排·舞台工艺·审图智能体
小奶包他干奶奶1 小时前
AI学习——1、机器学习概念
人工智能·机器学习
展讯快报1 小时前
悬浮提词器免费App评估报告:说得AI的免费策略与可用性分析
人工智能
Yuzhiyuxia1 小时前
【AI Agent面试系列】AI Agent记忆机制知识点1
人工智能·面试·职场和发展
2601_965448872 小时前
AI视频制作:做系列历史人物视频音色不搭,AI 音色克隆的方法实测
人工智能·音视频
UIU1142 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
2分钟速写快排2 小时前
ggg! 潜行摸鱼被 Trae 爆改成 3D!
人工智能·程序员·数据可视化