llama.cpp量化

1. llama.cpp 量化 qwen-14b 到 int4

先安装 llama.cpp,编译安装会比较久。

git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && git pull && make clean && LLAMA_CUBLAS=1 make
pip install -r llama.cpp/requirements.txt

执行 hftogguf 转换,类型选择 f16,路径是llama.cpp/convert-hf-to-gguf.py,这里指定输出路径为Qwen-14B-fp16.

!python convert-hf-to-gguf.py  /root/autodl-tmp/qwen/Qwen-14B --outfile Qwen-14B-fp16 --outtype f16

选择量化的方法,参考 quant llama2llm-course. 具体来说:

  1. q2_k:在注意力机制的 vw 和前馈网络的 w2 张量上使用Q4_K,其他张量使用Q2_K
  2. q3_k_l:在注意力的 wvwo 和前馈网络的 w2 张量上使用Q5_K,其他使用Q3_K
  3. q3_k_m:在注意力的 wvwo 和前馈网络的 w2 张量上使用Q4_K,其他使用Q3_K
  4. q3_k_s:所有张量都使用Q3_K
  5. q4_0:原始的 4 位量化方法。
  6. q4_1:比 q4_0 准确度更高,但不如 q5_0。然而推理速度比q5 模型更快。
  7. q4_k_m:一半的注意力 wv 和前馈网络的 w2 张量使用Q6_K,其他使用Q4_K
  8. q4_k_s:所有张量都使用Q4_K
  9. q5_0:准确度更高,资源使用更多,推理速度更慢。
  10. q5_1:准确度、资源使用和推理速度都比 q5_0 更高、更多、更慢。
  11. q5_k_m:一半的注意力 wv 和前馈网络的 w2 张量使用Q6_K,其他使用Q5_K
  12. q5_k_s:所有张量都使用Q5_K
  13. q6_k:所有张量都使用Q8_K
  14. q8_0:与 float16 几乎无法区分。资源使用高且速度慢。不推荐大多数用户使用。

一般来说,我推荐使用 Q5_K_M,因为它保留了模型的大部分性能。或者,如果你想节省一些内存,可以使用Q4_K_M。通常,K_M 版本比 K_S 版本更好。我不推荐使用 Q2_KQ3_*版本,因为它们会大幅降低模型性能。

QUANTIZATION_METHODS = ["q4_k_m", "q5_k_m"]
fp16 = "Qwen-14B-fp16"
for method in QUANTIZATION_METHODS:
    qtype = f"Qwen-14B.{method.upper()}.gguf"

    !./llama.cpp/quantize {fp16} {qtype} {method}

接下来我们就可以看到大量的 layer 被指定 method 量化了:

main: build = 2522 (a0e584de)
main: built with cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 for x86_64-linux-gnu
main: quantizing '/root/autodl-tmp/Qwen-14B-fp16' to 'Qwen-14B.Q4_K_M.gguf' as Q4_K_M
llama_model_loader: loaded meta data with 17 key-value pairs and 323 tensors from /root/autodl-tmp/Qwen-14B-fp16 (version GGUF V3 (latest))
llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output.
llama_model_loader: - kv   0:                       general.architecture str              = qwen
llama_model_loader: - kv   1:                               general.name str              = Qwen
llama_model_loader: - kv   2:                        qwen.context_length u32              = 8192
llama_model_loader: - kv   3:                           qwen.block_count u32              = 40
llama_model_loader: - kv   4:                      qwen.embedding_length u32              = 5120
llama_model_loader: - kv   5:                   qwen.feed_forward_length u32              = 27392
llama_model_loader: - kv   6:                        qwen.rope.freq_base f32              = 10000.000000
llama_model_loader: - kv   7:                  qwen.rope.dimension_count u32              = 128
llama_model_loader: - kv   8:                  qwen.attention.head_count u32              = 40
llama_model_loader: - kv   9:      qwen.attention.layer_norm_rms_epsilon f32              = 0.000001
llama_model_loader: - kv  10:                       tokenizer.ggml.model str              = gpt2
llama_model_loader: - kv  11:                      tokenizer.ggml.tokens arr[str,152064]  = ["!", "\"", "#", "$", "%", "&", "'", ...
llama_model_loader: - kv  12:                  tokenizer.ggml.token_type arr[i32,152064]  = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
llama_model_loader: - kv  13:                      tokenizer.ggml.merges arr[str,151387]  = ["Ġ Ġ", "ĠĠ ĠĠ", "i n", "Ġ t",...
llama_model_loader: - kv  14:                tokenizer.ggml.bos_token_id u32              = 151643
llama_model_loader: - kv  15:                tokenizer.ggml.eos_token_id u32              = 151643
llama_model_loader: - kv  16:            tokenizer.ggml.unknown_token_id u32              = 151643
llama_model_loader: - type  f32:  121 tensors
llama_model_loader: - type  f16:  202 tensors
llama_model_quantize_internal: meta size = 5950528 bytes
[   1/ 323]                  blk.0.attn_qkv.bias - [15360,     1,     1,     1], type =    f32, size =    0.059 MB
[   2/ 323]                blk.0.attn_qkv.weight - [ 5120, 15360,     1,     1], type =    f16, converting to q5_K .. size =   150.00 MiB ->    51.56 MiB
[   3/ 323]             blk.0.attn_output.weight - [ 5120,  5120,     1,     1], type =    f16, converting to q4_K .. size =    50.00 MiB ->    14.06 MiB
[   4/ 323]               blk.0.attn_norm.weight - [ 5120,     1,     1,     1], type =    f32, size =    0.020 MB
[   5/ 323]                blk.0.ffn_norm.weight - [ 5120,     1,     1,     1], type =    f32, size =    0.020 MB
[   6/ 323]                  blk.0.ffn_up.weight - [ 5120, 13696,     1,     1], type =    f16, converting to q4_K .. size =   133.75 MiB ->    37.62 MiB
[   7/ 323]                blk.0.ffn_gate.weight - [ 5120, 13696,     1,     1], type =    f16, converting to q4_K .. size =   133.75 MiB ->    37.62 MiB
[   8/ 323]                    token_embd.weight - [ 5120, 152064,     1,     1], type =    f16, converting to q4_K .. size =  1485.00 MiB ->   417.66 MiB
[   9/ 323]                blk.0.ffn_down.weight - [13696,  5120,     1,     1], type =    f16, 

2. 推理

这里参考 llama.cpp 部署通义千问 Qwen-14B, 修改 examples/chat.sh 为:

./main -m /root/Qwen-14B.Q4_K_M.gguf -c 512 -b 1024 -n 256 --keep 48 \
    --repeat_penalty 1.0 --color -i \
    -r "User:" -f prompts/chat-with-bob.txt

然后sh llama.cpp/examples/chat.sh

Inference

[1] llm quant

[2] llama.cpp quant llama

正文完
 
admin
版权声明:本站原创文章,由 admin 2024-03-25发表,共计3692字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请联系tensortimes@gmail.com。
评论(没有评论)
验证码