mirror of
https://github.com/microsoft/BitNet.git
synced 2026-10-25 08:08:28 +00:00
feat: add I2_S GGUF conversion for bitnet-b1.58-2B-4T and refactor T-MAC LUT path
- Add quantize_to_i2_s() for direct ternary-to-I2_S packing in conversion script - Support offline-quantized models (uint8 packed weights + weight_scale) - Fix weight_quant double-quantization bug for offline-quantized models - Fix I2_S scale computation to use first nonzero absolute value - Add I2_S ftype mapping and BitNetForCausalLM registration - Refactor ggml-bitnet-lut T-MAC wrapper with proper mul_mat implementation - Update llama.cpp submodule with I2_S ftype and 2B model type support
This commit is contained in:
6 files changed
+1395
-55
No files matched your search
+54
-36
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "ggml-bitnet.h"
|
||||
#include "ggml-quants.h"
|
||||
#include "ggml-cpu-impl.h"
|
||||
|
||||
#if defined(GGML_BITNET_ARM_TL1) || defined(GGML_BITNET_X86_TL2)
|
||||
#include "bitnet-lut-kernels.h"
|
||||
@@ -19,16 +20,11 @@
|
||||
#if defined(GGML_BITNET_ARM_TL1)
|
||||
|
||||
void ggml_bitnet_init(void) {
|
||||
// LOG(INFO) << "ggml_bitnet_init";
|
||||
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
// if (wrapper == nullptr) {
|
||||
// wrapper = new BITNET::BITNETGeMMWrapper<bitnet_bitnet_float_type>();
|
||||
// }
|
||||
if (bitnet_tensor_extras == nullptr) {
|
||||
bitnet_tensor_extras = new bitnet_tensor_extra[GGML_BITNET_MAX_NODES];
|
||||
}
|
||||
@@ -36,26 +32,17 @@ void ggml_bitnet_init(void) {
|
||||
}
|
||||
|
||||
void ggml_bitnet_free(void) {
|
||||
// LOG(INFO) << "ggml_bitnet_free";
|
||||
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = false;
|
||||
|
||||
// delete wrapper;
|
||||
// wrapper = nullptr;
|
||||
for (size_t i = 0; i < bitnet_tensor_extras_index; i++) {
|
||||
// aligned_free(bitnet_tensor_extras[i].qweights);
|
||||
// aligned_free(bitnet_tensor_extras[i].scales);
|
||||
}
|
||||
delete[] bitnet_tensor_extras;
|
||||
bitnet_tensor_extras = nullptr;
|
||||
}
|
||||
|
||||
static bool do_permutate(enum ggml_type type) {
|
||||
if (type == GGML_TYPE_TL1) {
|
||||
// Add additional args to decide if permuted I2 or naive I2
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -65,8 +52,7 @@ static bool do_permutate(enum ggml_type type) {
|
||||
bool ggml_bitnet_can_mul_mat(const struct ggml_tensor * src0, const struct ggml_tensor * src1, const struct ggml_tensor * dst) {
|
||||
if ((is_type_supported(src0->type)) &&
|
||||
src1->type == GGML_TYPE_F32 &&
|
||||
dst->type == GGML_TYPE_F32 &&
|
||||
src0->backend == GGML_BACKEND_TYPE_CPU) {
|
||||
dst->type == GGML_TYPE_F32) {
|
||||
if (src1->ne[1] <= 1) {
|
||||
return true;
|
||||
}
|
||||
@@ -79,10 +65,9 @@ size_t ggml_bitnet_mul_mat_get_wsize(const struct ggml_tensor * src0, const stru
|
||||
const size_t ne10 = src1->ne[0];
|
||||
const size_t ne11 = src1->ne[1];
|
||||
const int bits = ggml_bitnet_get_type_bits(src0->type);
|
||||
|
||||
|
||||
size_t wsize = ne10 * ne11 * 15 * sizeof(int8_t) + 1 * ne11 * 2 * sizeof(bitnet_float_type);
|
||||
if (sizeof(bitnet_float_type) == 2) {
|
||||
// Need fp32 to fp16 conversion
|
||||
wsize += std::max(ne10, ne01) * ne11 * sizeof(bitnet_float_type);
|
||||
}
|
||||
wsize = ((wsize - 1) / 64 + 1) * 64;
|
||||
@@ -100,19 +85,61 @@ int ggml_bitnet_get_type_bits(enum ggml_type type) {
|
||||
}
|
||||
}
|
||||
|
||||
void ggml_bitnet_mul_mat(const struct ggml_compute_params * params, struct ggml_tensor * dst) {
|
||||
const struct ggml_tensor * src0 = dst->src[0];
|
||||
const struct ggml_tensor * src1 = dst->src[1];
|
||||
|
||||
const size_t ne00 = src0->ne[0];
|
||||
const size_t ne01 = src0->ne[1];
|
||||
const size_t ne10 = src1->ne[0];
|
||||
const size_t ne11 = src1->ne[1];
|
||||
|
||||
const int ith = params->ith;
|
||||
const int nth = params->nth;
|
||||
const int bits = ggml_bitnet_get_type_bits(src0->type);
|
||||
|
||||
struct bitnet_tensor_extra * extra = (struct bitnet_tensor_extra *)src0->extra;
|
||||
GGML_ASSERT(extra != nullptr);
|
||||
|
||||
char * wdata = (char *)params->wdata;
|
||||
const size_t wsize_per_thread = ggml_bitnet_mul_mat_get_wsize(src0, src1, dst);
|
||||
|
||||
int8_t * qlut = (int8_t *)(wdata);
|
||||
bitnet_float_type * lut_scales = (bitnet_float_type *)(qlut + ne10 * ne11 * 15);
|
||||
bitnet_float_type * lut_biases = (bitnet_float_type *)(lut_scales + ne11);
|
||||
|
||||
if (ith == 0) {
|
||||
ggml_bitnet_mul_mat_task_init(
|
||||
(void *)((char *)src1->data),
|
||||
(void *)qlut,
|
||||
(void *)lut_scales,
|
||||
(void *)lut_biases,
|
||||
ne10, ne00, ne11, bits);
|
||||
}
|
||||
|
||||
// barrier
|
||||
if (nth > 1) {
|
||||
ggml_barrier(params->threadpool);
|
||||
}
|
||||
|
||||
ggml_bitnet_mul_mat_task_compute(
|
||||
(void *)extra->qweights,
|
||||
(void *)extra->scales,
|
||||
(void *)qlut,
|
||||
(void *)lut_scales,
|
||||
(void *)lut_biases,
|
||||
(void *)((char *)dst->data),
|
||||
ne10, ne00, ne11, bits);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(GGML_BITNET_X86_TL2)
|
||||
void ggml_bitnet_init(void) {
|
||||
// LOG(INFO) << "ggml_bitnet_init";
|
||||
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
// if (wrapper == nullptr) {
|
||||
// wrapper = new BITNET::BITNETGeMMWrapper<bitnet_bitnet_float_type>();
|
||||
// }
|
||||
if (bitnet_tensor_extras == nullptr) {
|
||||
bitnet_tensor_extras = new bitnet_tensor_extra[GGML_BITNET_MAX_NODES];
|
||||
}
|
||||
@@ -120,19 +147,11 @@ void ggml_bitnet_init(void) {
|
||||
}
|
||||
|
||||
void ggml_bitnet_free(void) {
|
||||
// LOG(INFO) << "ggml_bitnet_free";
|
||||
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
initialized = false;
|
||||
|
||||
// delete wrapper;
|
||||
// wrapper = nullptr;
|
||||
for (size_t i = 0; i < bitnet_tensor_extras_index; i++) {
|
||||
// aligned_free(bitnet_tensor_extras[i].qweights);
|
||||
// aligned_free(bitnet_tensor_extras[i].scales);
|
||||
}
|
||||
delete[] bitnet_tensor_extras;
|
||||
bitnet_tensor_extras = nullptr;
|
||||
}
|
||||
@@ -140,8 +159,7 @@ void ggml_bitnet_free(void) {
|
||||
bool ggml_bitnet_can_mul_mat(const struct ggml_tensor * src0, const struct ggml_tensor * src1, const struct ggml_tensor * dst) {
|
||||
if ((is_type_supported(src0->type)) &&
|
||||
src1->type == GGML_TYPE_F32 &&
|
||||
dst->type == GGML_TYPE_F32 &&
|
||||
src0->backend == GGML_BACKEND_TYPE_CPU) {
|
||||
dst->type == GGML_TYPE_F32) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -151,10 +169,9 @@ size_t ggml_bitnet_mul_mat_get_wsize(const struct ggml_tensor * src0, const stru
|
||||
const size_t ne01 = src0->ne[1];
|
||||
const size_t ne10 = src1->ne[0];
|
||||
const size_t ne11 = src1->ne[1];
|
||||
|
||||
|
||||
size_t wsize = ne10 * ne11 * 11 * sizeof(int8_t) + 2 * ne11 * 2 * sizeof(bitnet_float_type);
|
||||
if (sizeof(bitnet_float_type) == 2) {
|
||||
// Need fp32 to fp16 conversion
|
||||
wsize += std::max(ne10, ne01) * ne11 * sizeof(bitnet_float_type);
|
||||
}
|
||||
wsize = ((wsize - 1) / 64 + 1) * 64;
|
||||
@@ -171,4 +188,5 @@ int ggml_bitnet_get_type_bits(enum ggml_type type) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user