大模型高效微调(Finetune)实战教程——以DeepSeek-R1-Distill-Qwen-7B为例

Unsloth是一个开源工具,专门用来加速大语言模型(LLMs)的微调过程。它的主要功能和优势包括:

  • 🔭 高效微调:Unsloth 的微调速度比传统方法快 2-5 倍,内存占用减少 50%-80%。这意味着你可以用更少的资源完成微调任务。
  • ⚡ 低显存需求:即使是消费级 GPU(如 RTX 3090),也能轻松运行 Unsloth。例如,仅需 7GB 显存就可以训练 1.5B 参数的模型。
  • 🎯 支持多种模型和量化:Unsloth 支持 Llama、Mistral、Phi、Gemma 等主流模型,并且通过动态 4-bit 量化技术,显著降低显存占用,同时几乎不损失模型精度。
  • 🎁 开源与免费:Unsloth 提供免费的 Colab Notebook,用户只需添加数据集并运行代码即可完成微调。

微调的基本流程如下:

No description has been provided for this image

第一步:安装依赖&环境验证

In [2]:

%%capture
# 卸载当前已安装的 unsloth 包(如果已安装),然后从 GitHub 的源代码安装最新版本。
# 这样可以确保我们使用的是最新功能和修复。
!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir --no-deps git+https://github.com/unslothai/unsloth.git
# 安装 bitsandbytes 和 unsloth_zoo 包。
# bitsandbytes 是一个用于量化和优化模型的库,可以帮助减少模型占用的内存。unsloth_zoo 可能包含了一些预训练模型或其他工具,方便我们使用。
!pip install bitsandbytes unsloth_zoo xformers

In [3]:

import sys
import torch
import platform
from importlib.metadata import version

# 输出 Python 版本
print("Python 版本:", sys.version)

# 输出操作系统信息
print("操作系统:", platform.platform())

# 检查 CUDA 是否可用及相关信息
print("CUDA 是否可用:", torch.cuda.is_available())
if torch.cuda.is_available():
    print("CUDA 版本 (PyTorch 编译时使用的):", torch.version.cuda)
    print("当前 CUDA 设备数量:", torch.cuda.device_count())
    print("当前 CUDA 设备:", torch.cuda.current_device())
    print("当前 CUDA 设备名称:", torch.cuda.get_device_name(torch.cuda.current_device()))

# 输出 PyTorch 版本
print("PyTorch 版本:", torch.__version__)

# 输出其他库的版本(如果已安装)
libraries = ["triton", "unsloth", "xformers"]
for lib in libraries:
    try:
        print(f"{lib} 版本:", version(lib))
    except ImportError:
        print(f"{lib} 未安装")

Python 版本: 3.11.11 (main, Dec  4 2024, 08:55:07) [GCC 11.4.0]
操作系统: Linux-6.1.85+-x86_64-with-glibc2.35
CUDA 是否可用: True
CUDA 版本 (PyTorch 编译时使用的): 12.4
当前 CUDA 设备数量: 1
当前 CUDA 设备: 0
当前 CUDA 设备名称: Tesla T4
PyTorch 版本: 2.6.0+cu124
triton 版本: 3.2.0
unsloth 版本: 2025.3.19
xformers 版本: 0.0.29.post3

第二步:加载预训练模型

In [4]:

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_...",  # 如果需要访问授权模型,可以在这里填入密钥
)

🦥 Unsloth: Will patch your computer to enable 2x faster free finetuning.
🦥 Unsloth Zoo will now patch everything to make training faster!
==((====))==  Unsloth 2025.3.19: Fast Qwen2 patching. Transformers: 4.50.0.
   \\   /|    Tesla T4. Num GPUs = 1. Max memory: 14.741 GB. Platform: Linux.
O^O/ \_/ \    Torch: 2.6.0+cu124. CUDA: 7.5. CUDA Toolkit: 12.4. Triton: 3.2.0
\        /    Bfloat16 = FALSE. FA [Xformers = 0.0.29.post3. FA2 = False]
 "-____-"     Free license: http://github.com/unslothai/unsloth
Unsloth: Fast downloading is enabled - ignore downloading bars which are red colored!

model.safetensors.index.json:   0%|          | 0.00/100k [00:00<?, ?B/s]

model-00001-of-00002.safetensors:   0%|          | 0.00/4.97G [00:00<?, ?B/s]

model-00002-of-00002.safetensors:   0%|          | 0.00/3.52G [00:00<?, ?B/s]

Loading checkpoint shards:   0%|          | 0/2 [00:00<?, ?it/s]

generation_config.json:   0%|          | 0.00/236 [00:00<?, ?B/s]

tokenizer_config.json:   0%|          | 0.00/6.78k [00:00<?, ?B/s]

tokenizer.json:   0%|          | 0.00/11.4M [00:00<?, ?B/s]

special_tokens_map.json:   0%|          | 0.00/472 [00:00<?, ?B/s]

第三步:微调前测试

In [5]:

# 定义提示风格的字符串模板,用于格式化问题
prompt_style = """
Below is an instruction that describes a task, paired with an input that provides further context.
Write a response that appropriately completes the request.
Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.

### Instruction:
You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.
Please answer the following medical question.

### Question:
{}

### Response:
<think>{}
"""

# 定义具体的医学问题
question = "一个患有急性阑尾炎的病人已经发病5天,腹痛稍有减轻但仍然发热,在体检时发现右下腹有压痛的包块,此时应如何处理?"

In [6]:

# 将大模型设置为推理模式
FastLanguageModel.for_inference(model)

# 使用 tokenizer 对格式化后的问题进行编码,并移动到 GPU
inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")

# 使用模型生成回答
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].split("### Response:")[1])

<think>
好,我现在要帮这位用户解答一个关于急性阑尾炎的医疗问题。首先,我得仔细理解用户提供的背景信息。病人已经发病5天,腹痛稍微减轻,但还有发热,现在体检时发现右下腹有压痛的包块。我需要判断接下来的处理步骤。

首先,急性阑尾炎通常是严重的感染性疾病,需要及时处理。病程5天不算太长,但发热和包块提示可能有其他问题,比如胆囊炎或者其他器官的感染。所以,我得考虑包块的性质和可能的并发症。

包块的大小和位置也很重要。如果包块较大,可能压迫到其他脏器,比如输尿管或者右侧肾,这会导致右侧肾盂肾炎,这是一种严重的并发症。如果包块较小,可能需要进一步的检查,比如超声波或者穿刺活检,以确定性质。

接下来,我应该考虑进一步的诊断。如果没有明显其他症状,比如发热持续、剧烈疼痛,或者伴随其他器官的症状,可能包块是良性的,比如脂肪瘤或软组织瘤。但如果有这些迹象,就需要考虑恶性可能性。

诊断方面,超声检查是一个快速且可靠的手段。如果发现包块是实性、大于3cm,或者有不规则的形状,可能提示恶性。同时,检查包块的穿刺活检也是必要的,尤其是如果怀疑恶性的话。

治疗方面,如果包块是良性的,可能需要保守处理,比如超声引导下穿刺引流,或者手术切除。但如果包块是恶性的,尤其是当有严重并发症的迹象时,可能需要立即手术治疗。

此外,我还要考虑发热的原因。发热可能是感染的迹象,但也可能是其他原因,比如代谢性疾病或者寄生虫感染。但在这个情况下,结合腹痛和包块,更可能的是感染性疾病。

总结一下,处理步骤应该是:首先评估包块的性质和大小,进行超声检查,必要时穿刺活检,根据结果决定是否手术治疗。同时,关注发热的情况,如果持续不退,可能需要进一步的治疗或者考虑其他原因。

最后,我需要确保回答条理清晰,步骤明确,让医生能够快速做出决策。同时,语言要准确,避免歧义,确保信息的正确性。
</think>

在面对急性阑尾炎的患者时,处理情况需要综合考虑多种因素。首先,评估患者是否有其他严重症状,如发热持续、剧烈腹痛或伴随其他器官受压的情况。如果包块较大且压迫到输尿管或右侧肾,应考虑右侧肾盂肾炎的并发症。此时,超声检查是关键,以确定包块的性质和大小。若包块实性且大于3cm或有不规则形态,建议进行穿刺活检以排除恶性可能。根据检查结果,决定是否进行手术治疗,包括超声引导穿刺或直接手术切除。同时,发热的持续性需要进一步评估,可能涉及感染或其他原因。及时诊断和处理是确保患者康复的关键。<|end▁of▁sentence|>

第四步:加载数据集

In [7]:

# 定义一个用于格式化提示的多行字符串模板
train_prompt_style = """
Below is an instruction that describes a task, paired with an input that provides further context.
Write a response that appropriately completes the request.
Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.

### Instruction:
You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.
Please answer the following medical question.

### Question:
{}

### Response:
<think>
{}
</think>
{}
"""

In [8]:

# 定义结束标记(EOS_TOKEN),用于指示文本的结束
EOS_TOKEN = tokenizer.eos_token  # 必须添加结束标记

# 导入数据集加载函数
from datasets import load_dataset

# 加载指定的数据集,选择中文语言和训练集的前500条记录
dataset = load_dataset("FreedomIntelligence/medical-o1-reasoning-SFT", 'zh', split = "train[0:500]", trust_remote_code=True)

# 打印数据集的列名,查看数据集中有哪些字段
print(dataset.column_names)

README.md:   0%|          | 0.00/1.65k [00:00<?, ?B/s]

medical_o1_sft_Chinese.json:   0%|          | 0.00/64.8M [00:00<?, ?B/s]

Generating train split:   0%|          | 0/24772 [00:00<?, ? examples/s]

['Question', 'Complex_CoT', 'Response']

In [9]:

# 定义一个函数,用于格式化数据集中的每条记录
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]

Map:   0%|          | 0/500 [00:00<?, ? examples/s]

Out[9]:

'\nBelow is an instruction that describes a task, paired with an input that provides further context.\nWrite a response that appropriately completes the request.\nBefore answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.\n\n### Instruction:\nYou are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.\nPlease answer the following medical question.\n\n### Question:\n根据描述,一个1岁的孩子在夏季头皮出现多处小结节,长期不愈合,且现在疮大如梅,溃破流脓,口不收敛,头皮下有空洞,患处皮肤增厚。这种病症在中医中诊断为什么病?\n\n### Response:\n<think>\n这个小孩子在夏天头皮上长了些小结节,一直都没好,后来变成了脓包,流了好多脓。想想夏天那么热,可能和湿热有关。才一岁的小孩,免疫力本来就不强,夏天的湿热没准就侵袭了身体。\n\n用中医的角度来看,出现小结节、再加上长期不愈合,这些症状让我想到了头疮。小孩子最容易得这些皮肤病,主要因为湿热在体表郁结。\n\n但再看看,头皮下还有空洞,这可能不止是简单的头疮。看起来病情挺严重的,也许是脓肿没治好。这样的情况中医中有时候叫做禿疮或者湿疮,也可能是另一种情况。\n\n等一下,头皮上的空洞和皮肤增厚更像是疾病已经深入到头皮下,这是不是说明有可能是流注或瘰疬?这些名字常描述头部或颈部的严重感染,特别是有化脓不愈合,又形成通道或空洞的情况。\n\n仔细想想,我怎么感觉这些症状更贴近瘰疬的表现?尤其考虑到孩子的年纪和夏天发生的季节性因素,湿热可能是主因,但可能也有火毒或者痰湿造成的滞留。\n\n回到基本的症状描述上看,这种长期不愈合又复杂的状况,如果结合中医更偏重的病名,是不是有可能是涉及更深层次的感染?\n\n再考虑一下,这应该不是单纯的瘰疬,得仔细分析头皮增厚并出现空洞这样的严重症状。中医里头,这样的表现可能更符合‘蚀疮’或‘头疽’。这些病名通常描述头部严重感染后的溃烂和组织坏死。\n\n看看季节和孩子的体质,夏天又湿又热,外邪很容易侵入头部,对孩子这么弱的免疫系统简直就是挑战。头疽这个病名听起来真是切合,因为它描述的感染严重,溃烂到出现空洞。\n\n不过,仔细琢磨后发现,还有个病名似乎更为合适,叫做‘蝼蛄疖’,这病在中医里专指像这种严重感染并伴有深部空洞的情况。它也涵盖了化脓和皮肤增厚这些症状。\n\n哦,该不会是夏季湿热,导致湿毒入侵,孩子的体质不能御,其病情发展成这样的感染?综合分析后我觉得‘蝼蛄疖’这个病名真是相当符合。\n</think>\n从中医的角度来看,你所描述的症状符合“蝼蛄疖”的病症。这种病症通常发生在头皮,表现为多处结节,溃破流脓,形成空洞,患处皮肤增厚且长期不愈合。湿热较重的夏季更容易导致这种病症的发展,特别是在免疫力较弱的儿童身上。建议结合中医的清热解毒、祛湿消肿的治疗方法进行处理,并配合专业的医疗建议进行详细诊断和治疗。\n<|end▁of▁sentence|>'

第五步:执行微调

In [10]:

# 将大模型设置为训练模式
FastLanguageModel.for_training(model)

# 使用参数高效微调(PEFT)中的lora方式执行微调,设定一些超参数
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_rslora = False,  # 设置是否使用 Rank Stabilized LoRA 技术,这里设置为 False 表示不使用
    loftq_config = None,  # 设置是否使用 LoftQ 技术,这里设置为 None 表示不使用
)

Unsloth 2025.3.19 patched 28 layers with 28 QKV layers, 28 O layers and 28 MLP layers.

In [11]:

from trl import SFTTrainer  # 导入 SFTTrainer,用于监督式微调
from transformers import TrainingArguments  # 导入 TrainingArguments,用于设置训练参数
from unsloth import is_bfloat16_supported  # 导入函数,检查是否支持 bfloat16 数据格式

trainer = SFTTrainer(  # 创建一个 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=100,  # 最大训练步数
      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),这里设置为不报告
    ),
)

Unsloth: Tokenizing ["text"] (num_proc=2):   0%|          | 0/500 [00:00<?, ? examples/s]

In [12]:

# 执行训练
trainer_stats = trainer.train()

==((====))==  Unsloth - 2x faster free finetuning | Num GPUs used = 1
   \\   /|    Num examples = 500 | Num Epochs = 2 | Total steps = 100
O^O/ \_/ \    Batch size per device = 2 | Gradient accumulation steps = 4
\        /    Data Parallel GPUs = 1 | Total batch size (2 x 4 x 1) = 8
 "-____-"     Trainable parameters = 40,370,176/7,000,000,000 (0.58% trained)

Unsloth: Will smartly offload gradients to save VRAM!

[100/100 27:59, Epoch 1.59/2]

StepTraining Loss
12.716100
23.082100
32.798900
42.797500
52.322000
62.494300
72.701300
82.528200
92.564100
102.415500
112.152400
122.052900
132.052000
142.247500
151.989500
161.903100
172.297800
182.281300
191.959400
202.002300
211.920200
221.930500
231.970600
241.925400
252.173000
262.104100
272.039400
281.787000
292.074500
302.267400
312.072800
322.043400
331.970800
341.885800
352.006400
362.031200
372.066900
381.707100
392.059300
401.837000
412.048900
421.715900
431.964100
441.671500
452.070300
461.928500
472.029300
481.863700
491.838000
501.888700
511.744300
521.839200
531.765000
542.054400
551.983000
561.866000
571.743900
581.966100
591.762600
602.025800
611.393900
621.939400
632.215300
641.993100
651.874300
661.752300
671.802900
682.014400
691.877800
701.565300
711.690100
721.903200
731.817500
741.896300
752.054800
761.610000
771.960400
781.893200
791.962600
801.945200
811.769600
821.619300
831.878200
841.587200
851.863500
861.885700
871.958700
881.666200
891.895700
901.950900
911.762100
921.890000
932.067100
941.837900
951.925300
961.951300
972.056500
981.741900
992.002600

[100/100 28:21, Epoch 1/2]

StepTraining Loss
12.716100
23.082100
32.798900
42.797500
52.322000
62.494300
72.701300
82.528200
92.564100
102.415500
112.152400
122.052900
132.052000
142.247500
151.989500
161.903100
172.297800
182.281300
191.959400
202.002300
211.920200
221.930500
231.970600
241.925400
252.173000
262.104100
272.039400
281.787000
292.074500
302.267400
312.072800
322.043400
331.970800
341.885800
352.006400
362.031200
372.066900
381.707100
392.059300
401.837000
412.048900
421.715900
431.964100
441.671500
452.070300
461.928500
472.029300
481.863700
491.838000
501.888700
511.744300
521.839200
531.765000
542.054400
551.983000
561.866000
571.743900
581.966100
591.762600
602.025800
611.393900
621.939400
632.215300
641.993100
651.874300
661.752300
671.802900
682.014400
691.877800
701.565300
711.690100
721.903200
731.817500
741.896300
752.054800
761.610000
771.960400
781.893200
791.962600
801.945200
811.769600
821.619300
831.878200
841.587200
851.863500
861.885700
871.958700
881.666200
891.895700
901.950900
911.762100
921.890000
932.067100
941.837900
951.925300
961.951300
972.056500
981.741900
992.002600
1001.835600

第六步:微调后测试

In [13]:

# 打印前面的问题
print(question)

一个患有急性阑尾炎的病人已经发病5天,腹痛稍有减轻但仍然发热,在体检时发现右下腹有压痛的包块,此时应如何处理?

In [14]:

#测试同一个问题的答案
# 将模型切换到推理模式,准备回答问题
FastLanguageModel.for_inference(model)

# 将问题转换成模型能理解的格式,并发送到 GPU 上
inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")

# 让模型根据问题生成回答,最多生成 10000 个新词
outputs = model.generate(
    input_ids=inputs.input_ids,  # 输入的数字序列
    attention_mask=inputs.attention_mask,  # 注意力遮罩,帮助模型理解哪些部分重要
    max_new_tokens=10000,  # 最多生成 4000 个新词
    use_cache=True,  # 使用缓存加速生成
)

# 将生成的回答从数字转换回文字
response = tokenizer.batch_decode(outputs)

# 打印回答
print(response[0].split("### Response:")[1])

<think>
这个病人已经有急性阑尾炎5天了,虽然腹痛稍微减轻了,但还是有发热的情况。现在体检的时候发现右下腹有个包块,这可真让人有点紧张。

首先,我得想想这个包块的性质。包块是硬的,而且可能伴随疼痛,这让我想到可能是结核。结核在阑尾炎中是很常见的,而且它常常会带来很多并发症。

可是,也别忘了,阑尾炎还有其他可能性,比如急性坏死性阑尾炎。这个情况,虽然也有可能,但一般来说,坏死性阑尾炎发生得很快,不像现在这样已经有几天了。

所以,这个包块可能更倾向于结核。结核在急性阑尾炎中确实是个大问题,而且在包块上常常有这些表现。这个包块还伴随疼痛,这让我更倾向于结核了。

不过,为了安全起见,还是得再想想有没有其他可能性。比如,急性坏死性阑尾炎,虽然可能性不大,但也不能完全排除。这个情况通常会伴随严重的腹痛和发热,而且会有包块,但可能更倾向于坏死性。

不过,通常情况下,如果包块只是硬的,而且没有特别剧烈的疼痛,可能还是更倾向于结核。所以,为了稳妥,我觉得还是先做结核的检查吧。

如果检查结果是结核,那就得马上处理,毕竟结核可真是个大麻烦。但如果还是坏死性,那就需要处理坏死,虽然可能性不大,但也不能掉以轻心。

不管怎样,结核检查还是必要的,这样就能明确情况,做出正确的处理决定。所以,先做个结核的检查,确认一下是结核还是坏死性,再根据结果来处理吧。
</think>
在急性阑尾炎的病人中,右下腹的包块可能是结核或坏死性阑尾炎的表现。根据目前的症状,虽然腹痛稍有减轻,但仍然伴随发热,且包块硬且可能伴随疼痛,这可能提示结核。因此,在这种情况下,建议进行结核检查,以明确诊断。结核处理是关键,因为它可能带来严重的并发症,而坏死性阑尾炎的可能性相对较低。因此,建议立即进行结核的检查,以做出正确的处理决定。
<|end▁of▁sentence|>

第七步:本地保存模型

In [ ]:

#保存Lora权重
model.save_pretrained("ckpts/lora_model")
tokenizer.save_pretrained("ckpts/lora_model")

In [ ]:

# 加载模型
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = "ckpts/lora_model",
    max_seq_length = max_seq_length,
    load_in_4bit = True,
)
FastLanguageModel.for_inference(model)
inputs = tokenizer([prompt_style.format(question)], return_tensors='pt', max_length=max_seq_length).to("cuda")
outputs = model.generate(inputs['input_ids'], attention_mask=inputs['attention_mask'], max_length=max_seq_length, use_cache=True)
answer = tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]
print(answer)

第八步:Ollama调用

需先保存为GGUF格式的模型文件再调用:D

 

 如何系统的去学习大模型LLM ?

大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等问题热议不断。

事实上,抢你饭碗的不是AI,而是会利用AI的人。

科大讯飞、阿里、华为等巨头公司发布AI产品后,很多中小企业也陆续进场!超高年薪,挖掘AI大模型人才! 如今大厂老板们,也更倾向于会AI的人,普通程序员,还有应对的机会吗?

与其焦虑……

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!

但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高。

基于此,我用做产品的心态来打磨这份大模型教程,深挖痛点并持续修改了近70次后,终于把整个AI大模型的学习门槛,降到了最低!

在这个版本当中:

第一您不需要具备任何算法和数学的基础
第二不要求准备高配置的电脑
第三不必懂Python等任何编程语言

您只需要听我讲,跟着我做即可,为了让学习的道路变得更简单,这份大模型教程已经给大家整理并打包,现在将这份 LLM大模型资料 分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓

一、LLM大模型经典书籍

AI大模型已经成为了当今科技领域的一大热点,那以下这些大模型书籍就是非常不错的学习资源。

在这里插入图片描述

二、640套LLM大模型报告合集

这套包含640份报告的合集,涵盖了大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(几乎涵盖所有行业)
在这里插入图片描述

三、LLM大模型系列视频教程

在这里插入图片描述

四、LLM大模型开源教程(LLaLA/Meta/chatglm/chatgpt)

在这里插入图片描述

五、AI产品经理大模型教程

在这里插入图片描述

LLM大模型学习路线 

阶段1:AI大模型时代的基础理解

  • 目标:了解AI大模型的基本概念、发展历程和核心原理。

  • 内容

    • L1.1 人工智能简述与大模型起源
    • L1.2 大模型与通用人工智能
    • L1.3 GPT模型的发展历程
    • L1.4 模型工程
    • L1.4.1 知识大模型
    • L1.4.2 生产大模型
    • L1.4.3 模型工程方法论
    • L1.4.4 模型工程实践
    • L1.5 GPT应用案例

阶段2:AI大模型API应用开发工程

  • 目标:掌握AI大模型API的使用和开发,以及相关的编程技能。

  • 内容

    • L2.1 API接口
    • L2.1.1 OpenAI API接口
    • L2.1.2 Python接口接入
    • L2.1.3 BOT工具类框架
    • L2.1.4 代码示例
    • L2.2 Prompt框架
    • L2.3 流水线工程
    • L2.4 总结与展望

阶段3:AI大模型应用架构实践

  • 目标:深入理解AI大模型的应用架构,并能够进行私有化部署。

  • 内容

    • L3.1 Agent模型框架
    • L3.2 MetaGPT
    • L3.3 ChatGLM
    • L3.4 LLAMA
    • L3.5 其他大模型介绍

阶段4:AI大模型私有化部署

  • 目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。

  • 内容

    • L4.1 模型私有化部署概述
    • L4.2 模型私有化部署的关键技术
    • L4.3 模型私有化部署的实施步骤
    • L4.4 模型私有化部署的应用场景

这份 LLM大模型资料 包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓

DIY使用ESP32的手持游戏手柄并通过BLE进行通信 硬件部件: esp32× 1个 ws2812b× 6 游戏杆× 2 角度按钮× 2 按钮× 8 18560电池和电池座× 2 三向拨动开关× 1个 TP4056带保护的电池充电电路× 1个 MT3608升压转换器× 1个 软件应用程序和在线服务: Arduino IDE 手动工具和制造机: 烙铁(通用) 这是一个使用ESP32微控制器制作的DIY手持游戏手柄。您可能之前已经看过这样的游戏控制器。但大多数使用Arduino。或更具体地说,是Arduino pro micro或Leonardo开发板。因为这些板支持HID或通过USB的人机接口设备。但是esp32没有这种功能。那么我们该怎么做呢?嗯,esp32确实具有BLE或低功耗蓝牙,我们可以使用它通过蓝牙进行无线通信。 因此,我们有ESP32模块作为中央控制器,然后有USB C型端口和一个3.3v稳压器,可将5v转换为3.3v。然后我们有了编程电路,使用具有自动编程模式的ch340c usb到串行转换器和使用双工晶体管的自动复位电路。我们还具有电池充电电路,以及过充电和过放电保护功能。然后使用升压转换器ic将其升压至5v。接下来,我们有操纵杆,D-Pad按钮,触发按钮,Neopixel LED和i2c端口。最后是3向开关,可在USB电源和电池电源之间切换。 游戏手柄2个模拟游戏杆 2个触发按钮 2个D-Pads 6个可寻址RGB LED 和一个i2c端口 它可以使用2个18650锂离子电池运行,可以使用USB C型端口对其进行更改。它也可以用来对微控制器进行编程。该设计的灵感来自新的ps5控制器,以使其外观更好。GPIO4使用分压器连接到电池。这样我们就可以测量电池电压了。NeoPixel LED将指示控制器是否连接到设备或电池电压是否低。 该代码基于lemmingDev的BLE Gamepad库。在代码中,我为不同的输入定义了所有GPIO引脚。然后在设置中有一些初始的led动画。板子一旦连接到设备,所有的LED就会变成绿色。并且它将按先前定义的时间间隔检查电池电压。然后我们获得按钮状态,并相应地设置游戏手柄按钮。然后,我们采用模拟输入,并将其映射到合适的值。最后根据我们收到的值设置轴。上载代码后,在智能手机或PC上打开蓝牙菜单,您会看到一个新设备弹出。单击该按钮将其连接,就可以开始游戏了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值