可能大多数同学都像我一样,没有GPU,手头上也只有一台小破笔记本,又不想花钱买显卡买设备买云服务器。本文就带大家在这种条件下,实战一下微调 DeepSeek。

本文完整教程代码下载:文章末尾领取!
在这里插入图片描述

0. 环境准备

既然手头没有GPU,也没有能用的设备,那就得想办法白嫖其它服务了。本文使用两个工具:Colab 和 Unsloth。

0.1 Colab

Colab 是一款由谷歌推出的基于云端的编程环境。它具备诸多实用功能与显著优势。
在硬件资源方面,Colab 能为用户免费提供 GPU,这使得它在进行模型微调等任务时表现出色。尽管免费 GPU 的使用时长有一定限制,但一般来说,对于大部分模型微调需求而言,这些免费资源已经绰绰有余。
从使用便捷性来看,Colab 搭载了基于网页的 Jupyter Notebook 环境。用户无需经历繁琐的软件安装过程,只需通过浏览器就能轻松开启编程之旅,极大地降低了上手难度。
此外,Colab 拥有丰富的社区资源。在其平台上,用户可以轻松找到大量现成的代码示例以及详尽的教程,这对于新手来说无疑是一大福音,能够帮助他们迅速掌握相关知识和技能,快速进入编程状态。

0.2 unsloth

在这里插入图片描述

Unsloth 是一款开源工具,专注于加速大型语言模型(LLMs)的微调过程,具备诸多实用功能与显著优势。

在微调效率方面,Unsloth 的表现极为出色,其微调速度相较于传统方法能够提升 2 至 5 倍,并且内存占用可降低 50% 到 80%。这就意味着,借助 Unsloth,你可以利用更少的资源来完成微调任务,极大地提高了工作效率。

对于硬件设备的要求,Unsloth 也十分友好。它对显存的需求较低,即使是消费级 GPU,例如 RTX 3090,也能够轻松运行 Unsloth。以训练 1.5B 参数的模型为例,仅需 7GB 显存就可以满足要求。

在模型适配与量化技术方面,Unsloth 同样表现出色。它支持多种主流模型,包括 Llama、Mistral、Phi、Gemma 等。并且,通过采用动态 4 - bit 量化技术,Unsloth 能够显著降低显存占用,同时几乎不会损失模型精度,这在很大程度上提升了模型的实用性和适用范围。

此外,Unsloth 还具有开源与免费的优势。它提供了免费的 Colab Notebook,用户只需添加相应的数据集并运行代码,即可轻松完成微调工作。

总的来说,Unsloth 通过运用特定的优化技术,使得我们能够在配置相对较低的硬件设备资源环境下,更加高效地进行模型微调。在 Unsloth 出现之前,模型微调的成本居高不下,对于普通人来说几乎难以企及。通常情况下,微调一次模型不仅需要耗费数万元的资金,还需要花费数天的时间才能完成。

0.3 进入环境,准备实战!

(1)新建一个 Colab 页面,点击下方链接即可。(可能需要注册或者使用google账号登陆一下)

https://colab.research.google.com/#create=true

在这里插入图片描述

(2)点击菜单栏的 “代码执行程序”,选择下拉菜单中的 “更改运行时类型”

在这里插入图片描述

(3)选择 T4 GPU,这是 NVIDIA 推出的一款高性能 GPU,特别适合深度学习任务

在这里插入图片描述

好了,环境准备完毕,下面开始实战!

1. 安装依赖

首先安装一些 Python 包和库,这些库是运行 AI 模型微调任务所必需的工具。

  • • unsloth 是一个用于微调大型语言模型(LLM)的工具,可以让模型运行更快、占用更少内存。

  • • bitsandbytes 是一个用于量化和优化模型的库,可以帮助减少模型占用的内存。

  • • unsloth_zoo 可能包含了一些预训练模型或其他工具,方便我们使用。

pip install unsloth   pip install bitsandbytes unsloth_zoo

2. 加载预训练模型

接下来,加载一个预训练模型,咱们在这个模型上进行微调。

  • from_pretrained 函数用来加载模型。

  • model_name 参数指定这个模型的名称,我这里用的是 unsloth/DeepSeek-R1-Distill-Qwen-7B

from unsloth import FastLanguageModel  # 导入FastLanguageModel类,用来加载和使用模型   import torch  # 导入torch工具,用于处理模型的数学运算      max_seq_length = 2048  # 设置模型处理文本的最大长度,相当于给模型设置一个“最大容量”   dtype = None  # 设置数据类型,让模型自动选择最适合的精度   load_in_4bit = True  # 使用4位量化来节省内存,就像把大箱子压缩成小箱子      # 加载预训练模型,并获取tokenizer工具   model, tokenizer = FastLanguageModel.from_pretrained(       model_name="unsloth/DeepSeek-R1-Distill-Qwen-7B",  # 指定要加载的模型名称       max_seq_length=max_seq_length,  # 使用前面设置的最大长度       dtype=dtype,  # 使用前面设置的数据类型       load_in_4bit=load_in_4bit,  # 使用4位量化       # token="hf...",  # 如果需要访问授权模型,可以在这里填入密钥   )

在Colab中运行,可以看到以下的模型加载日志:

在这里插入图片描述

3. 微调前测试

在微调前,我们先来看下没有微调时模型的表现:这与我们平时调用模型API时的流程一样

(1)给一个Prompt

(2)调用 model.generate 生成结果

不过,这里也有几个不同的步骤:

(1)for_inference 准备模型进行推理

(2)inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda") 对prompt进行编码,并放到GPU中

(3)tokenizer.batch_decode(outputs) 大模型输出结果解码

prompt_style = """以下是描述任务的指令,以及提供进一步上下文的输入。   请写出一个适当完成请求的回答。   在回答之前,请仔细思考问题,并创建一个逻辑连贯的思考过程,以确保回答准确无误。      ### 指令:   你是一位精通卜卦、星象和运势预测的算命大师。   请回答以下算命问题。      ### 问题:   {}      ### 回答:   <think>{}</think>"""      # 定义提示风格的字符串模板,用于格式化问题      question = "1993年七月初九巳时生人,女,想了解爱情运势"   # 定义具体的算命问题      FastLanguageModel.for_inference(model)   # 准备模型以进行推理      inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")   # 使用 tokenizer 对格式化后的问题进行编码,并移动到 GPU      outputs = model.generate(       input_ids=inputs.input_ids,       attention_mask=inputs.attention_mask,       max_new_tokens=1200,       use_cache=True,   )   # 使用模型生成回答      response = tokenizer.batch_decode(outputs)   # 解码模型生成的输出为可读文本      print(response[0])   # 打印生成的回答部分

输出结果如下:

在这里插入图片描述

4. 加载数据集

在开始微调之前,还有关键的一步,就是加载数据集,并将数据集转换成微调所需的格式。

4.1 加载数据集

  • • 使用 load_dataset 函数可加载数据集

  • • 数据集名称:Conard/fortune-telling

  • • 使用数据集的前100条数据作为微调数据 split="train[0:100]"

# 定义一个用于格式化提示的多行字符串模板   train_prompt_style = """以下是描述任务的指令,以及提供进一步上下文的输入。   请写出一个适当完成请求的回答。   在回答之前,请仔细思考问题,并创建一个逻辑连贯的思考过程,以确保回答准确无误。      ### 指令:   你是一位精通八字算命、紫微斗数、风水、易经卦象、塔罗牌占卜、星象、面相手相和运势预测等方面的算命大师。   请回答以下算命问题。      ### 问题:   {}      ### 回答:   <思考>   {}   </思考>   {}"""      # 定义结束标记 (EOS_TOKEN),用于指示文本的结束   EOS_TOKEN = tokenizer.eos_token  # 必须添加结束标记      # 导入数据集加载函数   from datasets import load_dataset      # 加载指定的数据集,选择中文语言和训练集的前500条记录   dataset = load_dataset("Conard/fortune-telling", 'default', split="train[0:100]", trust_remote_code=True)      # 打印数据集的列名,查看数据集中有哪些字段   print(dataset.column_names)

加载数据集的过程日志:

在这里插入图片描述

4.2 格式化数据集

这一步是构造微调用的Prompt,将数据集中对应的字段填入train_prompt_style中。

# 定义一个函数,用于格式化数据集中的每条记录   def formatting_prompts_func(examples):       # 从数据集中提取问题、复杂思考过程和回答       inputs = examples["Question"]       cots = examples["Complex_CoT"]       outputs = examples["Response"]       texts = []  # 用于存储格式化后的文本          # 遍历每个问题、思考过程和回答,进行格式化       for input, cot, output in zip(inputs, cots, outputs):           # 使用字符串模板插入数据,并加上结束标记           text = train_prompt_style.format(input, cot, output) + EOS_TOKEN           texts.append(text)  # 将格式化后的文本添加到列表中          return {           "text": texts,  # 返回包含所有格式化文本的字典       }      dataset = dataset.map(formatting_prompts_func, batched=True)   dataset["text"][0]

以下是格式化完之后的 Prompt 数据示例。

在这里插入图片描述

5. 执行微调

环境、数据都准备好了,接下来终于可以开始微调了。微调前加载的代码如下:

FastLanguageModel.for_training(model)      model = FastLanguageModel.get_peft_model(       model,  # 传入已经加载好的预训练模型       r=16,  # 设置 LoRA 的秩,决定添加的可训练参数数量       target_modules=["q_proj", "k_proj", "v_proj", "o_proj",  # 指定模型中需要微调的关键模块                       "gate_proj", "up_proj", "down_proj"],       lora_alpha=16,  # 设置 LoRA 的超参数,影响可训练参数的训练方式       lora_dropout=0,  # 设置防止过拟合的参数,这里设置为 0 表示不丢弃任何参数       bias="none",  # 设置是否添加偏置项,这里设置为 "none" 表示不添加       use_gradient_checkpointing="unsloth",  # 使用优化技术节省显存并支持更大的批量大小       random_state=3407,  # 设置随机种子,确保每次运行代码时模型的初始化方式相同       # use_rsloora=False,  # 设置是否使用 Rank Stabilized LoRA 技术,这里设置为 False 表示不使用       loftq_config=None,  # 设置是否使用 LoftQ 技术,这里设置为 None 表示不使用   )      from trl import SFTTrainer  # 导入 SFTTrainer,用于监督式微调   from transformers import TrainingArguments  # 导入 TrainingArguments,用于设置训练参数   from unsloth import is_bfloat16_supported  # 导入函数,检查是否支持 bfloat16 数据格式      trainer = SFTTrainer(       model=model,  # 传入要微调的模型       tokenizer=tokenizer,  # 传入 tokenizer,用于处理文本数据       train_dataset=dataset,  # 传入训练数据集       dataset_text_field="text",  # 指定数据集中文本字段的名称       max_seq_length=max_seq_length,  # 设置最大序列长度       dataset_num_proc=2,  # 设置数据处理的并行进程数       packing=False,  # 是否启用打包功能(这里设置为 False,打包可以让训练更快,但可能影响效果)       args=TrainingArguments(           per_device_train_batch_size=2,  # 每个设备(如 GPU)上的批量大小           gradient_accumulation_steps=4,  # 梯度累积步数,用于模拟大批次训练           warmup_steps=5,  # 预热步数,训练开始时学习率逐渐增加的步数           max_steps=75,  # 最大训练步数           learning_rate=2e-4,  # 学习率,模型学习新知识的速度           fp16=not is_bfloat16_supported(),  # 是否使用 fp16 格式加速训练(如果环境不支持 bfloat16)           bf16=is_bfloat16_supported(),  # 是否使用 bfloat16 格式加速训练(如果环境支持)           logging_steps=1,  # 每隔多少步记录一次训练日志           optim="adamw_8bit",  # 使用的优化器,用于调整模型参数           weight_decay=0.01,  # 权重衰减,防止模型过拟合           lr_scheduler_type="linear",  # 学习率调度器类型,控制学习率的变化方式           seed=3407,  # 随机种子,确保训练结果可复现           output_dir="outputs",  # 训练结果保存的目录           report_to="none",  # 是否将训练结果报告到外部工具(如 WandB),这里设置为不报告       ),   )

微调前准备过程的日志:

在这里插入图片描述

最后,执行下面一句代码,开始微调。

trainer_stats = trainer.train()

微调过程的日志打印,100条数据,整个过程耗时30分钟左右。

在这里插入图片描述

6. 微调后测试

模型经过了微调,下面我们再用之前的Prompt测试一下微调是否有效果。

print(question)  # 打印前面的问题      # 将模型切换到推理模式,准备回答问题   FastLanguageModel.for_inference(model)      # 将问题转换成模型能理解的格式,并发送到 GPU 上   inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")      # 让模型根据问题生成回答,最多生成 1200 个新词   outputs = model.generate(       input_ids=inputs.input_ids,  # 输入的数字序列       attention_mask=inputs.attention_mask,  # 注意力遮罩,帮助模型理解哪些部分重要       max_new_tokens=1200,  # 最多生成 1200 个新词       use_cache=True,  # 使用缓存加速生成   )      # 将生成的回答从数字转换回文字   response = tokenizer.batch_decode(outputs)      # 打印回答   print(response[0])

运行结果如下:

在这里插入图片描述

先不管它回答的对不对,你就说,经过微调后,它的回答是不是显得专业了很多?

7. 微调模型的保存

7.1 保存前的准备

(1)需要首先申请一个hugging face的token

https://huggingface.co/settings/tokens

(2)创建一个 Write 的token

(3)复制这个token,填到colab的密钥中,密钥的名称填:HUGGINGFACE_TOKEN

在这里插入图片描述

7.2 将微调模型保存为gguf格式

GGUF 是一种高效的格式,它支持多种量化方法(如 4 位、8 位、16 位量化),可以显著减小模型文件的大小,便于存储和传输,适合在资源受限的设备上运行模型,例如在 Ollama 上部署时。量化后的模型在资源受限的设备上运行更快,适合边缘设备或低功耗场景。

# 导入 Google Colab 的 userdata 模块,用于访问用户数据   from google.colab import userdata      # 从 Google Colab 用户数据中获取 Hugging Face 的 API 令牌   HUGGINGFACE_TOKEN = userdata.get('HUGGINGFACE_TOKEN')      # 将模型保存为 8 位量化格式 (q8_0)   # 这种格式文件小且运行快,适合部署到资源受限的设备   if True: model.save_pretrained_gguf("model", tokenizer,)      # 将模型保存为 16 位量化格式 (f16)   # 16 位量化精度更高,但文件稍大   if False: model.save_pretrained_gguf("model_f16", tokenizer, quantization_method = "f16")      # 将模型保存为 4 位量化格式 (q4_k_m)   # 4 位量化文件最小,但精度可能稍低   if False: model.save_pretrained_gguf("model", tokenizer, quantization_method = "q4_k_m")

8. 微调模型上传到 HuggingFace

注意将模型仓库的名称修改为 自己的「用户名+模型名」。

# 导入 Hugging Face Hub 的 create_repo 函数,用于创建一个新的模型仓库   from huggingface_hub import create_repo      # 在 Hugging Face hub 上创建一个新的模型仓库   create_repo("你的Huggingface用户名/微调后模型的名字(自己定)", token=HUGGINGFACE_TOKEN, exist_ok=True)      # 将模型和分词器上传到 Hugging Face Hub 上的仓库   model.push_to_hub_gguf("你的Huggingface用户名/微调后模型的名字(自己定)", tokenizer, token=HUGGINGFACE_TOKEN)

如何学习AI大模型 ?

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。【保证100%免费】🆓

CSDN粉丝独家福利

这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以扫描下方二维码&点击下方CSDN官方认证链接免费领取 【保证100%免费】

读者福利: 👉👉CSDN大礼包:《最新AI大模型学习资源包》免费分享 👈👈

(👆👆👆安全链接,放心点击)

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

👉1.大模型入门学习思维导图👈

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程文末领取哈)
在这里插入图片描述

👉2.AGI大模型配套视频👈

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。

在这里插入图片描述
在这里插入图片描述

👉3.大模型实际应用报告合集👈

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程文末领取哈)

在这里插入图片描述

👉4.大模型落地应用案例PPT👈

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(全套教程文末领取哈)

在这里插入图片描述

👉5.大模型经典学习电子书👈

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。(全套教程文末领取哈)
img

在这里插入图片描述

👉6.大模型面试题&答案👈

截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。(全套教程文末领取哈)

在这里插入图片描述
👉学会后的收获:👈
基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习

CSDN粉丝独家福利

这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以扫描下方二维码&点击下方CSDN官方认证链接免费领取 【保证100%免费】

读者福利: 👉👉CSDN大礼包:《最新AI大模型学习资源包》免费分享 👈👈

(👆👆👆安全链接,放心点击)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐