当前位置: 首页 > news >正文

docker 中将dpo后的模型转为ollama能够调用的gguf格式

1 加载目录并进入docker环境

docker run -it --entrypoint /bin/bash -v /home/pretrained_model/output/:/output ollama/ollama

将dpo后的模型路径/home/pretrained_model/output/ 映射到docker中的/output目录

2 安装git

查看系统版本

root@8144e6f3a36f:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"

安装git

root@8144e6f3a36f:/# apt update && apt install -y git
root@8144e6f3a36f:/# git --version
git version 2.25.1

3 下载llama.cpp

root@8144e6f3a36f:/# git clone https://github.com/ggerganov/llama.cpp.git
Cloning into 'llama.cpp'...
remote: Enumerating objects: 47622, done.
remote: Counting objects: 100% (133/133), done.
remote: Compressing objects: 100% (104/104), done.
remote: Total 47622 (delta 79), reused 29 (delta 29), pack-reused 47489 (from 3)
Receiving objects: 100% (47622/47622), 99.78 MiB | 5.51 MiB/s, done.
Resolving deltas: 100% (34186/34186), done.

4 安装miniconda

# 更新 apt 并安装依赖
apt update && apt install -y wget bzip2# 下载 Miniconda(Linux 64位版本)
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh# 运行安装脚本(自动安装到 /root/miniconda3)
bash ~/miniconda.sh -b -p /opt/miniconda3# 将 conda 加入 PATH
echo 'export PATH="/opt/miniconda3/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc# 验证安装
conda --version
root@8144e6f3a36f:/llama.cpp# conda --version
conda 25.1.1

5 创建并进入虚拟环境

root@69e2b4914bb1:/llama.cpp# conda activate llamaCondaError: Run 'conda init' before 'conda activate'root@69e2b4914bb1:/llama.cpp# source activate llama
(llama) root@69e2b4914bb1:/llama.cpp# ll

6 退出docker后重启

(base) [nlp ~]$ docker attach 69e
You cannot attach to a stopped container, start it first
(base) [nlp ~]$ docker start 69e 
69e
(base) [nlp ~]$ docker attach 69e
root@69e2b4914bb1:/# ll
total 8
drwxr-xr-x.    1 root root  140 Apr  7 10:08 ./
drwxr-xr-x.    1 root root  140 Apr  7 10:08 ../

7 合并dpo lora模型

TypeError: __init__() got an unexpected keyword argument 'corda_config'

遇到上面问题需要切换虚拟环境

lora_merge.py

import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizerbase_model_path = '/Qwen2.5-0.5B-Instruct'           # 初始base模型路径或者模型名字
adapter_model_path = '/home/output/test-lora-dpo'       # 你的DPO adapter模型路径
output_merged_path = '/home/output/merge-lora-dpo'              # 合并后模型保存路径# 加载基本模型和adapter
base_model = AutoModelForCausalLM.from_pretrained(base_model_path,torch_dtype=torch.float16,device_map='auto'
)
model = PeftModel.from_pretrained(base_model, adapter_model_path, device_map='auto')# 合并adapter权重到主模型
model = model.merge_and_unload()# 保存合并后的模型(完整的HF格式权重)
model.save_pretrained(output_merged_path)
# Tokenizer也复制一份到新路径:
tok = AutoTokenizer.from_pretrained(base_model_path)
tok.save_pretrained(output_merged_path)

合并模型:

(llmtuner) [llm_finetune]$ python lora_merge.py 
Sliding Window Attention is enabled but not implemented for `sdpa`; unexpected results may be encountered.
[2025-04-08 10:40:30,289] [INFO] [real_accelerator.py:239:get_accelerator] Setting ds_accelerator to cuda (auto detect)
(llmtuner) [llm_finetune]$ 

合并后的模型: 

(base) [merge-lora-dpo]$ du -h *
4.0K    added_tokens.json
4.0K    config.json
4.0K    generation_config.json
1.6M    merges.txt
943M    model.safetensors
4.0K    special_tokens_map.json
8.0K    tokenizer_config.json
11M     tokenizer.json
2.7M    vocab.json

模型结构应类似:

my_dpo_model/
├── config.json
├── tokenizer.json(或tokenizer.model)
├── pytorch_model.bin (或model.safetensors)
├── tokenizer_config.json
├── special_tokens_map.json
└── (...其他必要文件)
(llama) root@69e2b4914bb1:/llama.cpp# python convert_hf_to_gguf.py ../output/merge-lora-dpo --outtype f16 --outfile ../output/convert.bin
INFO:hf-to-gguf:Loading model: merge-lora-dpo
INFO:gguf.gguf_writer:gguf: This GGUF file is for Little Endian only
INFO:hf-to-gguf:Exporting model...
INFO:hf-to-gguf:gguf: loading model part 'model.safetensors'
INFO:hf-to-gguf:token_embd.weight,         torch.float16 --> F16, shape = {896, 151936}
INFO:hf-to-gguf:Set model quantization version
INFO:gguf.gguf_writer:Writing the following files:
INFO:gguf.gguf_writer:../output/convert.bin: n_tensors = 290, total_size = 988.2M
Writing: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 988M/988M [00:00<00:00, 1.01Gbyte/s]
INFO:hf-to-gguf:Model successfully exported to ../output/convert.bin

8 将HF模型转换到GGML FP16格式(中间步骤)

如果你的模型使用的是LLaMA2架构,可以指定类型:

python convert_hf_to_gguf.py ../output/merge-lora-dpo --outtype f16 --outfile ../output/dop_model_f16.gguf

你还可以转换到更小的量化,如Q4_0:

python convert_hf_to_gguf.py ../output/merge-lora-dpo --outtype q4_0 --outfile ../output/dop_model_q4_0.gguf

会报错

usage: convert_hf_to_gguf.py [-h] [--vocab-only] [--outfile OUTFILE] [--outtype {f32,f16,bf16,q8_0,tq1_0,tq2_0,auto}] [--bigendian] [--use-temp-file] [--no-lazy] [--model-name MODEL_NAME][--verbose] [--split-max-tensors SPLIT_MAX_TENSORS] [--split-max-size SPLIT_MAX_SIZE] [--dry-run] [--no-tensor-first-split] [--metadata METADATA][--print-supported-models] [--remote][model]
convert_hf_to_gguf.py: error: argument --outtype: invalid choice: 'q4_0' (choose from 'f32', 'f16', 'bf16', 'q8_0', 'tq1_0', 'tq2_0', 'auto')

最终得到:

(base) [nlp output]$ du -sh *
1.3G    convert.bin
1.2G    dop_model_f16.gguf
913M    dop_model_q8_0.gguf
958M    merge-lora-dpo
24M     test-lora-dpo

9 使用llama.cpp docker full进行量化

拉取llama.cpp docker

docker pull ghcr.io/ggerganov/llama.cpp:full

进入容器 

docker run -it --entrypoint /bin/bash -v /home/pretrained_model/output/:/output ghcr.io/ggerganov/llama.cpp:full

查看是否目录挂载成功

root@e4ed60eee5ae:/app# ll ../output/
total 3451908
drwxrwxrwx. 4 root root       145 Apr  8 03:30 ./
drwxr-xr-x. 1 root root        28 Apr  8 07:44 ../
-rw-r--r--. 1 root root 994156320 Apr  8 02:51 convert.bin
-rw-r--r--. 1 root root 994156320 Apr  8 03:28 dop_model_f16.gguf
-rw-r--r--. 1 root root 531067680 Apr  8 03:30 dop_model_q8_0.gguf
drwxrwxr-x. 2 1018 1018       263 Apr  8 02:40 merge-lora-dpo/
drwxrwxrwx. 2 root root      4096 Apr  1 09:54 test-lora-dpo/

量化出现段错误

root@01382885d44b:/app# ./llama-quantize ../output/dop_model_f16.gguf  ../output/dop_model-Q4_K_M.gguf Q4_K_M
main: build = 5074 (1466621e)
main: built with cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 for x86_64-linux-gnu
main: quantizing '../output/dop_model_f16.gguf' to '../output/dop_model-Q4_K_M.gguf' as Q4_K_M
llama_model_loader: loaded meta data with 26 key-value pairs and 290 tensors from ../output/dop_model_f16.gguf (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              = qwen2
llama_model_loader: - kv   1:                               general.type str              = model
llama_model_loader: - kv   2:                               general.name str              = Merge Lora Dpollama_model_loader: - type  f32:  121 tensors
llama_model_loader: - type  f16:  169 tensors
Segmentation fault (core dumped)

该问题暂未解决

10 ollama运行自己的gguf

10.1 准备Modefile

qwen的Modfile配置: 

​​https://qwen.readthedocs.io/zh-cn/latest/run_locally/ollama.html

具体解析:

参数设置 (PARAMETER)

  1. temperature 0.7

    • 控制生成文本的随机性:值越高(如1.0)输出越多样化/创造性,值越低(如0.2)输出越确定/保守。0.7是平衡创造性和连贯性的折中值。

  2. top_p 0.8

    • 核采样(Nucleus Sampling)参数:仅从概率累积超过80%的词汇中选择,过滤低概率词,平衡生成质量与多样性。

  3. repeat_penalty 1.05

    • 抑制重复内容的惩罚因子:1.05表示轻微惩罚重复词汇或短语,避免冗余。

  4. top_k 20

    • 限制每一步生成的候选词数量为前20个,配合
      top_p

      进一步控制多样性。

以下是针对模板(

TEMPLATE

)的逐条解析,结合其逻辑结构和功能进行详细说明:

1. 模板整体结构

{{ if .Messages }}  <!-- 检查是否存在多轮对话历史 -->{{- if or .System .Tools }}  <!-- 检查是否有系统消息或工具定义 --><!-- 系统消息和工具部分 -->{{ end }}{{- range $i, $_ := .Messages }}  <!-- 遍历每条消息 --><!-- 处理用户/助手/工具角色消息 -->{{- end }}
{{- else }}  <!-- 若无历史消息(单轮对话) --><!-- 直接拼接系统消息和用户提示 -->
{{ end }}

2. 系统消息和工具定义部分

<|im_start|>system
{{ .System }}  <!-- 插入系统消息内容 -->
{{- if .Tools }}  <!-- 如果有工具定义 --># Tools
<!-- 工具函数签名列表 -->
<tools>
{{- range .Tools }}
{"type": "function", "function": {{ .Function }}}  <!-- 每个工具的函数签名 -->
{{- end }}
</tools><!-- 工具调用格式说明 -->
For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
{{- end }}<|im_end|>

功能

  • 强制以
    <|im_start|>system
    开头,插入系统消息(如
    You are Qwen...
    )。
  • 如果存在工具(
    .Tools
    ),则:
    • <tools>
      标签内列出所有工具的函数签名(JSON格式)。
    • 说明模型应如何调用工具(返回
      <tool_call>
      包裹的JSON)。

3. 多轮消息处理(

range .Messages

遍历每条消息,根据角色(

user

/

assistant

/

tool

)生成不同格式:

用户消息(
user

{{- if eq .Role "user" }}<|im_start|>user
{{ .Content }}<|im_end|>  <!-- 用户输入内容 -->
{{ end }}

格式

<|im_start|>user

+ 内容 +

<|im_end|>
助手消息(
assistant

{{ else if eq .Role "assistant" }}<|im_start|>assistant
{{ if .Content }}{{ .Content }}  <!-- 文本回复 -->
{{- else if .ToolCalls }}<tool_call>  <!-- 工具调用 -->
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{ end }}</tool_call>
{{- end }}{{ if not $last }}<|im_end|>  <!-- 非最后一条则闭合 -->
{{ end }}

功能

  • 如果助手返回文本(
    .Content
    ),直接输出。
  • 如果调用工具(
    .ToolCalls
    ),生成
    <tool_call>
    标签包裹的JSON数组(支持多工具调用)。
  • 若非最后一条消息,添加
    <|im_end|>
工具返回消息(
tool

{{ else if eq .Role "tool" }}<|im_start|>user
<tool_response>
{{ .Content }}  <!-- 工具执行结果 -->
</tool_response><|im_end|>
{{ end }}

格式

user

角色模拟工具返回,内容用

<tool_response>

标签包裹。

自动触发助手回复
{{- if and (ne .Role "assistant") $last }}<|im_start|>assistant
{{ end }}

逻辑
如果最后一条消息不是助手发送的(如用户提问或工具返回),自动添加

<|im_start|>assistant

以触发模型回复。

4. 单轮对话(无历史消息)

{{- if .System }}<|im_start|>system
{{ .System }}<|im_end|>  <!-- 系统消息 -->
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>  <!-- 用户提示 -->
{{ end }}<|im_start|>assistant
{{ end }}{{ .Response }}{{ if .Response }}<|im_end|>{{ end }}

逻辑

  • 直接拼接
    system
    消息(可选)、用户
    prompt
    ,然后强制以
    <|im_start|>assistant
    开头等待模型生成。
  • 如果已有预生成响应(
    .Response
    ),追加并闭合。

10.2 ollama加载gguf

(llmtuner) [output]$ ollama create qwen2.5-0.5b-instruct-q4_0 -f ./Modelfile5
transferring model data 
using existing layer sha256:7671c0c304e6ce5a7fc577bcb12aba01e2c155cc2efd29b2213c95b18edaf6ed 
creating new layer sha256:012bbc1c050907cbab5abb78d995ca4cf87a8d25091000e3120b0be009035a1e 
creating new layer sha256:66b9ea09bd5b7099cbb4fc820f31b575c0366fa439b08245566692c6784e281e 
creating new layer sha256:9297f08dd6c6435240b5cddc93261e8a159aa0fecf010de4568ec2df2417bdb2 
creating new layer sha256:507a9849b8e66b2128d6f225f53bc474bae84fc524889ba8b575c341eab354b9 
writing manifest 
success 
(llmtuner) [wuwenliang@zt-media-nlp output]$ ollama run qwen2.5-0.5b-instruct-q4_0:latest            
>>> 你好
你好,很高兴为您服务。请问您有什么问题或者需要帮助的事项吗?我会尽力提供帮助。>>> 你叫什么名字
我是来自阿里巴巴云团队的Qwen,也被称为通义、小明或阿里小白,是阿里云自主研发的人工智能模型。

参考文章:

ollama 使用自己的微调模型_ollama 微调-CSDN博客

https://github.com/ggml-org/llama.cpp/blob/master/examples/quantize/README.md

llama.cpp - Qwen

相关文章:

  • 对程序中使用到的字体进行子集化处理
  • C语言高频面试题——常量指针与指针常量区别
  • 文档处理控件Aspose.Words 教程:在 Word 中删除空白页完整指南
  • 【C++游戏引擎开发】第19篇:Compute Shader实现Tile划分
  • Cursor可视化大屏搭建__0420
  • 软件功能测试和非功能测试有什么区别和联系?
  • 【同济】高等数学6.7.8版答案
  • 1+X: Python程序开发职业技能等级要求(初级)练习资料分享
  • 软件工程师中级考试-上午知识点总结(下)
  • 基于OKR的企业管理数字化实践——以围棋教育机构流程优化为例
  • 【数字图像处理】图像纹理分析
  • 基于STM32的HX711货物称重系统
  • QT文件和文件夹拷贝操作
  • NetApp ONTAP 9 故障磁盘更换操作指南
  • 《零基础入门学习Python》
  • OpenGL shader开发实战学习笔记:第十二章 深入光照
  • Linux指令合集
  • C++ STL:从零开始模拟实现 list 容器
  • ACWing——算法基础课
  • 棉花糖实验新解
  • 诸葛燕喃出任中央文化和旅游管理干部学院党委书记
  • 林间徐行寻风眠——关于浙美“徐宗帅捐赠纪念展”
  • 8个月女婴被指受虐后体重仅6斤?潮州警方:未发现虐待,父母有抚养意愿
  • 海南热带雨林国家公园核心保护区一水电站设施将拆除,曾被中央环保督察通报
  • 郑州一废弃饭店堆砌物起火:明火被扑灭,未造成人员伤亡
  • 泰康资产获批设立全资私募基金管理子公司,首期投资规模预计120亿元