【LLM】Windows当地CPU摆设民间版中文羊驼模子(Chinese-LLaMA-Alpaca)踩坑记载

[复制链接]
发表于 2026-2-8 14:06:56 | 显示全部楼层 |阅读模式
目次
前言
预备工作
Git 
Python3.9 
Cmake
下载模子 
归并模子
摆设模子 


前言

想必有小搭档也想跟我一样体验下摆设大语言模子, 但碍于经济力气, 不外民间上出现了大量的量化模子, 我们布衣也能体验体验啦~, 该模子可以在条记本电脑上摆设, 确保你电脑至少有16G运行内存
开原地点:GitHub - ymcui/Chinese-LLaMA-Alpaca: 中文LLaMA&Alpaca大语言模子+当地CPU摆设 (Chinese LLaMA & Alpaca LLMs)
Linux和Mac的教程在开源的堆栈中有提供,固然假如你是M1的也可以参考以下文章:
https://gist.github.com/cedrickchee/e8d4cb0c4b1df6cc47ce8b18457ebde0

预备工作

最好是有署理, 否则你下载东西大概失败, 我为了下个模子花了一天时间, 痛哭~ 
我们须要先在电脑上安装以下环境:  


  • Git
  • Python3.9(利用Anaconda3创建该环境) 
  • Cmake(假如你电脑没有C和C++的编译环境还须要安装mingw)
Git 

下载地点:Git - Downloading Package 

   下载好安装包后打开, 不绝点下一步安装即可... 
  在cmd窗口输入以下假如有版本号表现分析已经安装乐成
  1. git -v
复制代码

Python3.9 

 我这里利用Anaconda3来利用Python, Anaconda3是什么?
   假如你熟悉docker, 那么你可以把docker的概念带过来, docker可以创建很多个容器, 每个容器的环境大概一样也大概不一样, Anaconda3也是一样的, 它可以创建很多个差别的Python版本, 相互不辩论, 想用哪个版本就切换到哪个版本...
   Anaconda3下载地点:Anaconda | Anaconda Distribution

 安装步调参考:







    等候安装好后不绝点next, 直到点Finish关闭即可
  在cmd窗口输入以下下令, 表现版本号则分析安装乐成
  1. conda -V
复制代码

接下来我们在cmd窗口输入以下下令创建一个python3.9的环境 
  1. conda create --name py39 python=3.9 -y
复制代码
  --name反面的py39是环境名字, 可以自己恣意起, 切换环境的时间须要它
  python=3.9是指定python版本
  添加-y后就不须要手动输入y去确认安装了
  

检察有哪些环境的下令:
  1. conda info -e
复制代码

激活/切换环境的下令:
  1. conda activate py39
复制代码
 要利用哪个环境的话换成对应名字即可

 进入环境后你就可以在这输入python干系的下令了, 如:

 要退出环境的话输入:
  1. conda deactivate
复制代码
当我退出环境后再检察python版本的话会提示我不是内部或外部下令,也不是可运行的步调
或批处理处罚文件。如:

Cmake

这是一个编译工具, 我们须要利用它去编译llama.cpp, 量化模子须要用到, 不量化模子个人电脑跑不起来, 以为量化这个概念不明确的可以明确为压缩, 这种概念是不对的, 只是为了资助你更好的明确.
在安装之前我们须要安装mingw, 制止编译时找不到编译环境, 按下win+r快捷键输入powershell
输入下令安装scoop, 这是一个包管理器, 我们利用它来下载安装mingw:
这个地方假如没有开署理的话大概会堕落 
  1. iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
复制代码
安装好后分别运行下面两个下令(添加库):
  1. scoop bucket add extras
复制代码
  1. scoop bucket add main
复制代码
 输入下令安装mingw
  1. scoop install mingw
复制代码
到这就已经安装好mingw了, 假如报错了请品评, 我看到了会复兴
接下来安装Cmake
地点:Download | CMake 

 安装参考:





    安装好后点Finish即可
  
下载模子 

我们须要下载两个模子, 一个是原版的LLaMA模子, 一个是扩充了中文的模子, 后续会举行一个归并模子的利用


  • 原版模子下载地点(要署理):https://ipfs.io/ipfs/Qmb9y5GCkTG7ZzbBWMu2BXwMkzyCKcUjtEKPpgdZ7GEFKm/
  • 备用:nyanko7/LLaMA-7B at main



  • 扩充了中文的模子下载:
发起在D盘上新建一个文件夹, 在内里举行下载利用, 如下:

 在弹出的框中分别输入以下下令:
  
  1. git lfs install
复制代码
  
  1. git clone https://huggingface.co/ziqingyang/chinese-alpaca-lora-7b
复制代码
这里大概会由于网络题目不绝失败......不绝重试就行, 有别的题目请品评, 看到会复兴

归并模子

终于写到这里了, 累~
在你下载了模子的目次内打开cmd窗口, 如下:

   这里我先说下这图片中的两个目次里文件是啥吧
  
  先是chinese-alpaca-lora-7b目次, 这个目次一样寻常你下载下来就不消动了, 格式如下:
  chinese-alpaca-lora-7b/
        - adapter_config.json
        - adapter_model.bin
        - special_tokens_map.json
        - tokenizer_config.json
        - tokenizer.model
  
  然后是path_to_original_llama_root_dir目次, 这个文件夹须要创建, 保持划一的文件名, 目次内的格式如下:
  path_to_original_llama_root_dir/
          - 7B/        #这是一个名为7B的文件夹
                  - checklist.chk
                  - consolidated.00.pth
                  - params.json
                  - tokenizer_checklist.chk
          - tokenizer.model
  自行按照上面的格式存放
   打开窗口后须要先激活python环境, 利用的就是前面装Anaconda3
  
  1. # 不记得有哪些环境的先运行以下命令
  2. conda info -e
  3. # 然后激活你需要的环境  我的环境名是py39
  4. conda activate py39
复制代码
切换好后分别实行以下下令安装依靠库
  
  1. pip install git+https://github.com/huggingface/transformers
  2. pip install sentencepiece==0.1.97
  3. pip install peft==0.2.0
复制代码
实行下令安装乐成后会有Successfully的字眼
 接下来须要将原版模子转HF格式, 须要借助最新版🤗transformers提供的脚本convert_llama_weights_to_hf.py
在目次内新建一个convert_llama_weights_to_hf.py文件, 用记事本打开后把以下代码粘贴进去
留意:我这里是为了方便直接拷贝出来了,脚本大概会更新,发起直接去以下地点拷贝最新的:
transformers/convert_llama_weights_to_hf.py at main · huggingface/transformers · GitHub
  
  1. # Copyright 2022 EleutherAI and The HuggingFace Inc. team. All rights reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. #     http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import argparse
  15. import gc
  16. import json
  17. import math
  18. import os
  19. import shutil
  20. import warnings
  21. import torch
  22. from transformers import LlamaConfig, LlamaForCausalLM, LlamaTokenizer
  23. try:
  24.     from transformers import LlamaTokenizerFast
  25. except ImportError as e:
  26.     warnings.warn(e)
  27.     warnings.warn(
  28.         "The converted tokenizer will be the `slow` tokenizer. To use the fast, update your `tokenizers` library and re-run the tokenizer conversion"
  29.     )
  30.     LlamaTokenizerFast = None
  31. """
  32. Sample usage:
  33. ```
  34. python src/transformers/models/llama/convert_llama_weights_to_hf.py \
  35.     --input_dir /path/to/downloaded/llama/weights --model_size 7B --output_dir /output/path
  36. ```
  37. Thereafter, models can be loaded via:
  38. ```py
  39. from transformers import LlamaForCausalLM, LlamaTokenizer
  40. model = LlamaForCausalLM.from_pretrained("/output/path")
  41. tokenizer = LlamaTokenizer.from_pretrained("/output/path")
  42. ```
  43. Important note: you need to be able to host the whole model in RAM to execute this script (even if the biggest versions
  44. come in several checkpoints they each contain a part of each weight of the model, so we need to load them all in RAM).
  45. """
  46. INTERMEDIATE_SIZE_MAP = {
  47.     "7B": 11008,
  48.     "13B": 13824,
  49.     "30B": 17920,
  50.     "65B": 22016,
  51. }
  52. NUM_SHARDS = {
  53.     "7B": 1,
  54.     "13B": 2,
  55.     "30B": 4,
  56.     "65B": 8,
  57. }
  58. def compute_intermediate_size(n):
  59.     return int(math.ceil(n * 8 / 3) + 255) // 256 * 256
  60. def read_json(path):
  61.     with open(path, "r") as f:
  62.         return json.load(f)
  63. def write_json(text, path):
  64.     with open(path, "w") as f:
  65.         json.dump(text, f)
  66. def write_model(model_path, input_base_path, model_size):
  67.     os.makedirs(model_path, exist_ok=True)
  68.     tmp_model_path = os.path.join(model_path, "tmp")
  69.     os.makedirs(tmp_model_path, exist_ok=True)
  70.     params = read_json(os.path.join(input_base_path, "params.json"))
  71.     num_shards = NUM_SHARDS[model_size]
  72.     n_layers = params["n_layers"]
  73.     n_heads = params["n_heads"]
  74.     n_heads_per_shard = n_heads // num_shards
  75.     dim = params["dim"]
  76.     dims_per_head = dim // n_heads
  77.     base = 10000.0
  78.     inv_freq = 1.0 / (base ** (torch.arange(0, dims_per_head, 2).float() / dims_per_head))
  79.     # permute for sliced rotary
  80.     def permute(w):
  81.         return w.view(n_heads, dim // n_heads // 2, 2, dim).transpose(1, 2).reshape(dim, dim)
  82.     print(f"Fetching all parameters from the checkpoint at {input_base_path}.")
  83.     # Load weights
  84.     if model_size == "7B":
  85.         # Not shared
  86.         # (The sharded implementation would also work, but this is simpler.)
  87.         loaded = torch.load(os.path.join(input_base_path, "consolidated.00.pth"), map_location="cpu")
  88.     else:
  89.         # Sharded
  90.         loaded = [
  91.             torch.load(os.path.join(input_base_path, f"consolidated.{i:02d}.pth"), map_location="cpu")
  92.             for i in range(num_shards)
  93.         ]
  94.     param_count = 0
  95.     index_dict = {"weight_map": {}}
  96.     for layer_i in range(n_layers):
  97.         filename = f"pytorch_model-{layer_i + 1}-of-{n_layers + 1}.bin"
  98.         if model_size == "7B":
  99.             # Unsharded
  100.             state_dict = {
  101.                 f"model.layers.{layer_i}.self_attn.q_proj.weight": permute(
  102.                     loaded[f"layers.{layer_i}.attention.wq.weight"]
  103.                 ),
  104.                 f"model.layers.{layer_i}.self_attn.k_proj.weight": permute(
  105.                     loaded[f"layers.{layer_i}.attention.wk.weight"]
  106.                 ),
  107.                 f"model.layers.{layer_i}.self_attn.v_proj.weight": loaded[f"layers.{layer_i}.attention.wv.weight"],
  108.                 f"model.layers.{layer_i}.self_attn.o_proj.weight": loaded[f"layers.{layer_i}.attention.wo.weight"],
  109.                 f"model.layers.{layer_i}.mlp.gate_proj.weight": loaded[f"layers.{layer_i}.feed_forward.w1.weight"],
  110.                 f"model.layers.{layer_i}.mlp.down_proj.weight": loaded[f"layers.{layer_i}.feed_forward.w2.weight"],
  111.                 f"model.layers.{layer_i}.mlp.up_proj.weight": loaded[f"layers.{layer_i}.feed_forward.w3.weight"],
  112.                 f"model.layers.{layer_i}.input_layernorm.weight": loaded[f"layers.{layer_i}.attention_norm.weight"],
  113.                 f"model.layers.{layer_i}.post_attention_layernorm.weight": loaded[f"layers.{layer_i}.ffn_norm.weight"],
  114.             }
  115.         else:
  116.             # Sharded
  117.             # Note that in the 13B checkpoint, not cloning the two following weights will result in the checkpoint
  118.             # becoming 37GB instead of 26GB for some reason.
  119.             state_dict = {
  120.                 f"model.layers.{layer_i}.input_layernorm.weight": loaded[0][
  121.                     f"layers.{layer_i}.attention_norm.weight"
  122.                 ].clone(),
  123.                 f"model.layers.{layer_i}.post_attention_layernorm.weight": loaded[0][
  124.                     f"layers.{layer_i}.ffn_norm.weight"
  125.                 ].clone(),
  126.             }
  127.             state_dict[f"model.layers.{layer_i}.self_attn.q_proj.weight"] = permute(
  128.                 torch.cat(
  129.                     [
  130.                         loaded[i][f"layers.{layer_i}.attention.wq.weight"].view(n_heads_per_shard, dims_per_head, dim)
  131.                         for i in range(num_shards)
  132.                     ],
  133.                     dim=0,
  134.                 ).reshape(dim, dim)
  135.             )
  136.             state_dict[f"model.layers.{layer_i}.self_attn.k_proj.weight"] = permute(
  137.                 torch.cat(
  138.                     [
  139.                         loaded[i][f"layers.{layer_i}.attention.wk.weight"].view(n_heads_per_shard, dims_per_head, dim)
  140.                         for i in range(num_shards)
  141.                     ],
  142.                     dim=0,
  143.                 ).reshape(dim, dim)
  144.             )
  145.             state_dict[f"model.layers.{layer_i}.self_attn.v_proj.weight"] = torch.cat(
  146.                 [
  147.                     loaded[i][f"layers.{layer_i}.attention.wv.weight"].view(n_heads_per_shard, dims_per_head, dim)
  148.                     for i in range(num_shards)
  149.                 ],
  150.                 dim=0,
  151.             ).reshape(dim, dim)
  152.             state_dict[f"model.layers.{layer_i}.self_attn.o_proj.weight"] = torch.cat(
  153.                 [loaded[i][f"layers.{layer_i}.attention.wo.weight"] for i in range(num_shards)], dim=1
  154.             )
  155.             state_dict[f"model.layers.{layer_i}.mlp.gate_proj.weight"] = torch.cat(
  156.                 [loaded[i][f"layers.{layer_i}.feed_forward.w1.weight"] for i in range(num_shards)], dim=0
  157.             )
  158.             state_dict[f"model.layers.{layer_i}.mlp.down_proj.weight"] = torch.cat(
  159.                 [loaded[i][f"layers.{layer_i}.feed_forward.w2.weight"] for i in range(num_shards)], dim=1
  160.             )
  161.             state_dict[f"model.layers.{layer_i}.mlp.up_proj.weight"] = torch.cat(
  162.                 [loaded[i][f"layers.{layer_i}.feed_forward.w3.weight"] for i in range(num_shards)], dim=0
  163.             )
  164.         state_dict[f"model.layers.{layer_i}.self_attn.rotary_emb.inv_freq"] = inv_freq
  165.         for k, v in state_dict.items():
  166.             index_dict["weight_map"][k] = filename
  167.             param_count += v.numel()
  168.         torch.save(state_dict, os.path.join(tmp_model_path, filename))
  169.     filename = f"pytorch_model-{n_layers + 1}-of-{n_layers + 1}.bin"
  170.     if model_size == "7B":
  171.         # Unsharded
  172.         state_dict = {
  173.             "model.embed_tokens.weight": loaded["tok_embeddings.weight"],
  174.             "model.norm.weight": loaded["norm.weight"],
  175.             "lm_head.weight": loaded["output.weight"],
  176.         }
  177.     else:
  178.         state_dict = {
  179.             "model.norm.weight": loaded[0]["norm.weight"],
  180.             "model.embed_tokens.weight": torch.cat(
  181.                 [loaded[i]["tok_embeddings.weight"] for i in range(num_shards)], dim=1
  182.             ),
  183.             "lm_head.weight": torch.cat([loaded[i]["output.weight"] for i in range(num_shards)], dim=0),
  184.         }
  185.     for k, v in state_dict.items():
  186.         index_dict["weight_map"][k] = filename
  187.         param_count += v.numel()
  188.     torch.save(state_dict, os.path.join(tmp_model_path, filename))
  189.     # Write configs
  190.     index_dict["metadata"] = {"total_size": param_count * 2}
  191.     write_json(index_dict, os.path.join(tmp_model_path, "pytorch_model.bin.index.json"))
  192.     config = LlamaConfig(
  193.         hidden_size=dim,
  194.         intermediate_size=compute_intermediate_size(dim),
  195.         num_attention_heads=params["n_heads"],
  196.         num_hidden_layers=params["n_layers"],
  197.         rms_norm_eps=params["norm_eps"],
  198.     )
  199.     config.save_pretrained(tmp_model_path)
  200.     # Make space so we can load the model properly now.
  201.     del state_dict
  202.     del loaded
  203.     gc.collect()
  204.     print("Loading the checkpoint in a Llama model.")
  205.     model = LlamaForCausalLM.from_pretrained(tmp_model_path, torch_dtype=torch.float16, low_cpu_mem_usage=True)
  206.     # Avoid saving this as part of the config.
  207.     del model.config._name_or_path
  208.     print("Saving in the Transformers format.")
  209.     model.save_pretrained(model_path)
  210.     shutil.rmtree(tmp_model_path)
  211. def write_tokenizer(tokenizer_path, input_tokenizer_path):
  212.     # Initialize the tokenizer based on the `spm` model
  213.     tokenizer_class = LlamaTokenizer if LlamaTokenizerFast is None else LlamaTokenizerFast
  214.     print("Saving a {tokenizer_class} to {tokenizer_path}")
  215.     tokenizer = tokenizer_class(input_tokenizer_path)
  216.     tokenizer.save_pretrained(tokenizer_path)
  217. def main():
  218.     parser = argparse.ArgumentParser()
  219.     parser.add_argument(
  220.         "--input_dir",
  221.         help="Location of LLaMA weights, which contains tokenizer.model and model folders",
  222.     )
  223.     parser.add_argument(
  224.         "--model_size",
  225.         choices=["7B", "13B", "30B", "65B", "tokenizer_only"],
  226.     )
  227.     parser.add_argument(
  228.         "--output_dir",
  229.         help="Location to write HF model and tokenizer",
  230.     )
  231.     args = parser.parse_args()
  232.     if args.model_size != "tokenizer_only":
  233.         write_model(
  234.             model_path=args.output_dir,
  235.             input_base_path=os.path.join(args.input_dir, args.model_size),
  236.             model_size=args.model_size,
  237.         )
  238.     spm_path = os.path.join(args.input_dir, "tokenizer.model")
  239.     write_tokenizer(args.output_dir, spm_path)
  240. if __name__ == "__main__":
  241.     main()
复制代码
在cmd窗口实行下令(假如你利用了anaconda,实行下令前请先激活环境):
  
  1. python convert_llama_weights_to_hf.py --input_dir path_to_original_llama_root_dir --model_size 7B --output_dir path_to_original_llama_hf_dir
复制代码
颠末漫长的等候....

 接下来归并输出PyTorch版本权重(.pth文件),利用merge_llama_with_chinese_lora.py脚本
在目次新建一个merge_llama_with_chinese_lora.py文件, 用记事本打开将以下代码粘贴进去
留意:我这里是为了方便直接拷贝出来了,脚本大概会更新,发起直接去以下地点拷贝最新的: 
Chinese-LLaMA-Alpaca/merge_llama_with_chinese_lora.py at main · ymcui/Chinese-LLaMA-Alpaca · GitHub
  
  1. """
  2. Borrowed and modified from https://github.com/tloen/alpaca-lora
  3. """
  4. import argparse
  5. import os
  6. import json
  7. import gc
  8. import torch
  9. import transformers
  10. import peft
  11. from peft import PeftModel
  12. parser = argparse.ArgumentParser()
  13. parser.add_argument('--base_model',default=None,required=True,type=str,help="Please specify a base_model")
  14. parser.add_argument('--lora_model',default=None,required=True,type=str,help="Please specify a lora_model")
  15. # deprecated; the script infers the model size from the checkpoint
  16. parser.add_argument('--model_size',default='7B',type=str,help="Size of the LLaMA model",choices=['7B','13B'])
  17. parser.add_argument('--offload_dir',default=None,type=str,help="(Optional) Please specify a temp folder for offloading (useful for low-RAM machines). Default None (disable offload).")
  18. parser.add_argument('--output_dir',default='./',type=str)
  19. args = parser.parse_args()
  20. assert (
  21.     "LlamaTokenizer" in transformers._import_structure["models.llama"]
  22. ), "LLaMA is now in HuggingFace's main branch.\nPlease reinstall it: pip uninstall transformers && pip install git+https://github.com/huggingface/transformers.git"
  23. from transformers import LlamaTokenizer, LlamaForCausalLM
  24. BASE_MODEL = args.base_model
  25. LORA_MODEL = args.lora_model
  26. output_dir = args.output_dir
  27. assert (
  28.     BASE_MODEL
  29. ), "Please specify a BASE_MODEL in the script, e.g. 'decapoda-research/llama-7b-hf'"
  30. tokenizer = LlamaTokenizer.from_pretrained(LORA_MODEL)
  31. if args.offload_dir is not None:
  32.     # Load with offloading, which is useful for low-RAM machines.
  33.     # Note that if you have enough RAM, please use original method instead, as it is faster.
  34.     base_model = LlamaForCausalLM.from_pretrained(
  35.         BASE_MODEL,
  36.         load_in_8bit=False,
  37.         torch_dtype=torch.float16,
  38.         offload_folder=args.offload_dir,
  39.         offload_state_dict=True,
  40.         low_cpu_mem_usage=True,
  41.         device_map={"": "cpu"},
  42.     )
  43. else:
  44.     # Original method without offloading
  45.     base_model = LlamaForCausalLM.from_pretrained(
  46.         BASE_MODEL,
  47.         load_in_8bit=False,
  48.         torch_dtype=torch.float16,
  49.         device_map={"": "cpu"},
  50.     )
  51. base_model.resize_token_embeddings(len(tokenizer))
  52. assert base_model.get_input_embeddings().weight.size(0) == len(tokenizer)
  53. tokenizer.save_pretrained(output_dir)
  54. print(f"Extended vocabulary size: {len(tokenizer)}")
  55. first_weight = base_model.model.layers[0].self_attn.q_proj.weight
  56. first_weight_old = first_weight.clone()
  57. ## infer the model size from the checkpoint
  58. emb_to_model_size = {
  59.     4096 : '7B',
  60.     5120 : '13B',
  61.     6656 : '30B',
  62.     8192 : '65B',
  63. }
  64. embedding_size = base_model.get_input_embeddings().weight.size(1)
  65. model_size = emb_to_model_size[embedding_size]
  66. print(f"Loading LoRA for {model_size} model")
  67. lora_model = PeftModel.from_pretrained(
  68.     base_model,
  69.     LORA_MODEL,
  70.     device_map={"": "cpu"},
  71.     torch_dtype=torch.float16,
  72. )
  73. assert torch.allclose(first_weight_old, first_weight)
  74. # merge weights
  75. print(f"Peft version: {peft.__version__}")
  76. print(f"Merging model")
  77. if peft.__version__ > '0.2.0':
  78.     # merge weights - new merging method from peft
  79.     lora_model = lora_model.merge_and_unload()
  80. else:
  81.     # merge weights
  82.     for layer in lora_model.base_model.model.model.layers:
  83.         if hasattr(layer.self_attn.q_proj,'merge_weights'):
  84.             layer.self_attn.q_proj.merge_weights = True
  85.         if hasattr(layer.self_attn.v_proj,'merge_weights'):
  86.             layer.self_attn.v_proj.merge_weights = True
  87.         if hasattr(layer.self_attn.k_proj,'merge_weights'):
  88.             layer.self_attn.k_proj.merge_weights = True
  89.         if hasattr(layer.self_attn.o_proj,'merge_weights'):
  90.             layer.self_attn.o_proj.merge_weights = True
  91.         if hasattr(layer.mlp.gate_proj,'merge_weights'):
  92.             layer.mlp.gate_proj.merge_weights = True
  93.         if hasattr(layer.mlp.down_proj,'merge_weights'):
  94.             layer.mlp.down_proj.merge_weights = True
  95.         if hasattr(layer.mlp.up_proj,'merge_weights'):
  96.             layer.mlp.up_proj.merge_weights = True
  97. lora_model.train(False)
  98. # did we do anything?
  99. assert not torch.allclose(first_weight_old, first_weight)
  100. lora_model_sd = lora_model.state_dict()
  101. del lora_model, base_model
  102. num_shards_of_models = {'7B': 1, '13B': 2}
  103. params_of_models = {
  104.     '7B':
  105.         {
  106.         "dim": 4096,
  107.         "multiple_of": 256,
  108.         "n_heads": 32,
  109.         "n_layers": 32,
  110.         "norm_eps": 1e-06,
  111.         "vocab_size": -1,
  112.         },
  113.     '13B':
  114.         {
  115.         "dim": 5120,
  116.         "multiple_of": 256,
  117.         "n_heads": 40,
  118.         "n_layers": 40,
  119.         "norm_eps": 1e-06,
  120.         "vocab_size": -1,
  121.         },
  122. }
  123. params = params_of_models[model_size]
  124. num_shards = num_shards_of_models[model_size]
  125. n_layers = params["n_layers"]
  126. n_heads = params["n_heads"]
  127. dim = params["dim"]
  128. dims_per_head = dim // n_heads
  129. base = 10000.0
  130. inv_freq = 1.0 / (base ** (torch.arange(0, dims_per_head, 2).float() / dims_per_head))
  131. def permute(w):
  132.     return (
  133.         w.view(n_heads, dim // n_heads // 2, 2, dim).transpose(1, 2).reshape(dim, dim)
  134.     )
  135. def unpermute(w):
  136.     return (
  137.         w.view(n_heads, 2, dim // n_heads // 2, dim).transpose(1, 2).reshape(dim, dim)
  138.     )
  139. def translate_state_dict_key(k):
  140.     k = k.replace("base_model.model.", "")
  141.     if k == "model.embed_tokens.weight":
  142.         return "tok_embeddings.weight"
  143.     elif k == "model.norm.weight":
  144.         return "norm.weight"
  145.     elif k == "lm_head.weight":
  146.         return "output.weight"
  147.     elif k.startswith("model.layers."):
  148.         layer = k.split(".")[2]
  149.         if k.endswith(".self_attn.q_proj.weight"):
  150.             return f"layers.{layer}.attention.wq.weight"
  151.         elif k.endswith(".self_attn.k_proj.weight"):
  152.             return f"layers.{layer}.attention.wk.weight"
  153.         elif k.endswith(".self_attn.v_proj.weight"):
  154.             return f"layers.{layer}.attention.wv.weight"
  155.         elif k.endswith(".self_attn.o_proj.weight"):
  156.             return f"layers.{layer}.attention.wo.weight"
  157.         elif k.endswith(".mlp.gate_proj.weight"):
  158.             return f"layers.{layer}.feed_forward.w1.weight"
  159.         elif k.endswith(".mlp.down_proj.weight"):
  160.             return f"layers.{layer}.feed_forward.w2.weight"
  161.         elif k.endswith(".mlp.up_proj.weight"):
  162.             return f"layers.{layer}.feed_forward.w3.weight"
  163.         elif k.endswith(".input_layernorm.weight"):
  164.             return f"layers.{layer}.attention_norm.weight"
  165.         elif k.endswith(".post_attention_layernorm.weight"):
  166.             return f"layers.{layer}.ffn_norm.weight"
  167.         elif k.endswith("rotary_emb.inv_freq") or "lora" in k:
  168.             return None
  169.         else:
  170.             print(layer, k)
  171.             raise NotImplementedError
  172.     else:
  173.         print(k)
  174.         raise NotImplementedError
  175. def save_shards(lora_model_sd, num_shards: int):
  176.     # Add the no_grad context manager
  177.     with torch.no_grad():
  178.         if num_shards == 1:
  179.             new_state_dict = {}
  180.             for k, v in lora_model_sd.items():
  181.                 new_k = translate_state_dict_key(k)
  182.                 if new_k is not None:
  183.                     if "wq" in new_k or "wk" in new_k:
  184.                         new_state_dict[new_k] = unpermute(v)
  185.                     else:
  186.                         new_state_dict[new_k] = v
  187.             os.makedirs(output_dir, exist_ok=True)
  188.             print(f"Saving shard 1 of {num_shards} into {output_dir}/consolidated.00.pth")
  189.             torch.save(new_state_dict, output_dir + "/consolidated.00.pth")
  190.             with open(output_dir + "/params.json", "w") as f:
  191.                 json.dump(params, f)
  192.         else:
  193.             new_state_dicts = [dict() for _ in range(num_shards)]
  194.             for k in list(lora_model_sd.keys()):
  195.                 v = lora_model_sd[k]
  196.                 new_k = translate_state_dict_key(k)
  197.                 if new_k is not None:
  198.                     if new_k=='tok_embeddings.weight':
  199.                         print(f"Processing {new_k}")
  200.                         assert v.size(1)%num_shards==0
  201.                         splits = v.split(v.size(1)//num_shards,dim=1)
  202.                     elif new_k=='output.weight':
  203.                         print(f"Processing {new_k}")
  204.                         splits = v.split(v.size(0)//num_shards,dim=0)
  205.                     elif new_k=='norm.weight':
  206.                         print(f"Processing {new_k}")
  207.                         splits = [v] * num_shards
  208.                     elif 'ffn_norm.weight' in new_k:
  209.                         print(f"Processing {new_k}")
  210.                         splits = [v] * num_shards
  211.                     elif 'attention_norm.weight' in new_k:
  212.                         print(f"Processing {new_k}")
  213.                         splits = [v] * num_shards
  214.                     elif 'w1.weight' in new_k:
  215.                         print(f"Processing {new_k}")
  216.                         splits = v.split(v.size(0)//num_shards,dim=0)
  217.                     elif 'w2.weight' in new_k:
  218.                         print(f"Processing {new_k}")
  219.                         splits = v.split(v.size(1)//num_shards,dim=1)
  220.                     elif 'w3.weight' in new_k:
  221.                         print(f"Processing {new_k}")
  222.                         splits = v.split(v.size(0)//num_shards,dim=0)
  223.                     elif 'wo.weight' in new_k:
  224.                         print(f"Processing {new_k}")
  225.                         splits = v.split(v.size(1)//num_shards,dim=1)
  226.                     elif 'wv.weight' in new_k:
  227.                         print(f"Processing {new_k}")
  228.                         splits = v.split(v.size(0)//num_shards,dim=0)
  229.                     elif "wq.weight" in new_k or "wk.weight" in new_k:
  230.                         print(f"Processing {new_k}")
  231.                         v = unpermute(v)
  232.                         splits = v.split(v.size(0)//num_shards,dim=0)
  233.                     else:
  234.                         print(f"Unexpected key {new_k}")
  235.                         raise ValueError
  236.                     for sd,split in zip(new_state_dicts,splits):
  237.                         sd[new_k] = split.clone()
  238.                         del split
  239.                     del splits
  240.                 del lora_model_sd[k],v
  241.                 gc.collect()    # Effectively enforce garbage collection
  242.             os.makedirs(output_dir, exist_ok=True)
  243.             for i,new_state_dict in enumerate(new_state_dicts):
  244.                 print(f"Saving shard {i+1} of {num_shards} into {output_dir}/consolidated.0{i}.pth")
  245.                 torch.save(new_state_dict, output_dir + f"/consolidated.0{i}.pth")
  246.             with open(output_dir + "/params.json", "w") as f:
  247.                 print(f"Saving params.json into {output_dir}/params.json")
  248.                 json.dump(params, f)
  249. save_shards(lora_model_sd=lora_model_sd, num_shards=num_shards)
复制代码
 实行下令(假如你利用了anaconda,实行下令前请先激活环境):
  
  1. python merge_llama_with_chinese_lora.py --base_model path_to_original_llama_hf_dir --lora_model chinese-alpaca-lora-7b --output_dir path_to_output_dir
复制代码
参数分析:


  • --base_model:存放HF格式的LLaMA模子权重和设置文件的目次(前面步调中转的hf格式)
  • --lora_model:扩充了中文的模子目次
  • --output_dir:指定生存全量模子权重的目次,默以为./(归并出来的目次)
  • (可选)--offload_dir:对于低内存用户须要指定一个offload缓存路径
  更具体的请看开原堆栈:GitHub - ymcui/Chinese-LLaMA-Alpaca: 中文LLaMA&Alpaca大语言模子+当地CPU/GPU摆设 (Chinese LLaMA & Alpaca LLMs)
  到这里就已经归并好模子了, 目次:

接下来就预备摆设吧

摆设模子 

我们须要先下载llama.cpp举行模子的量化, 输入以下下令: 
  
  1. git clone https://github.com/ggerganov/llama.cpp
复制代码
目次如: 

 重点来了, 在窗口中输入以下下令进入刚刚下载的llama.cpp
  
  1. cd llama.cpp
复制代码
 假如你是跟着教程利用scoop(包管理器)安装的MinGW,请利用以下下令(不是的请以后看):
  
  1. cmake . -G "MinGW Makefiles"
  2. cmake --build . --config Release
复制代码
 走完以上下令后你应该能在llama.cpp的bin目次内看到以下文件:

 假如你是利用的安装包的方式安装的MinGW,请利用以下下令:
  
  1. mkdir build
  2. cd build
  3. cmake ..
  4. cmake --build . --config Release
复制代码
走完以上下令后在build =》Release =》bin目次下应该会有以下文件:

   以上下令不能都输入,看你自己的环境选择下令!!! 
  假如没有以上的文件, 那你应该是报错了, 根本上要么就是下载依靠的地方错, 要么就是编译的地方堕落, 我在这里探索了很久 
接下来在llama.cpp内新建一个zh-models文件夹, 预备天生量化版本模子
   zh-models的目次格式如下:
  zh-models/
          - 7B/        #这是一个名为7B的文件夹
                - consolidated.00.pth
                - params.json
        - tokenizer.model
  
  把path_to_output_dir文件夹内的consolidated.00.pth和params.json文件放入上面格式中的位置
  把path_to_output_dir文件夹内的tokenizer.model文件放在跟7B文件夹同级的位置
  

  接着在窗口中输入下令将上述.pth模子权重转换为ggml的FP16格式,天生文件路径为zh-models/7B/ggml-model-f16.bin
  
  1. python convert-pth-to-ggml.py zh-models/7B/ 1
复制代码

 进一步对FP16模子举行4-bit量化,天生量化模子文件路径为zh-models/7B/ggml-model-q4_0.bin
  
  1. D:\llama\llama.cpp\bin\quantize.exe ./zh-models/7B/ggml-model-f16.bin ./zh-models/7B/ggml-model-q4_0.bin 2
复制代码
   quantize.exe文件在bin目次内, 自行根据路径更改
  
​到这就已经量化好了, 可以举行摆设看看效果了, 摆设的话假如你电脑设置好的可以选择摆设f16的,否则就摆设q4_0的....
  
  1. D:\llama\llama.cpp\bin\main.exe -m zh-models/7B/ggml-model-q4_0.bin --color -f prompts/alpaca.txt -ins -c 2048 --temp 0.2 -n 256 --repeat_penalty 1.3
复制代码
在提示符 > 之后输入你的prompt,cmd/ctrl+c制止输出,多行信息以\作为行尾 
   常用参数(更多参数请实行D:\llama\llama.cpp\bin\main.exe -h下令):
  -ins 启动类ChatGPT对话交换的运行模式
-f 指定prompt模板,alpaca模子请加载prompts/alpaca.txt
-c 控制上下文的长度,值越大越能参考更长的对话汗青(默认:512)
-n 控制复兴天生的最大长度(默认:128)
-b 控制batch size(默认:8),可恰当增长
-t 控制线程数目(默认:4),可恰当增长
--repeat_penalty 控制天生复兴中对重复文本的处罚力度
--temp 温度系数,值越低复兴的随机性越小,反之越大
--top_p, top_k 控制解码采样的干系参数
  
  想要摆设f16的可以把下令中-m参数换成zh-models/7B/ggml-model-f16.bin即可
  摆设效果:

终于写完了~

参考:


  • GitHub - ymcui/Chinese-LLaMA-Alpaca: 中文LLaMA&Alpaca大语言模子+当地CPU/GPU摆设 (Chinese LLaMA & Alpaca LLMs)

👍点赞,你的认但是我创作的动力 !
🌟收藏,你的青睐是我积极的方向!
✏️品评,你的意见是我进步的财产!   

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表