Unsloth是一个开源工具,专门用来加速大语言模型(LLMs)的微调过程。它的主要功能和优势包括:
- 🔭 高效微调:Unsloth 的微调速度比传统方法快 2-5 倍,内存占用减少 50%-80%。这意味着你可以用更少的资源完成微调任务。
- ⚡ 低显存需求:即使是消费级 GPU(如 RTX 3090),也能轻松运行 Unsloth。例如,仅需 7GB 显存就可以训练 1.5B 参数的模型。
- 🎯 支持多种模型和量化:Unsloth 支持 Llama、Mistral、Phi、Gemma 等主流模型,并且通过动态 4-bit 量化技术,显著降低显存占用,同时几乎不损失模型精度。
- 🎁 开源与免费:Unsloth 提供免费的 Colab Notebook,用户只需添加数据集并运行代码即可完成微调。
微调的基本流程如下:
第一步:安装依赖&环境验证
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]
Step | Training Loss |
---|---|
1 | 2.716100 |
2 | 3.082100 |
3 | 2.798900 |
4 | 2.797500 |
5 | 2.322000 |
6 | 2.494300 |
7 | 2.701300 |
8 | 2.528200 |
9 | 2.564100 |
10 | 2.415500 |
11 | 2.152400 |
12 | 2.052900 |
13 | 2.052000 |
14 | 2.247500 |
15 | 1.989500 |
16 | 1.903100 |
17 | 2.297800 |
18 | 2.281300 |
19 | 1.959400 |
20 | 2.002300 |
21 | 1.920200 |
22 | 1.930500 |
23 | 1.970600 |
24 | 1.925400 |
25 | 2.173000 |
26 | 2.104100 |
27 | 2.039400 |
28 | 1.787000 |
29 | 2.074500 |
30 | 2.267400 |
31 | 2.072800 |
32 | 2.043400 |
33 | 1.970800 |
34 | 1.885800 |
35 | 2.006400 |
36 | 2.031200 |
37 | 2.066900 |
38 | 1.707100 |
39 | 2.059300 |
40 | 1.837000 |
41 | 2.048900 |
42 | 1.715900 |
43 | 1.964100 |
44 | 1.671500 |
45 | 2.070300 |
46 | 1.928500 |
47 | 2.029300 |
48 | 1.863700 |
49 | 1.838000 |
50 | 1.888700 |
51 | 1.744300 |
52 | 1.839200 |
53 | 1.765000 |
54 | 2.054400 |
55 | 1.983000 |
56 | 1.866000 |
57 | 1.743900 |
58 | 1.966100 |
59 | 1.762600 |
60 | 2.025800 |
61 | 1.393900 |
62 | 1.939400 |
63 | 2.215300 |
64 | 1.993100 |
65 | 1.874300 |
66 | 1.752300 |
67 | 1.802900 |
68 | 2.014400 |
69 | 1.877800 |
70 | 1.565300 |
71 | 1.690100 |
72 | 1.903200 |
73 | 1.817500 |
74 | 1.896300 |
75 | 2.054800 |
76 | 1.610000 |
77 | 1.960400 |
78 | 1.893200 |
79 | 1.962600 |
80 | 1.945200 |
81 | 1.769600 |
82 | 1.619300 |
83 | 1.878200 |
84 | 1.587200 |
85 | 1.863500 |
86 | 1.885700 |
87 | 1.958700 |
88 | 1.666200 |
89 | 1.895700 |
90 | 1.950900 |
91 | 1.762100 |
92 | 1.890000 |
93 | 2.067100 |
94 | 1.837900 |
95 | 1.925300 |
96 | 1.951300 |
97 | 2.056500 |
98 | 1.741900 |
99 | 2.002600 |
[100/100 28:21, Epoch 1/2]
Step | Training Loss |
---|---|
1 | 2.716100 |
2 | 3.082100 |
3 | 2.798900 |
4 | 2.797500 |
5 | 2.322000 |
6 | 2.494300 |
7 | 2.701300 |
8 | 2.528200 |
9 | 2.564100 |
10 | 2.415500 |
11 | 2.152400 |
12 | 2.052900 |
13 | 2.052000 |
14 | 2.247500 |
15 | 1.989500 |
16 | 1.903100 |
17 | 2.297800 |
18 | 2.281300 |
19 | 1.959400 |
20 | 2.002300 |
21 | 1.920200 |
22 | 1.930500 |
23 | 1.970600 |
24 | 1.925400 |
25 | 2.173000 |
26 | 2.104100 |
27 | 2.039400 |
28 | 1.787000 |
29 | 2.074500 |
30 | 2.267400 |
31 | 2.072800 |
32 | 2.043400 |
33 | 1.970800 |
34 | 1.885800 |
35 | 2.006400 |
36 | 2.031200 |
37 | 2.066900 |
38 | 1.707100 |
39 | 2.059300 |
40 | 1.837000 |
41 | 2.048900 |
42 | 1.715900 |
43 | 1.964100 |
44 | 1.671500 |
45 | 2.070300 |
46 | 1.928500 |
47 | 2.029300 |
48 | 1.863700 |
49 | 1.838000 |
50 | 1.888700 |
51 | 1.744300 |
52 | 1.839200 |
53 | 1.765000 |
54 | 2.054400 |
55 | 1.983000 |
56 | 1.866000 |
57 | 1.743900 |
58 | 1.966100 |
59 | 1.762600 |
60 | 2.025800 |
61 | 1.393900 |
62 | 1.939400 |
63 | 2.215300 |
64 | 1.993100 |
65 | 1.874300 |
66 | 1.752300 |
67 | 1.802900 |
68 | 2.014400 |
69 | 1.877800 |
70 | 1.565300 |
71 | 1.690100 |
72 | 1.903200 |
73 | 1.817500 |
74 | 1.896300 |
75 | 2.054800 |
76 | 1.610000 |
77 | 1.960400 |
78 | 1.893200 |
79 | 1.962600 |
80 | 1.945200 |
81 | 1.769600 |
82 | 1.619300 |
83 | 1.878200 |
84 | 1.587200 |
85 | 1.863500 |
86 | 1.885700 |
87 | 1.958700 |
88 | 1.666200 |
89 | 1.895700 |
90 | 1.950900 |
91 | 1.762100 |
92 | 1.890000 |
93 | 2.067100 |
94 | 1.837900 |
95 | 1.925300 |
96 | 1.951300 |
97 | 2.056500 |
98 | 1.741900 |
99 | 2.002600 |
100 | 1.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大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓