自探索大语言模型微调(一)

发布于:2025-03-17 ⋅ 阅读:(10) ⋅ 点赞:(0)

一、数据

1.1、失败案例

Hugging Face:

根据B站上搜索到的资料,datasets这个库可以直接下载丰富的数据集合和与训练模型,调用也非常的简单,唯一的缺点就是,需要外网(翻墙),用国内的网数次无果后,选择放弃。

// 加载数据
import itertools

from datasets import load_dataset

test_dataset = load_dataset("p208p2002/wudao", split="train", streaming=True)

m = 5
show_test_data = list(itertools.islice(test_dataset, m))
print(show_test_data)

注意:有一些小伙伴可能会把pytorch里面的dataset和hugging face里面的datasets搞混,但它俩是不同的库里面的不同的类。 

1.2、数据集

北京智源人工智能研究院(智源研究院)的Data Hub网站:

Data Hubhttps://data.baai.ac.cn/data注意:需要确保一下电脑有那么多内存,一个数据集几百个G;

// 展示一下所下载的数据集
import json
import os

# 指定包含 JSON 文件的文件夹路径
folder_path = r'F:\AI\AI_Fine_Tune\pythonProject\data_WenBen\WuDaoCorpus2.0_base_200G'

# 获取文件夹中所有 JSON 文件的列表,并按文件名排序
json_files = sorted([f for f in os.listdir(folder_path) if f.endswith('.json')])

# 选择前5个文件,如果文件总数少于5个,则选择所有文件
json_files = json_files[:5]

# 遍历前5个 JSON 文件
for filename in json_files:
    file_path = os.path.join(folder_path, filename)

    # 打开文件并读取
    with open(file_path, 'r', encoding='utf-8') as file:
        # 使用 json.load() 直接加载整个文件内容
        data = json.load(file)

        # 打印正在处理的文件名
        print(json.dumps(data, indent=4, ensure_ascii=False))

 二、部署预训练模型

下载Ollama:Ollamahttps://ollama.com/

下载了以后,可以设置把用ollama拉取的模型存在指定的路径下:

  • 启动设置(Windows 11)或控制面板(Windows 10)应用程序,并搜索环境变量。
  • 点击编辑账户环境变量。 编辑或创建一个新的用户账户变量OLLAMA_MODELS,设置为您希望存储模型的路径。
  • 点击确定/应用以保存。
  • 如果Ollama已经在运行,请退出系统托盘中的应用程序,然后从开始菜单或在保存环境变量后启动的新终端中重新启动它。

将模型拉取下来,这里拉取deepseek R1 1.5b的小模型试一试水:

// 命令行窗口, 系统的哈(win + R, cmd),不是pycharm等里面的终端

// 拉取模型
ollama pull deepseek-r1:1.5b

// 启动模型
ollama run deepseek-r1:1.5b
//此时,你的模型已经启动,可以开始与模型进行交互了
//这里的交互是在windows系统的命令行窗口交互哦

// pycharm中调用ollama中的拉取的模型
import requests
import json

host = "localhost"
port = "11434"
url = f"http://{host}:{port}/api/chat"
model = "deepseek-r1:1.5b"

data = {
    "model": model,
    "messages": [{"role": "user", "content": "生成一个 Python 函数"}]
}

response = requests.post(url, json=data, timeout=60)
print(response.text)
// 该处response是很多个json对象,对应不同时间模型的输出,即是流式的
// 这种想要获取正常的一句话的结果,只能逐行拼接,就像下面这样

# 定义一个生成器函数,逐行处理响应内容
def process_stream(response):
    for line in response.iter_lines():
        if line:
            try:
                # 解析 JSON 数据
                data = json.loads(line.decode("utf-8"))
                # 提取 content 字段并返回
                if "message" in data and "content" in data["message"]:
                    yield data["message"]["content"]
            except json.JSONDecodeError as e:
                print(f"Error decoding JSON: {e}")

# 使用生成器函数逐行处理输出
final_output = ""
for content in process_stream(response):
    final_output += content

# 打印最终拼接的输出
print("Final Output:")
print(final_output)

三、数据处理

数据预处理,主要是将结构化的数据tokenize一下,并且对数据进行填充或者截断,这步主要是确保数据的大小与模型的要求相匹配;tokenize并不仅仅是将词分解成一个token那么大,而且它还将token大小的词转化成了数字

tokenize可以通过tokenizer实现,但需要注意的是tokenizer与模型是相匹配的,如果使用了错误的tokenizer会让模型很困惑,这样调出来的模型会一团糟。

// 这种是Hugging Face的,估计有可能用不了
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("DeepSeek-R1-Distill-Qwen-1.5B")
// 啊,真的用不了,不开心,还要去找词汇表和tokenizer的文件

// 经查阅,deepseek-r1:1.5b对应的分词器为LlamaTokenizerFast

因为,ollama拉取的模型文件形式为:

目前,据我了解和transform不匹配(调用会报找不到模型文件的错误,为什么呢?都可以交互了)。查阅魔塔社区的开源模型,看形式是匹配的,接下来去魔塔社区下载一个预训练模型;然后使用以下代码达成数据处理的目的:

from transformers import AutoTokenizer

model_dir = r"F:\AI\ollama_model"  # 替换为本地模型文件夹路径
tokenizer = AutoTokenizer.from_pretrained(model_dir)

四、模型微调

4.1、模型微调的方法

(一) LoRA(Low-Rank Adaptation)微调

这种方法的核心思想是通过引入低秩矩阵来调整模型的权重,而不是直接修改模型的所有参数。这种方式不仅节省计算资源,还能显著提高微调的效率。

W=W_0 +\left ( A * B \right )

其中,W是现在的权重,W_0是原始的权重,AB就是低秩权重;


网站公告

今日签到

点亮在社区的每一天
去签到