llama.cpp部署

llama.cpp

介绍

部署

介绍

大模型的研究分为训练和推理两个部分:

  • 训练的过程,实际上就是在寻找模型参数,使得模型的损失函数最小化;
  • 推理结果最优化的过程;

训练完成之后,模型的参数就固定了,这时候就可以使用模型进行推理,对外提供服务。

llama.cpp 主要解决的是推理过程中的性能问题。主要有两点优化:

  • llama.cpp 使用的是 C 语言写的机器学习张量库 ggml
  • llama.cpp 提供了模型量化的工具

计算类 Python 库的优化手段之一就是使用 C 重新实现,这部分的性能提升非常明显。另外一个是量化,量化是通过牺牲模型参数的精度,来换取模型的推理速度。llama.cpp 提供了大模型量化的工具,可以将模型参数从 32 位浮点数转换为 16 位浮点数,甚至是 8、4 位整数。

除此之外,llama.cpp 还提供了服务化组件,可以直接对外提供模型的 API 。

使用量化模型

下载编译 llama.cpp

git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make

在目录下会生成一系列可执行文件

  • main:使用模型进行推理
  • quantize:量化模型
  • server:提供模型 API 服务

准备 llama.cpp 支持的模型

llama.cpp 支持转换的模型格式有 PyTorch 的 .pth 、huggingface 的 .safetensors 、还有之前 llamma.cpp 采用的 ggmlv3。

在 huggingface 上找到合适格式的模型,下载至 llama.cpp 的 models 目录下。

git clone https://huggingface.co/4bit/Llama-2-7b-chat-hf ./models/Llama-2-7b-chat-hf

格式转化

  • 依赖

llama.cpp 项目下带有 requirements.txt 文件,直接安装依赖即可。

pip install -r requirements.txt
  • 转换模型
python convert.py ./models/Llama-2-7b-chat-hf --vocabtype spm

params = Params(n_vocab=32000, n_embd=4096, n_mult=5504, n_layer=32, n_ctx=2048, n_ff=11008, n_head=32, n_head_kv=32, f_norm_eps=1e-05, f_rope_freq_base=None, f_rope_scale=None, ftype=None, path_model=PosixPath('models/Llama-2-7b-chat-hf'))
Loading vocab file 'models/Llama-2-7b-chat-hf/tokenizer.model', type 'spm'
...
Wrote models/Llama-2-7b-chat-hf/ggml-model-f16.gguf

vocabtype 指定分词算法,默认值是 spm,如果是 bpe,需要显示指定。

量化模型

  • 使用 quantize 量化模型

quantize 提供各种精度的量化。

./quantize

usage: ./quantize [--help] [--allow-requantize] [--leave-output-tensor] model-f32.gguf [model-quant.gguf] type [nthreads]

  --allow-requantize: Allows requantizing tensors that have already been quantized. Warning: This can severely reduce quality compared to quantizing from 16bit or 32bit
  --leave-output-tensor: Will leave output.weight un(re)quantized. Increases model size but may also increase quality, especially when requantizing

Allowed quantization types:
   2  or  Q4_0   :  3.56G, +0.2166 ppl @ LLaMA-v1-7B
   3  or  Q4_1   :  3.90G, +0.1585 ppl @ LLaMA-v1-7B
   8  or  Q5_0   :  4.33G, +0.0683 ppl @ LLaMA-v1-7B
   9  or  Q5_1   :  4.70G, +0.0349 ppl @ LLaMA-v1-7B
  10  or  Q2_K   :  2.63G, +0.6717 ppl @ LLaMA-v1-7B
  12  or  Q3_K   : alias for Q3_K_M
  11  or  Q3_K_S :  2.75G, +0.5551 ppl @ LLaMA-v1-7B
  12  or  Q3_K_M :  3.07G, +0.2496 ppl @ LLaMA-v1-7B
  13  or  Q3_K_L :  3.35G, +0.1764 ppl @ LLaMA-v1-7B
  15  or  Q4_K   : alias for Q4_K_M
  14  or  Q4_K_S :  3.59G, +0.0992 ppl @ LLaMA-v1-7B
  15  or  Q4_K_M :  3.80G, +0.0532 ppl @ LLaMA-v1-7B
  17  or  Q5_K   : alias for Q5_K_M
  16  or  Q5_K_S :  4.33G, +0.0400 ppl @ LLaMA-v1-7B
  17  or  Q5_K_M :  4.45G, +0.0122 ppl @ LLaMA-v1-7B
  18  or  Q6_K   :  5.15G, -0.0008 ppl @ LLaMA-v1-7B
   7  or  Q8_0   :  6.70G, +0.0004 ppl @ LLaMA-v1-7B
   1  or  F16    : 13.00G              @ 7B
   0  or  F32    : 26.00G              @ 7B

  • 执行量化模型
./quantize ./models/Llama-2-7b-chat-hf/ggml-model-f16.gguf ./models/Llama-2-7b-chat-hf/ggml-model-q4_0.gguf Q4_0

llama_model_quantize_internal: model size  = 12853.02 MB
llama_model_quantize_internal: quant size  =  3647.87 MB
llama_model_quantize_internal: hist: 0.036 0.015 0.025 0.039 0.056 0.076 0.096 0.112 0.118 0.112 0.096 0.077 0.056 0.039 0.025 0.021

量化之后,模型的大小从 13G 降低到 3.6G,但模型精度从 16 位浮点数降低到 4 位整数。

运行 GGUF 模型

下载模型

在 llama.cpp 项目的首页 https://github.com/ggerganov/llama.cpp 有列举支持的模型

去 https://huggingface.co/models 找 GGUF 格式的大模型版本,下载模型文件放在 llama.cpp 项目 models 目录下。

git clone https://huggingface.co/rozek/LLaMA-2-7B-32K-Instruct_GGUF ./models/LLaMA-2-7B-32K-Instruct_GGUF

仓库中包含各种量化位数的模型,Q2、Q3、Q4、Q5、Q6、Q8、F16。量化模型的命名方法遵循: “Q” + 量化比特位 + 变种。

量化位数越少,对硬件资源的要求越低,但是模型的精度也越低。

使用 git clone 命令下载的模型会加载失败,提示 magic 不匹配。

在网页直接下载的模型可以正常使用。

推理

在 llama.cpp 项目的根目录,编译源码之后,执行下面的命令,使用模型进行推理。

./main -m ./models/llama-2-7b-langchain-chat-GGUF/llama-2-7b-langchain-chat-q4_0.gguf -p "What color is the sun?" -n 1024

 What color is the sun?
 nobody knows. It’s not a specific color, more a range of colors. Some people say it's yellow; some say orange, while others believe it to be red or white. Ultimately, we can only imagine what color the sun might be because we can't see its exact color from this planet due to its immense distance away!
It’s fascinating how something so fundamental to our daily lives remains a mystery even after decades of scientific inquiry into its properties and behavior.” [end of text]

llama_print_timings:        load time =   376.57 ms
llama_print_timings:      sample time =    56.40 ms /   105 runs   (    0.54 ms per token,  1861.77 tokens per second)
llama_print_timings: prompt eval time =   366.68 ms /     7 tokens (   52.38 ms per token,    19.09 tokens per second)
llama_print_timings:        eval time = 15946.81 ms /   104 runs   (  153.33 ms per token,     6.52 tokens per second)
llama_print_timings:       total time = 16401.43 ms

当然,也可以用上面量化的模型进行推理。

./main -m  ./models/Llama-2-7b-chat-hf/ggml-model-q4_0.gguf -p "What color is the sun?" -n 1024

What color is the sun?
 sierp 10, 2017 at 12:04 pm - Reply
The sun does not have a color because it emits light in all wavelengths of the visible spectrum and beyond. However, due to our atmosphere's scattering properties, the sun appears yellow or orange from Earth. This is known as Rayleigh scattering and is why the sky appears blue during the daytime. [end of text]

llama_print_timings:        load time = 90612.21 ms
llama_print_timings:      sample time =    52.31 ms /    91 runs   (    0.57 ms per token,  1739.76 tokens per second)
llama_print_timings: prompt eval time =   523.38 ms /     7 tokens (   74.77 ms per token,    13.37 tokens per second)
llama_print_timings:        eval time = 15266.91 ms /    90 runs   (  169.63 ms per token,     5.90 tokens per second)
llama_print_timings:       total time = 15911.47 ms

四位量化模型,在没有 GPU 的情况下,基本能够实现实时推理。敲完命令,按回车,就能看到模型的回复。

main 命令有一系列参数可选,其中比较重要的参数有:

-ins 交互模式,可以连续对话,上下文会保留
-c 控制上下文的长度,值越大越能参考更长的对话历史(默认:512)
-n 控制回复生成的最大长度(默认:128)
–temp 温度系数,值越低回复的随机性越小

交互模式下使用模型

./main -m ./models/llama-2-7b-langchain-chat-GGUF/llama-2-7b-langchain-chat-q4_0.gguf -ins

> 世界上最大的鱼是什么?
卡加内利亚鲨为世界最大的鱼,体长达60英尺(18)。牠们的头部相当于一只小车,身体非常丑,腹部有两个气孔,气孔之间还有一个大口径的鳃,用于进行捕食。牠们通常是从水中搴出来到陆地上抓到的小鱼,然后产生大量液体以解脱自己的身体。

> 现在还有这种鱼吗?
作者所提到的“卡加内利亚鲨”,应该是指的是“卡加内利亚鳄”。卡加内利亚鳄是一种大型淡水肉食性鱼类,分布于欧洲和非洲部分区域。这种鱼的体长最大可达60英尺(18),是世界上已知最大的鱼之一。

不过,现在这种鱼已经消失了,因为人类对戒备和保护水生生物的意识程度低下,以及环境污染等多方面原因。

交互模式下,以对话的形式,有上下文的连续使用大模型。

提供模型的 API 服务

有两种方式,一种是使用 llama.cpp 提供的 API 服务,另一种是使用第三方提供的工具包。

使用 llama.cpp server 提供 API 服务

前面编译之后,会在 llama.cpp 项目的根目录下生成一个 server 可执行文件,执行下面的命令,启动 API 服务。

./server -m ./models/llama-2-7b-langchain-chat-GGUF/llama-2-7b-langchain-chat-q4_0.gguf --host 0.0.0.0 --port 8080

llm_load_tensors: mem required  = 3647.96 MB (+  256.00 MB per state)
..................................................................................................
llama_new_context_with_model: kv self size  =  256.00 MB
llama_new_context_with_model: compute buffer total size =   71.97 MB

llama server listening at http://0.0.0.0:8080

{"timestamp":1693789480,"level":"INFO","function":"main","line":1593,"message":"HTTP server listening","hostname":"0.0.0.0","port":8080}

这样就启动了一个 API 服务,可以使用 curl 命令进行测试。

curl --request POST \
    --url http://localhost:8080/completion \
    --header "Content-Type: application/json" \
    --data '{"prompt": "What color is the sun?","n_predict": 512}'

{"content":".....","generation_settings":{"frequency_penalty":0.0,"grammar":"","ignore_eos":false,"logit_bias":[],"mirostat":0,"mirostat_eta":0.10000000149011612,"mirostat_tau":5.0,......}}

使用第三方工具包提供的 API 服务

在 llamm.cpp 项目的首页 https://github.com/ggerganov/llama.cpp 中有提到各种语言编写的第三方工具包,可以使用这些工具包提供 API 服务,包括 Python、Go、Node.js、Ruby、Rust、C#/.NET、Scala 3、Clojure、React Native、Java 等语言的实现。

以 Python 为例,使用 llama-cpp-python 提供 API 服务。

  • 安装依赖
pip install llama-cpp-python -i https://mirrors.aliyun.com/pypi/simple/

如果需要针对特定的硬件进行优化,就配置 “CMAKE_ARGS” 参数,详情请参数 https://github.com/abetlen/llama-cpp-python 。我本地是 CPU 环境,就没有进行额外的配置。

  • 启动 API 服务
python -m llama_cpp.server --model ./models/llama-2-7b-langchain-chat-GGUF/llama-2-7b-langchain-chat-q4_0.gguf

llama_new_context_with_model: kv self size  = 1024.00 MB
llama_new_context_with_model: compute buffer total size =  153.47 MB
AVX = 1 | AVX2 = 1 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | SSSE3 = 1 | VSX = 0 |
INFO:     Started server process [57637]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)

  • 使用 curl 测试 API 服务
curl -X 'POST' \
  'http://localhost:8000/v1/chat/completions' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "messages": [
    {
      "content": "You are a helpful assistant.",
      "role": "system"
    },
    {
      "content": "Write a poem for Chinese?",
      "role": "user"
    }
  ]
}'

{"id":"chatcmpl-c3eec466-6073-41e2-817f-9d1e307ab55f","object":"chat.completion","created":1693829165,"model":"./models/llama-2-7b-langchain-chat-GGUF/llama-2-7b-langchain-chat-q4_0.gguf","choices":[{"index":0,"message":{"role":"assistant","content":"I am not programmed to write poems in different languages. How about I"},"finish_reason":"length"}],"usage":{"prompt_tokens":26,"completion_tokens":16,"total_tokens":42}}

  • 使用 openai 调用 API 服务
# -*- coding: utf-8 -*-

import openai
openai.api_key = 'random'
openai.api_base = 'http://localhost:8000/v1'
messages = [{'role': 'system', 'content': u'你是一个真实的人,老实回答提问,不要耍滑头'}]
messages.append({'role': 'user', 'content': u'你昨晚去哪里了'})
response = openai.ChatCompletion.create(
    model='random',
    messages=messages,
)
print(response['choices'][0]['message']['content'])

参考文档

大模型部署工具 llama.cpp

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Llama.cpp 是一个虚构的编程文件名,因此无法给出具体的编程训练过程。然而,我可以简单介绍一下通常的编程训练方法。 首先,为了训练 Llama.cpp 这个程序,我们需要了解所使用的编程语言和开发环境。根据具体情况,我们可以选择使用 C++、Java、Python 或其他编程语言来编写代码。此外,我们需要安装相应的开发环境,如 Visual Studio、Eclipse 或者 PyCharm。 接下来,我们需要设定训练目标。这可能是一个具体的问题或任务,例如编写一个简单的加法程序、设计一个实现某种功能的小游戏或者开发一个完整的应用程序。 在开始编写代码之前,我们应该对问题进行分析和规划。这包括确定所需的输入和输出,设计程序的结构和逻辑,以及选择合适的数据结构和算法。 然后,我们可以开始编写代码。可以使用文本编辑器或集成开发环境来创建和编辑程序文件。根据训练目标,我们可以使用不同的编程概念和语法,如变量、函数、循环和条件语句,来实现所需的功能。 编写代码后,我们需要进行测试和调试。可以编写一些测试用例来验证程序的正确性,并运行程序进行测试。通过调试技巧和工具,我们可以找到并修复潜在的错误和问题。 最后,我们可以优化代码,提高程序的性能和效率。这包括减少资源消耗、优化算法和数据结构,以及优化代码的可读性和可维护性。 通过不断的实践和训练,我们可以逐渐提升编程技能,并学会更多高级的编程概念和技术。在编程的旅程中,理解问题、设计解决方案、编写代码、测试和调试是一个循环迭代的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值