AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


基于llama.cpp的量化部署实战
发布日期:2024-04-18 14:31:53 浏览次数: 3082


一、关于量化

深度神经网络模型在结构设计好之后,训练过程的核心目的是确定每个神经元的权重参数,通常是记为浮点数,精度有16、32、64位不一,基于GPU加速训练所得,量化就是通过将这些权重的精度降低,以降低硬件要求的过程。

举例而言,LLaMA 模型为 16 位浮点精度,其 7B 版本有 70 亿参数,该模型完整大小为 13 GB,则用户至少须有如此多的内存和磁盘,模型才能可用,更不用提 13B 版本 24 GB 的大小,令人望而却步。但通过量化,比如将精度降至 4 位,则 7B 和 13B 版本分别压至约 4 GB 和 8 GB,消费级硬件即可满足要求,大家便能在个人电脑上体验大模型了。

LLaMA.cpp 的量化实现基于作者的另外一个库ggml,使用 C/C++ 实现的机器学习模型中的 tensor。所谓 tensor,其实是神经网络模型中的核心数据结构,常见于 TensorFlow、PyTorch 等框架。改用 C/C++ 实现后,支持更广,效率更高,也为 LLaMA.cpp 的出现奠定了基础。

二、llama.cpp

LLaMA.cpp[1]就像这个名字,LLaMA.cpp 项目是开发者 Georgi Gerganov 基于 Meta 释出的 LLaMA 模型(简易 Python 代码示例)手撸的纯 C/C++ 版本,用于模型推理。所谓推理,即是给输入-跑模型-得输出的模型运行过程。那么,纯 C/C++ 版本有何优势呢?

无需任何额外依赖,相比 Python 代码对 PyTorch 等库的要求,C/C++ 直接编译出可执行文件,跳过不同硬件的繁杂准备;支持 Apple Silicon 芯片的 ARM NEON 加速,x86 平台则以 AVX2 替代;具有 F16 和 F32 的混合精度;支持 4-bit 量化;无需 GPU,可只用 CPU 运行;

三、实战环节

3.1 安装 llama.cpp

拉取 llama.cpp 仓库代码

$ git clone https://github.com/ggerganov/llama.cpp

编译llama.cpp

使用GPU执行-推荐

$ cd llama.cpp$ make LLAMA_CUBLAS=1

使用CPU执行-安装简单

$ cd llama.cpp$ make

3.2 生成量化版本模型

模型准备

将合并模型(选择生成pth格式模型)中最后一步生成的tokenizer.model文件放入ti-models目录下,模型文件consolidated.*.pth和配置文件params.json放入ti-models/7B目录下,详细步骤如下所示(LLaMA-7B-pthpth格式模型路径):

$ mkdir ti-models/$ cp LLaMA-7B-pth/tokenizer.model ti-models/$ mkdir ti-models/7B$ cp LLaMA-7B-pth/consolidated.0* ti-models/7B/$ cp LLaMA-7B-pth/params.json ti-models/7B/

结果如下:

llama.cpp/ti-models/ - 7B/ - consolidated.00.pth - ggml-model-f16.bin - params.json - tokenizer.model

3.3 将上述.pth模型权重转换为ggml的FP16格式

$ python convert.py ti-models/7B/

生成文件路径为ti-models/7B/ggml-model-f16.gguf,对FP16模型进行4-bit量化

$ ./quantize ./ti-models/7B/ggml-model-f16.gguf ./ti-models/7B/ggml-model-q4_0.bin q4_0

生成量化模型文件路径为ti-models/7B/ggml-model-q4_0.bin


3.4 加载并启动模型

3.4.1 交互式测试

方案1:chat.sh内容如下:

#!/bin/bashSYSTEM='You are a helpful assistant. 你是一个乐于助人的助手。'FIRST_INSTRUCTION=$2./main -m $1 \--color -i -c 4096 -t 8 --temp 0.5 --top_k 40 --top_p 0.9 --repeat_penalty 1.1 \--in-prefix-bos --in-prefix ' [INST] ' --in-suffix ' [/INST]' -p \"[INST] <<SYS>>$SYSTEM<</SYS>>
$FIRST_INSTRUCTION [/INST]"
$ chmod +x chat.sh$ ./chat.sh ti-models/7B/ggml-model-q4_0.gguf '您好!帮我看下今天是几号?'

方案2:控制台输入:

$ ./main -m ti-models/7B/ggml-model-q4_0.bin --color -f prompts/alpaca.txt -ins -c 2048 --temp 0.2 -n 256 --repeat_penalty 1.1

在提示符 > 之后输入你的promptcmd/ctrl+c中断输出,多行信息以\作为行尾。如需查看帮助和参数说明,请执行./main -h命令。下面介绍一些常用的参数:

-c 控制上下文的长度,值越大越能参考更长的对话历史(默认:512)-ins 启动类ChatGPT对话交流的instruction运行模式-f 指定prompt模板,alpaca模型请加载prompts/alpaca.txt-n 控制回复生成的最大长度(默认:128)-b 控制batch size(默认:8),可适当增加-t 控制线程数量(默认:4),可适当增加--repeat_penalty 控制生成回复中对重复文本的惩罚力度--temp 温度系数,值越低回复的随机性越小,反之越大--top_p, top_k 控制解码采样的相关参数更详细的官方说明请参考[2]

3.4.2 交互式对话

== Running in interactive mode. == - Press Ctrl+C to interject at any time. - Press Return to return control to LLaMa. - To return control without starting a new line, end your input with '/'. - If you want to submit another line, end your input with '\'.
Below is an instruction that describes a task. Write a response that appropriately completes the request.> ལས་སུ་བྱ་བ་དང་དགོས་ཆེད་གཉིད་ལ་ཁྱད་པར་ཅི།ལན།གཉིས་པ་ལས་སུ་བྱ་བ་ནི་བྱེད་པ་པོ་གང་ཞིག་ཚིག་ཟིན་ལ་དངོས་སུ་གསལ་མིན་ཇི་ལྟར་ཡང་བྱ་བའི་ཡུལ་ཞིག་གཙོ་བོར་བཟུང་ནས་བྱ་བ་བྱས་པ་ཙམ་སྟོན་པ་ལ་ཟེར་། བཞི་པ་དགོས་ཆེད་ཅེས་པ་ནི་ལ་དོན་གྱི་ཕྲད་གང་ཡང་རུང་བ་ཞིག་གིས་དགོས་པ་གང་ཞིག་གི་ཆེད་དུ་བྱ་བ་གང་ཞིག་བྱས་པ་ཚིག་ཟིན་དུ་གསལ་པོར་བསྟན་པ་ཞིག་ལ་ཟེར་།

3.4.3 架设server

llama.cpp还提供架设server的功能,用于API调用、架设简易demo等用途。运行以下命令启动server,二进制文件./server在llama.cpp根目录,服务默认监听127.0.0.1:8080。可以通过--host设置ip地址,--port自定义端口号。这里指定模型路径、上下文窗口大小。如果需要使用GPU解码,也可指定-ngl参数。更详细的使用教程请访问[3]

3.4.4 server式访问

启动服务

$ ./server -m ./ti-models/7B/ggml-model-q4_0.gguf -c 4096 -ngl 999

服务启动后,即可通过多种方式进行调用。

利用curl命令调用服务(server_curl_example.sh)

SYSTEM_PROMPT='You are a helpful assistant. 你是一个乐于助人的助手。'# SYSTEM_PROMPT='You are a helpful assistant. 你是一个乐于助人的助手。请你提供专业、有逻辑、内容真实、有价值的详细回复。' # Try this one, if you prefer longer response.INSTRUCTION=$1ALL_PROMPT="[INST] <<SYS>>\n$SYSTEM_PROMPT\n<</SYS>>\n\n$INSTRUCTION [/INST]"CURL_DATA="{\"prompt\": \"$ALL_PROMPT\",\"n_predict\": 128}"
curl --request POST \--url http://localhost:8080/completion \--header "Content-Type: application/json" \--data "$CURL_DATA"
$ bash server_curl_example.sh 'དཔེ་རྒྱན་དང་གཟུགས་རྒྱན་གཉིས་ལ་ཁྱད་པར་གང་ཡོད།'

利用python调用服务

import requestsimport jsondef send_request(instruction):system_prompt = 'You are a helpful assistant. 你是一个乐于助人的助手。'all_prompt = f"[INST] <<SYS>>\n{system_prompt}\n<</SYS>>\n\n{instruction} [/INST]"data = {"prompt": all_prompt,"n_predict": 128}response = requests.post("http://localhost:8080/completion",headers={"Content-Type": "application/json"},data=json.dumps(data))return response.text# 使用这个函数,你可以传入指令:instruction = "དཔེ་རྒྱན་དང་གཟུགས་རྒྱན་གཉིས་ལ་ཁྱད་པར་གང་ཡོད།"response_text = send_request(instruction)print(response_text)

稍后返回的响应结果

{"content": "\n ལན།དཔེ་དང་དཔེ་ཅན་གཉིས་ངོ་བོ་ཐ་དད་པར་བཀོད་པ་ལ་བརྟེན་ནས་དེ་གཉིས་མཚུངས་པར་རྟོགས་པར་བྱེད་པ་ནི་དཔེ་རྒྱན་དང་གཟུགས་རྒྱན་ནི་དཔེ་དང་དཔེ་ཅན་གཉིས་ལ་ངོ་བོ་ཐ་དད་དུ་མ་བྱས་པར་བརྗོད་པར་འདོད་པའི་དོན་དེ་ཉིད་དཔེའི་གཟུགས་སུ་བཀོད་པ་ཡིན།","id_slot": 0,"stop": true,"model": "/root/paddlejob/workspace/env_run/output/opencode/cym_code/zh-models/7B/ggml-model-q4_0.bin","tokens_predicted": 128,"tokens_evaluated": 40,"generation_settings": {"n_ctx": 4096,"n_predict": -1,"model": "/root/paddlejob/workspace/env_run/output/opencode/cym_code/zh-models/7B/ggml-model-q4_0.bin","seed": 4294967295,"temperature": 0.800000011920929,"dynatemp_range": 0.0,"dynatemp_exponent": 1.0,"top_k": 40,"top_p": 0.949999988079071,"min_p": 0.05000000074505806,"tfs_z": 1.0,"typical_p": 1.0,"repeat_last_n": 64,"repeat_penalty": 1.0,"presence_penalty": 0.0,"frequency_penalty": 0.0,"penalty_prompt_tokens": [],"use_penalty_prompt_tokens": false,"mirostat": 0,"mirostat_tau": 5.0,"mirostat_eta": 0.10000000149011612,"penalize_nl": false,"stop": [],"n_keep": 0,"n_discard": 0,"ignore_eos": false,"stream": false,"logit_bias": [],"n_probs": 0,"min_keep": 0,"grammar": "","samplers": ["top_k", "tfs_z", "typical_p", "top_p", "min_p", "temperature"]},"prompt": "[INST] <<SYS>>\nYou are a helpful assistant. 你是一个乐于助人的助手。\n<</SYS>>\n\n [/INST]","truncated": false,"stopped_eos": false,"stopped_word": false,"stopped_limit": true,"stopping_word": "","tokens_cached": 167,"timings": {"prompt_n": 40,"prompt_ms": 481.453,"prompt_per_token_ms": 12.036325,"prompt_per_second": 83.0818376871678,"predicted_n": 128,"predicted_ms": 4979.148,"predicted_per_token_ms": 38.89959375,"predicted_per_second": 25.707209345855958}}

3.5 推理速度测试

$ ./perplexity -m ti-models/7B/ggml-model-q4_0.gguf -f test.txt -c 4096 -ngl 999

4 量化方法选择及推理速度总结

默认的量化方法为q4_0,虽然速度最快但损失也是最大的,其余方法各有利弊,按实际情况选择;需要注意的是F16以及q8_0并不会因为增加线程数而提高太多速度;线程数-t与物理核心数一致时速度最快,超过之后速度反而变慢(M1 Max上从8改到10之后耗时变为3倍);如果使用了Metal版本(即启用了苹果GPU解码),速度还会有进一步显著提升,表中标注为-ngl 1;综合推荐(仅供参考):7B推荐Q5_1Q5_K_S,13B推荐Q5_0Q5_K_S;机器资源够用且对速度要求不是那么苛刻的情况下可以使用q8_0Q6_K,接近F16模型的效果。


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询