当前位置: 首页 > news >正文

8.大模型微调学习案例:基于 Hugging Face、8位量化与 LoRA 适配器的方案

文章目录

  • 一、引言
  • 二、数据预处理与构建数据集
    • 2.1 加载 JSON 数据
    • 2.2 构造训练样本
    • 2.3 构建 Hugging Face 数据集与分词
    • 2.4 添加标签字段
    • 2.5 划分训练集与验证集
  • 三、模型加载、量化与适配器配置
    • 3.1 配置设备与显存使用
    • 3.2 配置 8 位量化
    • 3.3 加载预训练模型并映射设备
    • 3.4 为 8 位训练准备模型
    • 3.5 定义并应用 LoRA 适配器
  • 四、自定义 Trainer 及训练参数配置
    • 4.1 自定义 Trainer 类
    • 4.2 配置训练参数
    • 4.3 数据整理器(Data Collator)
  • 五、模型训练与保存
    • 5.1 构建 Trainer 并启动训练
    • 5.2 模型保存
  • 六、分析及展望
  • 全部代码(一键复制):
  • tip:高效下载大模型:利用 hf-mirror 镜像轻松绕过 Hugging Face

一、引言

在大模型微调的实践中,为了降低开发门槛、便于教学和理解,很多参数配置仅用于确保代码能跑通,真正的生产环境调优需要根据具体场景进行调整。本文基于 Hugging Face Transformers、Datasets、PEFT、BitsAndBytes 等工具,详细介绍整个流程并对关键代码部分做了充分注释,方便读者参考学习。

加上之前更新的内容,相信能走到这的读者(这门槛确实高),安装环境那肯定没问题了(其实懒了),就不在更新了;

因为用了知识图谱的数据,所以才有4.1,当然这部分可以不看。


二、数据预处理与构建数据集

下面代码展示如何从本地 JSON 文件中加载数据,并构造训练样本。数据预处理过程包括将知识点与相关主题拼接为一段文本,并利用 Hugging Face Datasets 进行管理,同时完成分词和标签添加。

2.1 加载 JSON 数据

import json
from pathlib import Path# 读取 JSON 数据,数据格式为:{"知识点": ["主题1", "主题2", ...], ...}
json_path = Path("./data/new_knowledge_base.json")
with open(json_path, "r", encoding="utf-8") as f:data = json.load(f)

2.2 构造训练样本

# 遍历数据字典,将每个知识点与其相关主题拼接为一段文本
training_samples = []
for key, values in data.items():# 拼接 prompt:显示知识点信息prompt = f"知识点: {key}"# 拼接 answer:将所有相关主题使用分号分隔answer = "; ".join(values)training_samples.append({"prompt": prompt, "answer": answer})# 输出前 3 个训练样本以供检查
print("前3个训练样本:")
for sample in training_samples[:3]:print("Prompt:", sample["prompt"])print("Answer:", sample["answer"])print("=" * 40)

2.3 构建 Hugging Face 数据集与分词

from datasets import Dataset
from transformers import AutoTokenizer# 利用列表构造 Hugging Face 数据集
dataset = Dataset.from_list(training_samples)
print("\n数据集信息:")
print(dataset)# 加载预训练的中文分词器(这里使用 bert-base-chinese)
tokenizer = AutoTokenizer.from_pretrained("./bert-base-chinese")def tokenize_function(batch):"""对每个批次,将 prompt 和 answer 拼接成一段文本,然后进行分词处理(截断和 padding)"""# 拼接文本,中间以换行符分隔texts = [p + "\n" + a for p, a in zip(batch["prompt"], batch["answer"])]tokenized_output = tokenizer(texts,truncation=True,       # 超长文本截断padding="max_length",  # 固定长度 paddingmax_length=64          # 最大长度设置为 64(根据需要调整))return tokenized_output# 对整个数据集进行分词映射
tokenized_dataset = dataset.map(tokenize_function, batched=True)
print("\n分词后的样本示例:")
print(tokenized_dataset[0])

2.4 添加标签字段

def add_labels(example):# 将 input_ids 的副本作为 labels,确保训练时能正确计算 lossexample["labels"] = example["input_ids"].copy()return example# 对分词后的数据集添加 labels 字段
tokenized_dataset = tokenized_dataset.map(add_labels)
print("\n添加 labels 后的样本示例:")
print(tokenized_dataset[0])

2.5 划分训练集与验证集

# 按 80/20 划分训练集和验证集
split_dataset = tokenized_dataset.train_test_split(test_size=0.2)
train_dataset = split_dataset["train"]
eval_dataset = split_dataset["test"]
print("训练集样本数:", len(train_dataset))
print("验证集样本数:", len(eval_dataset))

三、模型加载、量化与适配器配置

本节展示如何加载本地预训练模型(deepseek-llm-7b-base),结合 BitsAndBytes 工具实现 8 位量化,并通过 PEFT-LoRA 适配器进行参数高效微调。

3.1 配置设备与显存使用

import os
import torchmodel_path = "./deepseek-llm-7b-base"
local_rank = int(os.getenv('LOCAL_RANK', -1))
if local_rank != -1:# 初始化分布式训练环境torch.distributed.init_process_group(backend='nccl')torch.cuda.set_device(local_rank)device = torch.device("cuda", local_rank)
else:device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 限制每个 GPU 的显存使用比例,避免超出显存限制
torch.cuda.set_per_process_memory_fraction(0.98, device=device.index)

3.2 配置 8 位量化

from transformers import BitsAndBytesConfig# 定义 BitsAndBytes 的量化配置:
# - load_in_8bit: 启用 8 位加载
# - bnb_8bit_compute_dtype: 计算时使用 FP16 精度,平衡效率和精度
bnb_config = BitsAndBytesConfig(load_in_8bit=True,bnb_8bit_compute_dtype=torch.float16
)

3.3 加载预训练模型并映射设备

from transformers import AutoModelForCausalLM# 加载模型时传入量化配置,使用 device_map="auto" 自动将模型分配到可用设备
model = AutoModelForCausalLM.from_pretrained(model_path,quantization_config=bnb_config,device_map="auto"
)

3.4 为 8 位训练准备模型

# 使用 PEFT 工具提供的辅助函数,准备模型用于 k-bit(此处为 8 位)训练
from peft import prepare_model_for_kbit_training
model = prepare_model_for_kbit_training(model)

3.5 定义并应用 LoRA 适配器

PEFT(Parameter-Efficient Fine-Tuning)是一种高效微调方法,而 LoRA(Low-Rank Adaptation)则是其中常用的方案。通过只调整部分关键模块的低秩矩阵参数,能大幅减少微调的参数量。

from peft import LoraConfig, get_peft_model# 定义 LoRA 配置:
# - r: 低秩矩阵的秩
# - lora_alpha: 缩放因子
# - target_modules: 指定应用 LoRA 的模块名称(如 q_proj 和 v_proj)
# - lora_dropout: Dropout 概率,防止过拟合
# - bias: 此处不使用 bias
# - task_type: 指定任务类型为因果语言模型(CAUSAL_LM)
lora_config = LoraConfig(r=8,lora_alpha=32,target_modules=["q_proj", "v_proj"],lora_dropout=0.05,bias="none",task_type="CAUSAL_LM"
)# 将 LoRA 适配器应用到模型中,返回新的模型
model = get_peft_model(model, lora_config)# 打印模型中可训练参数的信息,确认 LoRA 已正确添加
print(model.print_trainable_parameters())

四、自定义 Trainer 及训练参数配置

为了满足特定需求,我们重写了 Trainer 类中的 compute_lossprediction_step 方法,确保对不同格式输出都能正确提取损失(loss),同时为示例设置了“能跑就行”的参数。

4.1 自定义 Trainer 类

from transformers import Trainerclass MyTrainer(Trainer):def compute_loss(self, model, inputs, **kwargs):"""重写 compute_loss 方法:1. 调用模型 forward 传入 inputs 得到输出2. 根据输出格式(字典、元组或其他)提取 loss 张量3. 如果 loss 不可反向传播,则进行处理"""outputs = model(**inputs)if hasattr(outputs, "loss") and outputs.loss is not None:loss = outputs.losselif isinstance(outputs, dict):loss = outputs.get("loss", None)elif isinstance(outputs, (list, tuple)):loss = outputs[0]else:loss = outputsif loss is None:raise ValueError("模型未返回 loss,请检查输入标签是否正确。")if not loss.requires_grad:# 确保 loss 是可反向传播的loss = loss.clone().detach().requires_grad_(True)return lossdef prediction_step(self, model, inputs, prediction_loss_only, ignore_keys=None):"""重写 prediction_step 方法用于评估:1. 在 no_grad 模式下调用模型,避免计算梯度2. 根据输出格式提取 loss 和 logits3. 返回 (loss, logits, labels)"""with torch.no_grad():outputs = model(**inputs)if hasattr(outputs, "loss") and outputs.loss is not None:loss = outputs.loss# 如果模型有 logits 属性则提取,否则设置为 Nonelogits = outputs.logits if hasattr(outputs, "logits") else Noneelif isinstance(outputs, (list, tuple)):loss = outputs[0]logits = outputs[1:] if not prediction_loss_only else Noneelse:loss = outputslogits = Nonelabels = inputs.get("labels")return (loss, logits, labels)

4.2 配置训练参数

在本示例中,我们的目标是确保代码能运行,因此设置了较低的训练轮次和小批量大小。实际应用中可根据硬件资源和任务需求进行调整。

from transformers import TrainingArgumentstraining_args = TrainingArguments(output_dir="./results",                  # 模型保存输出目录num_train_epochs=1,                      # 训练轮次(示例中设置为 1 轮)per_device_train_batch_size=1,           # 每个设备的训练批量大小per_device_eval_batch_size=1,            # 每个设备的验证批量大小gradient_accumulation_steps=32,          # 梯度累积步数,用于模拟更大批量eval_strategy="epoch",                   # 每个 epoch 后进行评估save_strategy="epoch",                   # 每个 epoch 后保存模型检查点fp16=True,                               # 开启 FP16 加速训练logging_steps=50,                        # 每 50 步记录日志report_to="tensorboard",                 # 日志记录工具dataloader_num_workers=2,                # 数据加载线程数ddp_find_unused_parameters=False,        # 分布式训练优化参数local_rank=local_rank                    # 支持分布式训练
)

4.3 数据整理器(Data Collator)

使用 DataCollatorWithPadding 自动对不同长度的样本进行 padding,确保输入格式统一。

from transformers import DataCollatorWithPaddingdata_collator = DataCollatorWithPadding(tokenizer=tokenizer)

五、模型训练与保存

在构建好自定义 Trainer 之后,启动训练过程,并在训练结束后保存模型和分词器配置,确保后续部署或推理时可直接加载。

5.1 构建 Trainer 并启动训练

# 构建自定义 Trainer 对象,传入模型、训练参数、数据集和数据整理器
trainer = MyTrainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=eval_dataset,data_collator=data_collator,  # 使用 data_collator 替代 tokenizer 进行自动 padding
)# 启动训练过程
trainer.train()

5.2 模型保存

训练完成后,通过 Trainer 内置方法保存最终模型和分词器配置。保存目录(如 ./results/final_model)中将包含模型权重分片和分词器相关文件(如 tokenizer_config.jsonspecial_tokens_map.jsonvocab.txt 等),便于后续使用。

# 保存最终模型(模型权重、配置等)
trainer.save_model("./results/final_model")
# 同时保存分词器配置,确保推理时输入预处理一致
tokenizer.save_pretrained("./results/final_model")

六、分析及展望

为了能跑,做了很多的妥协,以下是结果:

TrainOutput(global_step=6, training_loss=351.4185791015625, metrics={‘train_runtime’: 87.7887, ‘train_samples_per_second’: 2.449, ‘train_steps_per_second’: 0.068, ‘total_flos’: 478853587795968.0, ‘train_loss’: 351.4185791015625, ‘epoch’: 0.8930232558139535})

可以看到,结果很离谱;以下是分析

从结果来看,存在几个需要关注的关键指标和潜在问题,这些问题需要在企业级大模型训练环境中加以优化和解决,以确保模型能够高效、稳健地收敛。

训练与验证损失的差异

  • 验证损失较低(≈10.67): 在当前 Epoch(第0个Epoch)结束时,验证阶段的损失已经达到了较低水平。
  • 训练损失较高(≈351.42): 而训练过程中累计的损失显著偏高,这种差异可能源自多个因素:
    • 模型训练模式与评估模式的差异: 在训练阶段,诸如 dropout 等正则化策略仍在生效,导致训练损失偏高;而在评估模式下,这些机制被关闭,从而使得验证损失相对较低。
    • 梯度累积策略: 当前配置中采用了较高的梯度累积步数(32),这可能会对损失的统计方式产生影响,造成训练损失在报告时与实际优化目标存在一定差异。
    • 数据预处理或标签设置: 需要确认训练和验证数据的预处理流程是否完全一致,防止出现数据分布或标签计算不一致的问题。

性能指标与计算资源利用

  • 低样本与步长吞吐量: 从日志中可以看到,每秒仅有约2.449个样本和0.068个训练步,表明当前训练过程极为缓慢。这可能反映出:
    • 模型规模较大或架构复杂,导致计算密集度高;
    • 数据加载与处理流程存在瓶颈;
    • 硬件资源(例如 GPU 显存利用率)可能没有得到充分优化。
  • 总 FLOPs 指标: 指标显示了巨大的计算量(≈4.79e+14 FLOPs),这在企业级场景下要求优化调度和并行计算策略,以实现更高的计算效率。

量化警告的影响

  • MatMul8bitLt 警告: 日志中提到的警告表明,在量化过程中输入数据会从 torch.float32 转换为 float16。这是使用 bitsandbytes 库进行低精度训练时的常见提示,需确认量化策略是否与整体训练计划和精度要求一致。
    • 建议在确保数值稳定性的前提下,进一步测试低精度计算对模型收敛和泛化能力的影响,以便在性能与精度之间取得最佳平衡。

总结与前瞻性建议

  • 调优数据管道与硬件配置: 考虑优化数据加载、多线程数据预处理以及利用分布式训练方案,以提升整体吞吐量和训练效率。
  • 校准训练与评估指标: 对比训练与验证阶段的损失计算方式,确保在梯度累积和量化策略下两者能够更好地匹配。
  • 量化策略评估: 进一步评估低精度训练对模型性能的影响,并根据企业需求制定适当的精度与效率折衷方案。

采用前瞻性、创新的策略,建议在继续训练的同时,通过性能剖析工具对各环节进行精细调优,从而打造一套既高效又稳健的企业级大模型训练系统。

更多的阅读,可以进主页:小胡说技书

可以体验到,从知识图谱的构建(数据源)、数据管理、炼丹(大模型)、Java开发(SSM)、前端(Vue3)、安全、部署全流程。

至于new_knowledge_base.json是拿ai生的,就几个,不用单独要;

毕竟这篇只是学习或者提供思路的博客,没有实际开发的价值。

全部代码(一键复制):

# -*- coding: utf-8 -*-
"""
本代码示例展示如何:
1. 加载 /data/new_knowledge_base.json 数据,并构造训练样本
2. 使用 Hugging Face Datasets 构建数据集,并进行分词和添加 labels
3. 划分训练集与验证集
4. 加载本地预训练模型 deepseek-llm-7b-base
5. 使用 PEFT 添加 LoRA 适配器
6. 自定义 Trainer 子类,重写 compute_loss 和 evaluation_step 方法,确保返回的 loss 可反向传播
7. 配置 Trainer 进行微调训练
"""import json
from pathlib import Path
import os
from datasets import Dataset
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, DataCollatorWithPadding, BitsAndBytesConfig
import torch
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training# ----------------------------
# Step 0. 设置环境变量(可选)
# ----------------------------
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
os.environ["TOKENIZERS_PARALLELISM"] = "false"  # 禁用 tokenizers 的并行化# ----------------------------
# Step 1. 加载 JSON 数据
# ----------------------------
json_path = Path("./data/new_knowledge_base.json")
with open(json_path, "r", encoding="utf-8") as f:data = json.load(f)
# data 为字典,键为知识点,值为相关主题列表# ----------------------------
# Step 2. 数据预处理:构建训练样本
# ----------------------------
training_samples = []
for key, values in data.items():prompt = f"知识点: {key}"answer = "; ".join(values)training_samples.append({"prompt": prompt, "answer": answer})print("前3个训练样本:")
for sample in training_samples[:3]:print("Prompt:", sample["prompt"])print("Answer:", sample["answer"])print("=" * 40)# ----------------------------
# Step 3. 构建 Hugging Face 数据集
# ----------------------------
dataset = Dataset.from_list(training_samples)
print("\n数据集信息:")
print(dataset)# ----------------------------
# Step 4. 数据 Tokenization
# ----------------------------
tokenizer = AutoTokenizer.from_pretrained("./bert-base-chinese")def tokenize_function(batch):"""对每个批次,将 prompt 和 answer 拼接成一段文本,再进行分词处理"""texts = [p + "\n" + a for p, a in zip(batch["prompt"], batch["answer"])]tokenized_output = tokenizer(texts,truncation=True,padding="max_length",max_length=64  # 增加最大长度以更好地捕捉上下文)return tokenized_outputtokenized_dataset = dataset.map(tokenize_function, batched=True)
print("\n分词后的样本示例:")
print(tokenized_dataset[0])# ----------------------------
# Step 5. 添加 labels 字段
# ----------------------------
def add_labels(example):example["labels"] = example["input_ids"].copy()return exampletokenized_dataset = tokenized_dataset.map(add_labels)
print("\n添加 labels 后的样本示例:")
print(tokenized_dataset[0])# ----------------------------
# Step 6. 划分训练集与验证集
# ----------------------------
split_dataset = tokenized_dataset.train_test_split(test_size=0.2)
train_dataset = split_dataset["train"]
eval_dataset = split_dataset["test"]
print("训练集样本数:", len(train_dataset))
print("验证集样本数:", len(eval_dataset))# ----------------------------
# Step 7. 加载预训练模型与分词器
# ----------------------------
model_path = "./deepseek-llm-7b-base"local_rank = int(os.getenv('LOCAL_RANK', -1))
if local_rank != -1:torch.distributed.init_process_group(backend='nccl')torch.cuda.set_device(local_rank)device = torch.device("cuda", local_rank)
else:device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 限制每张GPU卡的显存使用
torch.cuda.set_per_process_memory_fraction(0.98, device=device.index)# 配置 8 位量化参数
bnb_config = BitsAndBytesConfig(load_in_8bit=True,                # 开启 8 位加载bnb_8bit_compute_dtype=torch.float16  # 计算时仍使用 FP16 精度
)# 加载模型时传入量化配置,并自动映射设备
model = AutoModelForCausalLM.from_pretrained(model_path,quantization_config=bnb_config,device_map="auto"
)# 准备模型用于 8 位训练
model = prepare_model_for_kbit_training(model)# 定义 LoRA 配置
lora_config = LoraConfig(r=8,                    # Rank of the low-rank matriceslora_alpha=32,          # Scaling factor for the learned weightstarget_modules=["q_proj", "v_proj"],  # Target modules to apply LoRAlora_dropout=0.05,      # Dropout probability for the LoRA layersbias="none",            # Bias type for the LoRA layerstask_type="CAUSAL_LM"   # Task type for the model
)# 将 LoRA 适配器应用到模型
model = get_peft_model(model, lora_config)# 打印模型结构以确认适配器已添加
print(model.print_trainable_parameters())# ----------------------------
# Step 8. 自定义 Trainer 子类,重写 compute_loss 和 evaluation_step 方法
# ----------------------------
class MyTrainer(Trainer):def compute_loss(self, model, inputs, **kwargs):outputs = model(**inputs)# 检查输出对象是否包含 loss 属性(例如 CausalLMOutputWithPast)if hasattr(outputs, "loss") and outputs.loss is not None:loss = outputs.losselif isinstance(outputs, dict):loss = outputs.get("loss", None)elif isinstance(outputs, (list, tuple)):loss = outputs[0]else:loss = outputsif loss is None:raise ValueError("The model did not return a loss. Ensure that your inputs contain the correct labels.")if not loss.requires_grad:loss = loss.clone().detach().requires_grad_(True)return lossdef prediction_step(self, model, inputs, prediction_loss_only, ignore_keys=None):with torch.no_grad():outputs = model(**inputs)# 同样提取 loss 张量,避免直接返回输出对象if hasattr(outputs, "loss") and outputs.loss is not None:loss = outputs.losslogits = outputs.logits if hasattr(outputs, "logits") else Noneelif isinstance(outputs, (list, tuple)):loss = outputs[0]logits = outputs[1:] if not prediction_loss_only else Noneelse:loss = outputslogits = Nonelabels = inputs.get("labels")return (loss, logits, labels)# ----------------------------
# Step 9. 设置训练参数
# ----------------------------
training_args = TrainingArguments(output_dir="./results",num_train_epochs=1,  # 减少训练轮次以减少计算量per_device_train_batch_size=1,  # 继续减少批量大小per_device_eval_batch_size=1,gradient_accumulation_steps=32,  # 增加梯度累积步数eval_strategy="epoch",  # 使用 eval_strategy 替代 evaluation_strategysave_strategy="epoch",fp16=True, logging_steps=50,report_to="tensorboard",dataloader_num_workers=2,  # 减少数据加载线程数ddp_find_unused_parameters=False,  # 关闭DDP中查找未使用的参数local_rank=local_rank  # 支持分布式训练
)# ----------------------------
# Step 10. 创建数据整理器(Data Collator)
# ----------------------------
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)# ----------------------------
# Step 11. 构建 MyTrainer 并开始训练
# ----------------------------
trainer = MyTrainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=eval_dataset,data_collator=data_collator,  # 使用 data_collator 替代 tokenizer
)# 开始训练
trainer.train()# 保存最终模型(包括权重和配置)
trainer.save_model("./results/final_model")
# 同时保存分词器,确保后续恢复环境一致
tokenizer.save_pretrained("./results/final_model")

tip:高效下载大模型:利用 hf-mirror 镜像轻松绕过 Hugging Face

OSError: Can't load tokenizer for './bert-base-chinese'. 
If you were trying to load it from 'https://huggingface.co/models',make sure you don't have a local directory with the same name. Otherwise, make sure './bert-base-chinese' is the correct path to a directory containing all relevant files for a BertTokenizerFast tokenizer.

国内无法连Hugging Face;报错一种解决方法(win直接下载即可,下载挺快):

通过 hf-mirror 下载大模型

  1. 访问镜像站点
    打开浏览器,访问 hf-mirror.com,在搜索框中输入想要下载的大模型名称(例如:deepseek-llm-7b-base)。镜像站点会显示模型的各项信息及下载链接。

  2. 获取下载链接
    找到目标模型后,复制其对应的下载链接。通常链接指向的是模型权重的分片文件,如 pytorch_model-00001-of-00002.bin 等。

在 Linux 下使用 wget 下载

例如:deepseek-ai/deepseek-llm-7b-base快速下载命令(截图给ai生成即可)

  • -c 参数:表示断点续传,适合下载大文件。
  • -O 参数:指定输出文件名称。
# 创建存放模型的目录
mkdir -p deepseek-llm-7b-base && cd deepseek-llm-7b-base# 设置基础 URL
BASE_URL="https://hf-mirror.com/deepseek-ai/deepseek-llm-7b-base/resolve/main"# 下载模型权重文件(分片)
wget -c "${BASE_URL}/pytorch_model-00001-of-00002.bin" -O pytorch_model-00001-of-00002.bin
wget -c "${BASE_URL}/pytorch_model-00002-of-00002.bin" -O pytorch_model-00002-of-00002.bin# 下载模型索引文件
wget -c "${BASE_URL}/pytorch_model.bin.index.json" -O pytorch_model.bin.index.json# 下载配置文件
wget -c "${BASE_URL}/config.json" -O config.json
wget -c "${BASE_URL}/generation_config.json" -O generation_config.json# 下载分词器文件
wget -c "${BASE_URL}/tokenizer.json" -O tokenizer.json
wget -c "${BASE_URL}/tokenizer_config.json" -O tokenizer_config.jsonecho "所有文件下载完成!"

更多ai相关,请移步主页。

封面图:
在这里插入图片描述

相关文章:

8.大模型微调学习案例:基于 Hugging Face、8位量化与 LoRA 适配器的方案

文章目录 一、引言二、数据预处理与构建数据集2.1 加载 JSON 数据2.2 构造训练样本2.3 构建 Hugging Face 数据集与分词2.4 添加标签字段2.5 划分训练集与验证集 三、模型加载、量化与适配器配置3.1 配置设备与显存使用3.2 配置 8 位量化3.3 加载预训练模型并映射设备3.4 为 8 …...

用分页干掉显存浪费!聊聊VLLM的PagedAttention

不知道你在部署模型的时候,有没有经历过这样的抓狂时刻——跑大模型时显卡显存明明没有占满,程序却报错OOM(内存不足)?表面看是显存不足,背后其实是KVCache碎片化和重复存储这个"隐形刺客"在作祟…...

Python——地图可视化

分级统计地图:一般使用同一种颜色表示一个区域的属性,常用与选举和人口普查数据的可视化。对于颜色的选择可以使用单色渐变系、双向渐变系、完整色谱变化。 使用这类颜色渐变进行填充存在的问题: 使用这类方法适用于数据密集分布的区域&#…...

3.8【Q】cv

这个draw_line函数的逻辑和功能是什么?代码思路是什么?怎么写的? 这个t是什么?t.v[0]和t.v[1],[2]又是什么? void rst::rasterizer::draw(rst::pos_buf_id pos_buffer, rst::ind_buf_id ind_buffer, rst::Primitive ty…...

LeetCode 热题 100_字符串解码(71_394_中等_C++)(栈)

LeetCode 热题 100_字符串解码(71_394) 题目描述:输入输出样例:题解:解题思路:思路一(栈): 代码实现代码实现(栈):以思路一为例进行调…...

基于大模型预测的新型隐球菌脑膜炎综合诊疗研究报告

目录 一、引言 1.1 研究背景与目的 1.2 研究现状综述 二、大模型预测原理及数据基础 2.1 大模型技术简介 2.2 数据收集与预处理 2.3 模型训练与验证 三、术前风险预测与准备 3.1 病情评估指标确定 3.2 手术方案制定 3.3 麻醉方案规划 四、术中监测与应对 4.1 实时…...

SQL Server核心知识总结

SQL Server核心知识总结 🎯 本文总结了SQL Server核心知识点,每个主题都提供实际可运行的示例代码。 一、SQL Server基础精要 1. 数据库核心操作 -- 1. 创建数据库(核心配置) CREATE DATABASE 学生管理系统 ON PRIMARY (NAME 学生管理系统…...

浏览器WEB播放RTSP

注意:浏览器不能直接播放RTSP,必须转换后才能播放。这一点所有的播放都是如此。 参考 https://github.com/kyriesent/node-rtsp-stream GitHub - phoboslab/jsmpeg: MPEG1 Video Decoder in JavaScript 相关文件方便下载 https://download.csdn.net…...

登录固定账号和密码:

接口文档 【apifox】面试宝典 个人中心-保存用户数据信息 - 教学练测项目-面试宝典-鸿蒙 登录固定账号和密码: 账号:hmheima 密码:Hmheima%123 UI设计稿 【腾讯 CoDesign】面试宝典 CoDesign - 腾讯自研设计协作平台 访问密码&#xff1…...

深度学习/强化学习调参技巧

深度调优策略 1. 学习率调整 技巧:学习率是最重要的超参数之一。过大可能导致训练不稳定,过小则收敛速度慢。可以使用学习率衰减(Learning Rate Decay)或自适应学习率方法(如Adam、RMSprop)来动态调整学习…...

Java常用正则表达式(身份证号、邮箱、手机号)格式校验

目录 身份证号的正则表达式 代码解释 正则表达式 方法 isValidIDCard 注意事项 校验邮箱的正则表达式 代码解释 正则表达式 方法 isValidEmail 注意事项 手机号的正则表达式 中国大陆手机号校验(支持空字符串) 代码解释 通用手机号校验&am…...

1.12.信息系统的分类【ES】

专家系统(ES)技术架构深度解析 一、ES核心定义 🧠 智能决策中枢 由三大核心能力构建的领域专家模拟系统: 存储专家级领域知识(10^4规则量级)支持不确定性推理(置信度>85%)动态…...

c语言程序设计--(结构体、共用体)冲刺考研复试中的面试问答,来看看我是怎么回答的吧!

结构体 1、谈谈你对结构体的理解。 答,首先在结构的基础知识上,结构是一些值的集合,这些值称为成员变量结构的每个成员可以是不同类型的变量。结构体其实就是把(一些单一类型的数据)不同类型的数据组合在一起的做法便…...

闭包:JavaScript 中的隐形大杀器

你可能已经在很多地方听说过闭包这个词,尤其是涉及到 JavaScript 的作用域和异步操作时。闭包是 JavaScript 中非常核心的概念,然而它又非常容易让开发者感到困惑。今天我们就来深入剖析闭包,帮助你真正理解它的工作原理,以及如何…...

分布式锁—7.Curator的分布式锁一

大纲 1.Curator的可重入锁的源码 2.Curator的非可重入锁的源码 3.Curator的可重入读写锁的源码 4.Curator的MultiLock源码 5.Curator的Semaphore源码 1.Curator的可重入锁的源码 (1)InterProcessMutex获取分布式锁 (2)InterProcessMutex的初始化 (3)InterProcessMutex.…...

linux---天气爬虫

代码概述 这段代码实现了一个天气查询系统,支持实时天气、未来天气和历史天气查询。用户可以通过终端菜单选择查询类型,并输入城市名称来获取相应的天气信息。程序通过 TCP 连接发送 HTTP 请求,并解析返回的 JSON 数据来展示天气信息。 #in…...

C++蓝桥杯基础篇(九)

片头 嗨!小伙伴们,大家好~ 今天我们将学习蓝桥杯基础篇(十),学习函数相关知识,准备好了吗?咱们开始咯! 一、函数基础 一个典型的函数定义包括以下部分:返回类型、函数名…...

Java Spring MVC (2)

常见的Request Controller 和 Response Controller 的区别 用餐厅点餐来理解 想象你去一家餐厅吃饭: Request Controller(接单员):负责处理你的点餐请求,记录你的口味、桌号等信息。Response Controller&#xff08…...

Elasticsearch:使用 BigQuery 提取数据

作者:来自 Elastic Jeffrey Rengifo 了解如何使用 Python 在 Elasticsearch 中索引和搜索 Google BigQuery 数据。 BigQuery 是 Google 的一个平台,允许你将来自不同来源和服务的数据集中到一个存储库中。它还支持数据分析,并可使用生成式 AI…...

接口-菜品分页查询

业务内容 页面上菜品根据菜品名称、菜品分类、售卖状态三个字段进行分页查询。 在请求参数中携带了菜品名称、菜品分类、售卖状态三个字段参数。 返回PageResult类型的实体。 注意:在返回数据中在records下有个categoryName,这个字段的内容在category…...

springboot3 RestClient、HTTP 客户端区别

1 RestClient使用 RestClient 是 Spring 6.1 M2 中引入的同步 HTTP 客户端,它取代了 RestTemplate。同步 HTTP 客户端以阻塞方式发送和接收 HTTP 请求和响应,这意味着它会等待每个请求完成后才继续下一个请求。本文将带你了解 RestClient 的功能以及它与…...

自我训练模型:通往未来的必经之路?

摘要 在探讨是否唯有通过自我训练模型才能掌握未来的问题时,文章强调了底层技术的重要性。当前,许多人倾向于关注应用层的便捷性,却忽视了支撑这一切的根本——底层技术。将模型简单视为产品是一种短视行为,长远来看,理…...

RuoYi框架添加自己的模块(学生管理系统CRUD)

RuoYi框架添加自己的模块(学生管理系统) 框架顺利运行 首先肯定要顺利运行框架了,这个我不多说了 设计数据库表 在ry数据库中添加表tb_student 表字段如图所示 如图所示 注意id字段是自增的 注释部分是后面成功后前端要展示的部分 导入…...

linux查看python版本

1.查看Linux是否安装python yum list all | grep python 2.Linux安装python yum install python 3.Linux查看python版本 python -V...

算法题(89):单项链表

审题: 本题需要我们实现一个可以执行三个指令的数据结构来解决这里的问题 思路: 方法一:利用数组模拟链表 由于这里涉及插入删除操作,所以我们不能使用数组结构存储数据,这样子会超时,所以我们就利用数组来…...

开源之夏经验分享|Koupleless 社区黄兴抗:在开源中培养工程思维

开源之夏经验分享|Koupleless 社区黄兴抗:在开源中培养工程思维 文|黄兴抗 电子信息工程专业 Koupleless 社区贡献者 就读于南昌师范学院,电子信息工程专业的大三学生。 本文 2634 字,预计阅读 7​ 分钟​ 今天 SOFAStack 邀…...

体验开源openeuler openharmony stratovirt模拟器

文档 openeuler社区面向数字基础设施的开源操作系统 openharmony社区 OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目, 目标是面向全场景、全连接、全智能时代、基于开源的方式,搭建一个智能终端设备操作系统…...

【AI实践】基于TensorFlow/Keras的CNN(卷积神经网络)简单实现:手写数字识别的工程实践

深度神经网络系列文章 【AI深度学习网络】卷积神经网络(CNN)入门指南:从生物启发的原理到现代架构演进【AI实践】基于TensorFlow/Keras的CNN(卷积神经网络)简单实现:手写数字识别的工程实践 引言 在深度…...

深入探讨AI-Ops架构 第一讲 - 运维的进化历程以及未来发展趋势

首先,让我们一起回顾运维的进化之路,然后再深入探讨AI-Ops架构的细节。 运维的进化历程 1. AI 大范围普及前的运维状态 (传统运维) 在AI技术尚未广泛渗透到运维领域之前,我们称之为传统运维,其主要特点是: 人工驱动…...

2025年全球生成式AI消费应用发展趋势报告

原文链接:The Top 100 Gen AI Consumer Apps - 4th Edition | Andreessen Horowitz 核心要点:本报告由a16z发布,深度解析了2025年全球生成式AI消费应用的发展格局,揭示了技术迭代与商业化加速的双重趋势。 报告显示,A…...

VBA 列方向合并单元格,左侧范围大于右侧范围

实现功能如下: excel指定行列范围内的所有单元格 规则1:每一列的连续相同的值合并单元格 规则2:每一列的第一个非空单元格与其下方的所有空白单元格合并单元 规则3:优先左侧列合并单元格,合并后,右侧的单元…...

设计AI芯片架构的入门 研究生入行数字芯片设计、验证的项目 opentitan

前言 这几年芯片设计行业在国内像坐过山车。时而高亢,时而低潮。最近又因为AI的热潮开始high起来。到底芯片行业的规律是如何? 我谈谈自己观点:芯片设计是“劳动密集型”行业。 “EDA和工具高度标准化和代工厂的工艺标准化之后,芯…...

【弹性计算】异构计算云服务和 AI 加速器(二):适用场景

异构计算云服务和 AI 加速器(二):适用场景 1.图形处理2.视频处理3.计算4.人工智能 异构计算 目前已经被广泛地应用于生产和生活当中,主要应用场景如下图所示。 1.图形处理 GPU 云服务器在传统的图形处理领域具有强大的优势&…...

JVM常用概念之移动GC和局部性

问题 非移动GC一定比移动GC好吗? 基础知识 移动GC和非移动GC 移动GC 在进行垃圾回收时,为了减少碎片而移动对象来顺利完成垃圾回收的GC。 Serial GC 在单线程环境下,它在标记-清除(Mark-Sweep)算法的基础上进行…...

微服务保护:Sentinel

home | Sentinelhttps://sentinelguard.io/zh-cn/ 微服务保护的方案有很多,比如: 请求限流 线程隔离 服务熔断 服务故障最重要原因,就是并发太高!解决了这个问题,就能避免大部分故障。当然,接口的并发…...

使用Wireshark截取并解密摄像头画面

在物联网(IoT)设备普及的今天,安全摄像头等智能设备在追求便捷的同时,往往忽视了数据传输过程中的加密保护。很多摄像头默认通过 HTTP 协议传输数据,而非加密的 HTTPS,从而给潜在攻击者留下了可乘之机。本文…...

IDEA 基础配置: maven配置 | 服务窗口配置

文章目录 IDEA版本与MAVEN版本对应关系maven配置镜像源插件idea打开服务工具窗口IDEA中的一些常见问题及其解决方案IDEA版本与MAVEN版本对应关系 查找发布时间在IDEA版本之前的dea2021可以使用maven3.8以及以前的版本 比如我是idea2021.2.2 ,需要将 maven 退到 apache-maven-3.…...

20250-3-8 树的存储结构

一、树的逻辑结构回顾 树:一个分支结点可以有多课子树 如果按照二叉树的存储来实现树的存储,则只依靠数组下标,无法反映结点之间的逻辑关系。 二、双亲表示法(顺序存储) 1.因此:我们可以用链式存储的方法&…...

Visual-RFT视觉强化微调:用「试错学习」教会AI看图说话

📜 文献卡 英文题目: Visual-RFT: Visual Reinforcement Fine-Tuning;作者: Ziyu Liu; Zeyi Sun; Yuhang Zang; Xiaoyi Dong; Yuhang Cao; Haodong Duan; Dahua Lin; Jiaqi WangDOI: 10.48550/arXiv.2503.01785摘要翻译: 像OpenAI o1这样的大型推理模型中的强化微调…...

PDF处理控件Aspose.PDF,如何实现企业级PDF处理

PDF处理为何成为开发者的“隐形雷区”? “手动调整200页PDF目录耗时3天,扫描件文字识别错误导致数据混乱,跨平台渲染格式崩坏引发客户投诉……” 作为开发者,你是否也在为PDF处理的复杂细节消耗大量精力?Aspose.PDF凭…...

DeepSeek-R1本地化部署(Mac)

一、下载 Ollama 本地化部署需要用到 Ollama,它能支持很多大模型。官方网站:https://ollama.com/ 点击 Download 即可,支持macOS,Linux 和 Windows;我下载的是 mac 版本,要求macOS 11 Big Sur or later,Ol…...

Swift Package Manager (SPM) 创建并集成本地库

在macOS 项目中,使用 Swift Package Manager (SPM) 创建并集成本地库的完整步骤。 创建一个macos应用程序,选择 swift、oc、swiftui都可以。 创建好应用之后,开始创建SPM本地库。 打开终端app,进入项目根目录,逐次输…...

分布式锁—6.Redisson的同步器组件

大纲 1.Redisson的分布式锁简单总结 2.Redisson的Semaphore简介 3.Redisson的Semaphore源码剖析 4.Redisson的CountDownLatch简介 5.Redisson的CountDownLatch源码剖析 1.Redisson的分布式锁简单总结 (1)可重入锁RedissonLock (2)公平锁RedissonFairLock (3)联锁MultiL…...

文献分享: ConstBERT固定数目向量编码文档

😂图放这了,大道至简的 idea \text{idea} idea不愧是 ECIR \text{ECIR} ECIR 👉原论文 1. ConstBERT \textbf{1. ConstBERT} 1. ConstBERT的原理 1️⃣模型的改进点:相较于 ColBERT \text{ColBERT} ColBERT为每个 Token \text{Tok…...

如何使用SSH命令安全连接并转发端口到远程服务器

ssh -p 22546 rootconnect.westc.gpuhub.com d6IS/mQKq/iG ssh -CNgv -L 6006:127.0.0.1:6006 rootconnect.westc.gpuhub.com -p 22546 第一条命令:用于登录远程服务器,进行交互式操作。第二条命令:用于建立 SSH 隧道,进行端口转…...

SolidWorks 转 PDF3D 技术详解

在现代工程设计与制造流程中,不同软件间的数据交互与格式转换至关重要。将 SolidWorks 模型转换为 PDF3D 格式,能有效解决模型展示、数据共享以及跨平台协作等问题。本文将深入探讨 SolidWorks 转 PDF3D 的技术原理、操作流程及相关注意事项,…...

9.2 EvictionManager源码解读

本节重点总结 : evictionManager初始化了两个相同的manager对象 evictionManager做本机驱逐pod的判定和厨房evictionAdmitHandler用来kubelet创建Pod前进依据本机的资源压力进行准入检查 evictionManager判断内存驱逐阈值有两种方法 第一种使用内核的memcg的通知机制&#xff…...

考研数一非数竞赛复习之Stolz定理求解数列极限

在非数类大学生数学竞赛中,Stolz定理作为一种强大的工具,经常被用来解决和式数列极限的问题,也被誉为离散版的’洛必达’方法,它提供了一种简洁而有效的方法,使得原本复杂繁琐的极限计算过程变得直观明了。本文&#x…...

整理一下高级设施农业栽培学这门课程的所有知识点

整理一下高级设施农业栽培学这门课程的所有知识点 以下是高级设施农业栽培学这门课程从入门到精通需要学习的知识点: 一、设施农业概述 设施农业的概念与发展历程 了解设施农业的定义、特点及作用,掌握其发展历程、现状与未来趋势。熟悉国内外设施农业…...

2025最新软件测试面试八股文(含答案+文档)

1、请试着比较一下黑盒测试、白盒测试、单元测试、集成测试、系统测试、验收测试的区别与联系。 参考答案: 黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。 白盒测试:已知产品的内部工作过程…...