// requant_trunk.c — Surgical GGUF rewriter for Kimi-K3 UD-Q4_K_XL. // // Requantizes ONLY the Q8_0 "trunk" tensors (attention, shared experts, output, // token embedding) from Q8_0 -> Q4_K. Byte-copies everything else unchanged: // - MXFP4 routed-expert tensors (ffn_*_exps) : QAT-native, must NOT requant // - F32/BF16 norm & bias tensors : tiny, keep full precision // // Why not llama-quantize? In --allow-requantize mode it forces EVERY non-overridden // tensor to the positional type, which would dequant->requant the MXFP4 experts and // destroy their QAT calibration. We must byte-preserve the experts. // // Processes one shard at a time (split-in = split-out, like --keep-split). // // Build (on box): // gcc -O2 -o requant_trunk requant_trunk.c \ // -I/root/llama.cpp/ggml/include -I/root/llama.cpp/ggml/src \ // /root/llama.cpp/build/ggml/src/libggml-base.a \ // /root/llama.cpp/build/ggml/src/libggml-cpu.a \ // /root/llama.cpp/build/ggml/src/libggml.a -lm -lpthread // // Usage: requant_trunk // #include #include #include #include #include #include "ggml.h" #include "ggml-quants.h" #define GGUF_MAGIC 0x46554747 // "GGUF" #define ALIGNMENT 32 // ---- little-endian read helpers ---- static uint32_t rd_u32(FILE *f){ uint32_t v; if(fread(&v,4,1,f)!=1){fprintf(stderr,"EOF u32\n");exit(1);} return v; } static uint64_t rd_u64(FILE *f){ uint64_t v; if(fread(&v,8,1,f)!=1){fprintf(stderr,"EOF u64\n");exit(1);} return v; } // ---- write helpers (dynamic buffer for header) ---- typedef struct { uint8_t *data; size_t len, cap; } Buf; static void buf_put(Buf *b, const void *p, size_t n){ if (b->len + n > b->cap){ b->cap = (b->len + n)*2 + 1024; b->data = realloc(b->data, b->cap); if(!b->data){fprintf(stderr,"oom\n");exit(1);} } memcpy(b->data + b->len, p, n); b->len += n; } static void buf_u32(Buf *b, uint32_t v){ buf_put(b, &v, 4); } static void buf_u64(Buf *b, uint64_t v){ buf_put(b, &v, 8); } // skip a KV value of given vtype in input file static void skip_kv_value(FILE *f, uint32_t vtype){ switch(vtype){ case 0: case 1: case 7: fseek(f,1,SEEK_CUR); break; case 2: case 3: fseek(f,2,SEEK_CUR); break; case 4: case 5: case 6: fseek(f,4,SEEK_CUR); break; case 10: case 11: case 12: fseek(f,8,SEEK_CUR); break; case 8: { uint64_t l=rd_u64(f); fseek(f,(long)l,SEEK_CUR); } break; case 9: { uint32_t at=rd_u32(f); uint64_t al=rd_u64(f); if (at==8){ for(uint64_t i=0;i \n", argv[0]); return 1; } const char *fin_name = argv[1], *fout_name = argv[2]; FILE *fin = fopen(fin_name, "rb"); if(!fin){ perror("open in"); return 1; } FILE *fout = fopen(fout_name, "wb"); if(!fout){ perror("open out"); return 1; } // ---- header ---- uint32_t magic = rd_u32(fin); if (magic != GGUF_MAGIC){ fprintf(stderr,"not GGUF\n"); return 1; } uint32_t version = rd_u32(fin); uint64_t n_tensors = rd_u64(fin); uint64_t n_kv = rd_u64(fin); fprintf(stderr,"[requant] %s: ver=%u tensors=%llu kv=%llu\n", fin_name, version, (unsigned long long)n_tensors, (unsigned long long)n_kv); Buf hdr = {0}; buf_u32(&hdr, magic); buf_u32(&hdr, version); buf_u64(&hdr, n_tensors); buf_u64(&hdr, n_kv); // ---- copy KV verbatim ---- for (uint64_t i=0;i q8_0 -> q4_K } TInfo; TInfo *tis = calloc(n_tensors, sizeof(TInfo)); uint64_t n_requant=0, n_copy=0, bytes_in=0, bytes_out=0; for (uint64_t i=0;iname = malloc(nl+1); if(fread(ti->name,nl,1,fin)!=1){exit(1);} ti->name[nl]=0; ti->n_dims = rd_u32(fin); uint64_t nelem = 1; for (uint32_t d=0; dn_dims; d++){ ti->dims[d]=rd_u64(fin); nelem *= ti->dims[d]; } ti->orig_type = rd_u32(fin); ti->orig_offset = rd_u64(fin); enum ggml_type ot = (enum ggml_type)ti->orig_type; // total tensor bytes = row_size(type, ne[0]) * ne[1]*ne[2]*ne[3] int64_t nrow_mult = 1; for (uint32_t d=1; dn_dims; d++) nrow_mult *= (int64_t)ti->dims[d]; ti->orig_size = ggml_row_size(ot, (int64_t)ti->dims[0]) * nrow_mult; // decision: requant Q8_0 non-expert tensors to Q4_K; copy everything else if (ot == GGML_TYPE_Q8_0 && !is_routed_expert(ti->name)){ ti->requant = true; ti->new_type = GGML_TYPE_Q4_K; ti->new_size = ggml_row_size(GGML_TYPE_Q4_K, (int64_t)ti->dims[0]) * nrow_mult; n_requant++; } else { ti->requant = false; ti->new_type = ti->orig_type; ti->new_size = ti->orig_size; n_copy++; } // sanity: Q4_K requires the row dim divisible by QK_K(256). If not, copy instead. if (ti->requant && (ti->dims[0] % 256) != 0){ fprintf(stderr," [warn] %s dims[0]=%llu not mult of 256, copying instead\n", ti->name,(unsigned long long)ti->dims[0]); ti->requant=false; ti->new_type=ti->orig_type; ti->new_size=ti->orig_size; n_requant--; n_copy++; } bytes_in += ti->orig_size; bytes_out += ti->new_size; } fprintf(stderr,"[requant] tensors: %llu requant(q8_0->q4_K), %llu copy | data %.1f GB -> %.1f GB\n", (unsigned long long)n_requant,(unsigned long long)n_copy, bytes_in/1e9, bytes_out/1e9); // ---- write tensor infos with new types & recomputed offsets ---- // first compute new data offsets (sequential, aligned per-tensor to ALIGNMENT within data section) uint64_t *new_off = calloc(n_tensors, sizeof(uint64_t)); uint64_t cur = 0; for (uint64_t i=0;iname); buf_u64(&tinfos, nl); buf_put(&tinfos, ti->name, nl); buf_u32(&tinfos, ti->n_dims); for (uint32_t d=0; dn_dims; d++) buf_u64(&tinfos, ti->dims[d]); buf_u32(&tinfos, ti->new_type); buf_u64(&tinfos, new_off[i]); } // ---- emit header + tinfos, pad to data start ---- uint64_t head_len = hdr.len + tinfos.len; uint64_t data_start = (head_len + ALIGNMENT - 1)/ALIGNMENT*ALIGNMENT; fwrite(hdr.data, hdr.len, 1, fout); fwrite(tinfos.data, tinfos.len, 1, fout); for (uint64_t p=head_len; porig_offset), SEEK_SET); if (!ti->requant){ // byte-copy uint8_t *tmp = malloc(ti->orig_size); if (fread(tmp, ti->orig_size, 1, fin)!=1){ fprintf(stderr,"read tensor %s fail\n",ti->name); return 1; } // write at new offset uint64_t pos = data_start + new_off[i]; fseek(fout, (long)pos, SEEK_SET); fwrite(tmp, ti->orig_size, 1, fout); free(tmp); } else { int64_t nelem = 1; for (uint32_t d=0; dn_dims; d++) nelem *= (int64_t)ti->dims[d]; if ((size_t)nelem > fbuf_n){ fbuf = realloc(fbuf, nelem*sizeof(float)); fbuf_n=nelem; } if (ti->orig_size > qbuf_n){ qbuf = realloc(qbuf, ti->orig_size); qbuf_n=ti->orig_size; } // read q8_0 if (fread(qbuf, ti->orig_size, 1, fin)!=1){ fprintf(stderr,"read q8 %s fail\n",ti->name); return 1; } // dequant q8_0 -> f32 dequantize_row_q8_0((const block_q8_0*)qbuf, fbuf, nelem); // requant f32 -> q4_K (into a second region; reuse qbuf after? need separate) void *out = malloc(ti->new_size); quantize_row_q4_K_ref(fbuf, (block_q4_K*)out, nelem); uint64_t pos = data_start + new_off[i]; fseek(fout, (long)pos, SEEK_SET); fwrite(out, ti->new_size, 1, fout); free(out); } done++; if (done % 50 == 0 || done==n_tensors){ fprintf(stderr,"\r[requant] %llu/%llu tensors", (unsigned long long)done,(unsigned long long)n_tensors); fflush(stderr); } } fprintf(stderr,"\n[requant] wrote %s\n", fout_name); fclose(fin); fclose(fout); return 0; }