尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

反量化:反量化K类(q4_k、q5_k、q6_k)

反量化:反量化K类(q4_k、q5_k、q6_k) 反量化K类.h// 反量化K类.h —— K 系量化块q4_k/q5_k/q6_k的反量化// 用途把 K 系量化块每块 256 元素转为 f32 输出。// 布局本任务实测确认// q4_k(144B)d(f16)dmin(f16)scales[12]qs[128]8 组 × 32 元素x d·sc·q − dmin·m// q5_k(176B)ddminscales[12]qh[32]qs[128]8 组 × 32 元素q5 含第 5 位// q6_k(210B)ql[128]qh[64]scales[16 有符号]d(f16块末尾)16 组 × 16 元素无 dmin#pragmaonce// 引入基础类型浮点/索引#include公共/基础定义.h// 反量化Q4K块把一个 q4_k 量化块256 元素、144 字节反量化为 f32// 公式x (q4 · 组缩放) − dmin·m组缩放 d·scsc 是 6 位组缩放码void反量化Q4K块(constuint8_t*块,float*输出,size_t 元素数);// 反量化Q5K块把一个 q5_k 量化块256 元素、176 字节反量化为 f32// 公式x (q5 · 组缩放) − dmin·mq5 低4位 | (qh 第5位 × 16)void反量化Q5K块(constuint8_t*块,float*输出,size_t 元素数);// 反量化Q6K块把一个 q6_k 量化块256 元素、210 字节反量化为 f32// 公式x d·sc·(q6 − 32)q6 6 位值低4位 | 高2位×16sc 是 8 位有符号组缩放void反量化Q6K块(constuint8_t*块,float*输出,size_t 元素数);反量化K类.cpp// 反量化K类.cpp —— K 系量化块q4_k/q5_k/q6_k的反量化实现// 用途把 K 系量化块每块 256 元素转为 f32 输出。// 布局本任务实测确认勿凭旧注释/stock 结构// q4_k(144B)d(f16)dmin(f16)scales[12]qs[128]8 组 × 32 元素// q5_k(176B)ddminscales[12]qh[32]qs[128]// q6_k(210B)ql[128]qh[64]scales[16 有符号]d(f16块末尾)无 dmin#include内核/反量化/反量化K类.h#include内核/反量化/反量化Q8零.h// 引入错误处理元素数校验抛运行错误#include公共/错误处理.h// 引入标准头浮点幂/极限#includecmath#includelimits// 取缩放最小解出第 j 组0..7的 6 位组缩放码与 6 位最小码// 说明scales[12] 打包 8 个 6 位缩放 8 个 6 位最小。j4 时两组分别存于// scales[j] 与 scales[j4] 的低 6 位j4 时高 4 位被拆分// scales[j4] 低 4 位为缩放低 4 位、高 4 位为最小低 4 位// scales[j-4] 高 2 位为缩放高 2 位、scales[j] 高 2 位为最小高 2 位staticvoid取缩放最小(intj,constuint8_t*scales,uint8_t缩放,uint8_t最小){if(j4){缩放scales[j]63;最小scales[j4]63;}else{缩放static_castuint8_t((scales[j4]0xF)|((scales[j-4]6)4));最小static_castuint8_t((scales[j4]4)|((scales[j]6)4));}}// 反量化Q4K块把一个 q4_k 量化块256 元素、144 字节反量化为 f32// 布局d(2)dmin(2)scales(12)qs(128)。8 组 × 32 元素每组一个 6 位缩放码与最小码。// 数据排列每 64 元素为一个 chunk32 字节 qs组 2j 用字节低半字节、组 2j1 用高半字节// 公式x d·sc·q − dmin·mvoid反量化Q4K块(constuint8_t*块,float*输出,size_t 元素数){// K 系块固定每块 256 元素防御元素数不符直接抛错if(元素数!256){抛出运行错误(Q4K块 元素数必须为 256);}// 块头d(f16) dmin(f16)const浮点 d半精度转浮点(static_castuint16_t(块[0]|(块[1]8)));const浮点 整体最小半精度转浮点(static_castuint16_t(块[2]|(块[3]8)));constuint8_t*scales块4;constuint8_t*qs块16;// 4 个 chunk每个 64 元素、32 字节 qs、2 组缩放for(intc0;c4;c){uint8_ts0,m0,s1,m1;取缩放最小(c*20,scales,s0,m0);取缩放最小(c*21,scales,s1,m1);const浮点 d1d*s0,最小1整体最小*m0;const浮点 d2d*s1,最小2整体最小*m1;constuint8_t*qqsc*32;// 组 2c低半字节x d1·q − 最小1for(intl0;l32;l){输出[c*64l]d1*(q[l]0xF)-最小1;}// 组 2c1高半字节x d2·q − 最小2for(intl0;l32;l){输出[c*6432l]d2*(q[l]4)-最小2;}}}// 反量化Q5K块把一个 q5_k 量化块256 元素、176 字节反量化为 f32// 布局d(2)dmin(2)scales(12)qh(32)qs(128)。8 组 × 32 元素。// q5 低 4 位qs | 第 5 位qh每 chunk 用 qh[l] 的 u1/u2 位起始 1/2每 chunk 左移 2// 公式x d·sc·q5 − dmin·mvoid反量化Q5K块(constuint8_t*块,float*输出,size_t 元素数){// K 系块固定每块 256 元素防御元素数不符直接抛错if(元素数!256){抛出运行错误(Q5K块 元素数必须为 256);}// 块头d(f16) dmin(f16)const浮点 d半精度转浮点(static_castuint16_t(块[0]|(块[1]8)));const浮点 整体最小半精度转浮点(static_castuint16_t(块[2]|(块[3]8)));constuint8_t*scales块4;constuint8_t*qh块16;constuint8_t*qs块48;// 4 个 chunku1/u2 是 qh[l] 中对应第 5 位的掩码每 chunk 左移 2uint8_tu11,u22;for(intc0;c4;c){uint8_ts0,m0,s1,m1;取缩放最小(c*20,scales,s0,m0);取缩放最小(c*21,scales,s1,m1);const浮点 d1d*s0,最小1整体最小*m0;const浮点 d2d*s1,最小2整体最小*m1;constuint8_t*qqsc*32;// 组 2c低半字节 qh 第 5 位for(intl0;l32;l){const浮点 q5astatic_cast浮点((q[l]0xF)((qh[l]u1)?16:0));输出[c*64l]d1*q5a-最小1;}// 组 2c1高半字节 qh 第 5 位for(intl0;l32;l){const浮点 q5bstatic_cast浮点((q[l]4)((qh[l]u2)?16:0));输出[c*6432l]d2*q5b-最小2;}u1static_castuint8_t(u12);u2static_castuint8_t(u22);}}// 反量化Q6K块把一个 q6_k 量化块256 元素、210 字节反量化为 f32// 布局ql(128)qh(64)scales(16 有符号)d(f16块末尾)。16 组 × 16 元素无 dmin。// 数据每 128 元素为一半q1/q2 用 ql 低半字节、q3/q4 用高半字节qh 每字节 8 元素各 2 位// 公式x d·sc·(q6 − 32)q6 6 位值低4位 | 高2位×16void反量化Q6K块(constuint8_t*块,float*输出,size_t 元素数){// K 系块固定每块 256 元素防御元素数不符直接抛错if(元素数!256){抛出运行错误(Q6K块 元素数必须为 256);}// d 在块末尾字节 208~209const浮点 d半精度转浮点(static_castuint16_t(块[208]|(块[209]8)));constuint8_t*ql块;constuint8_t*qh块128;constint8_t*screinterpret_castconstint8_t*(块192);// 2 个 128 元素一半ql 每半 64 字节、qh 每半 32 字节、scales 每半 8 个for(intn0;n2;n){for(intl0;l32;l){// is 确定缩放下标所在半组每 16 元素一组constintisl/16;// 四种元素低/高半字节 × 前/后 32 字节各取 qh 中 2 位constint8_tq1static_castint8_t((ql[n*64l]0xF)|(((qh[n*32l]0)3)4))-32;constint8_tq2static_castint8_t((ql[n*64l32]0xF)|(((qh[n*32l]2)3)4))-32;constint8_tq3static_castint8_t((ql[n*64l]4)|(((qh[n*32l]4)3)4))-32;constint8_tq4static_castint8_t((ql[n*64l32]4)|(((qh[n*32l]6)3)4))-32;// 输出按元素序直接下标写入q1→l0q2→l32q3→l64q4→l96输出[n*128l0]d*sc[n*8is0]*q1;输出[n*128l32]d*sc[n*8is2]*q2;输出[n*128l64]d*sc[n*8is4]*q3;输出[n*128l96]d*sc[n*8is6]*q4;}}}
返回列表