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

【细看open_r1】精读训练和评估模型以及生成合成数据的脚本(src/open_r1)

src/open_r1 目录下主要包含了一些用于训练和评估模型以及生成合成数据的Python脚本,下面我们对其中几个主要的Python文件进行深度剖析。

configs.py

这个文件定义了两个数据类 GRPOConfigSFTConfig,它们分别继承自 trl.GRPOConfigtrl.SFTConfig,并且添加了一些额外的参数用于回调、基准测试等。

# 导入必要的模块
from dataclasses import dataclass, field
from typing import Optional
import trl# 定义GRPOConfig类,继承自trl.GRPOConfig
@dataclass
class GRPOConfig(trl.GRPOConfig):"""args for callbacks, benchmarks etc"""# 定义用于存储基准测试名称的列表,默认值为空列表benchmarks: list[str] = field(default_factory=lambda: [], metadata={"help": "The benchmarks to run after training."})# 定义用于存储回调函数名称的列表,默认值为空列表callbacks: list[str] = field(default_factory=lambda: [], metadata={"help": "The callbacks to run during training."})# 定义可选的系统提示,用于基准测试,默认值为Nonesystem_prompt: Optional[str] = field(default=None, metadata={"help": "The optional system prompt to use for benchmarking."})# 定义Hub模型的修订版本,默认值为"main"hub_model_revision: Optional[str] = field(default="main", metadata={"help": "The Hub model branch to push the model to."})# 定义是否覆盖Hub修订版本,默认值为Falseoverwrite_hub_revision: bool = field(default=False, metadata={"help": "Whether to overwrite the Hub revision."})# 定义是否推送到Hub修订版本/分支,默认值为Falsepush_to_hub_revision: bool = field(default=False, metadata={"help": "Whether to push to a Hub revision/branch."})# 定义WandB的实体,用于存储运行结果,默认值为Nonewandb_entity: Optional[str] = field(default=None,metadata={"help": ("The entity to store runs under.")},)# 定义WandB的项目,用于存储运行结果,默认值为Nonewandb_project: Optional[str] = field(default=None,metadata={"help": ("The project to store runs under.")},)# 定义SFTConfig类,继承自trl.SFTConfig
@dataclass
class SFTConfig(trl.SFTConfig):"""args for callbacks, benchmarks etc"""# 定义用于存储基准测试名称的列表,默认值为空列表benchmarks: list[str] = field(default_factory=lambda: [], metadata={"help": "The benchmarks to run after training."})# 定义用于存储回调函数名称的列表,默认值为空列表callbacks: list[str] = field(default_factory=lambda: [], metadata={"help": "The callbacks to run during training."})# 定义可选的系统提示,用于基准测试,默认值为Nonesystem_prompt: Optional[str] = field(default=None,metadata={"help": "The optional system prompt to use for benchmarking."},)# 定义Hub模型的修订版本,默认值为"main"hub_model_revision: Optional[str] = field(default="main",metadata={"help": "The Hub model branch to push the model to."},)# 定义是否覆盖Hub修订版本,默认值为Falseoverwrite_hub_revision: bool = field(default=False, metadata={"help": "Whether to overwrite the Hub revision."})# 定义是否推送到Hub修订版本/分支,默认值为Falsepush_to_hub_revision: bool = field(default=False, metadata={"help": "Whether to push to a Hub revision/branch."})# 定义WandB的实体,用于存储运行结果,默认值为Nonewandb_entity: Optional[str] = field(default=None,metadata={"help": ("The entity to store runs under.")},)# 定义WandB的项目,用于存储运行结果,默认值为Nonewandb_project: Optional[str] = field(default=None,metadata={"help": ("The project to store runs under.")},)

sft.py

这个文件是一个监督式微调(Supervised Fine-Tuning,SFT)的脚本,用于对解码器语言模型进行微调。

1 导入必要的模块
import logging
import os
import sys
import datasets
import torch
import transformers
from datasets import load_dataset
from transformers import AutoTokenizer, set_seed
from transformers.trainer_utils import get_last_checkpoint
from open_r1.configs import SFTConfig
from open_r1.utils.callbacks import get_callbacks
from open_r1.utils.logging import init_wandb_training
from trl import (ModelConfig,ScriptArguments,SFTTrainer,TrlParser,get_kbit_device_map,get_peft_config,get_quantization_config,
)
2 配置日志记录
logger = logging.getLogger(__name__)def main(script_args, training_args, model_args):# 设置随机种子以确保可重复性set_seed(training_args.seed)# 配置日志记录logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%Y-%m-%d %H:%M:%S",handlers=[logging.StreamHandler(sys.stdout)],)log_level = training_args.get_process_log_level()logger.setLevel(log_level)datasets.utils.logging.set_verbosity(log_level)transformers.utils.logging.set_verbosity(log_level)transformers.utils.logging.enable_default_handler()transformers.utils.logging.enable_explicit_format()# 记录每个进程的简要信息logger.warning(f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"+ f" distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}")logger.info(f"Model parameters {model_args}")logger.info(f"Script parameters {script_args}")logger.info(f"Training parameters {training_args}")
3 检查最后一个检查点
    # 检查最后一个检查点last_checkpoint = Noneif os.path.isdir(training_args.output_dir):last_checkpoint = get_last_checkpoint(training_args.output_dir)if last_checkpoint is not None and training_args.resume_from_checkpoint is None:logger.info(f"Checkpoint detected, resuming training at {last_checkpoint=}.")# 如果使用WandB进行报告,则初始化WandB训练if "wandb" in training_args.report_to:init_wandb_training(training_args)
4 加载数据集和分词器
    # 加载数据集dataset = load_dataset(script_args.dataset_name, name=script_args.dataset_config)# 加载分词器tokenizer = AutoTokenizer.from_pretrained(model_args.model_name_or_path, trust_remote_code=model_args.trust_remote_code, use_fast=True)tokenizer.pad_token = tokenizer.eos_token
5 初始化模型参数
    # 初始化模型参数logger.info("*** Initializing model kwargs ***")torch_dtype = (model_args.torch_dtype if model_args.torch_dtype in ["auto", None] else getattr(torch, model_args.torch_dtype))quantization_config = get_quantization_config(model_args)model_kwargs = dict(revision=model_args.model_revision,trust_remote_code=model_args.trust_remote_code,attn_implementation=model_args.attn_implementation,torch_dtype=torch_dtype,use_cache=False if training_args.gradient_checkpointing else True,device_map=get_kbit_device_map() if quantization_config is not None else None,quantization_config=quantization_config,)training_args.model_init_kwargs = model_kwargs
6 初始化SFT Trainer
    # 初始化SFT Trainertrainer = SFTTrainer(model=model_args.model_name_or_path,args=training_args,train_dataset=dataset[script_args.dataset_train_split],eval_dataset=dataset[script_args.dataset_test_split] if training_args.eval_strategy != "no" else None,processing_class=tokenizer,peft_config=get_peft_config(model_args),callbacks=get_callbacks(training_args, model_args),)
7 训练循环
    # 训练循环logger.info("*** Train ***")checkpoint = Noneif training_args.resume_from_checkpoint is not None:checkpoint = training_args.resume_from_checkpointelif last_checkpoint is not None:checkpoint = last_checkpointtrain_result = trainer.train(resume_from_checkpoint=checkpoint)metrics = train_result.metricsmetrics["train_samples"] = len(dataset[script_args.dataset_train_split])trainer.log_metrics("train", metrics)trainer.save_metrics("train", metrics)trainer.save_state()
8 保存模型和创建模型卡片
    # 保存模型和创建模型卡片logger.info("*** Save model ***")trainer.save_model(training_args.output_dir)logger.info(f"Model saved to {training_args.output_dir}")# 在主进程上保存其他信息kwargs = {"dataset_name": script_args.dataset_name,"tags": ["open-r1"],}if trainer.accelerator.is_main_process:trainer.create_model_card(**kwargs)# 恢复k,v缓存以进行快速推理trainer.model.config.use_cache = Truetrainer.model.config.save_pretrained(training_args.output_dir)
9 评估模型
    # 评估模型if training_args.do_eval:logger.info("*** Evaluate ***")metrics = trainer.evaluate()metrics["eval_samples"] = len(dataset[script_args.dataset_test_split])trainer.log_metrics("eval", metrics)trainer.save_metrics("eval", metrics)
10 推送到Hub
    # 推送到Hubif training_args.push_to_hub:logger.info("Pushing to hub...")trainer.push_to_hub(**kwargs)if __name__ == "__main__":parser = TrlParser((ScriptArguments, SFTConfig, ModelConfig))script_args, training_args, model_args = parser.parse_args_and_config()main(script_args, training_args, model_args)

evaluate.py`

用于定义自定义的 LightEval 评估任务,以下是对该文件的深度解析:

1. 模块导入和常量定义

import randomfrom lighteval.metrics.dynamic_metrics import (ExprExtractionConfig,IndicesExtractionConfig,LatexExtractionConfig,multilingual_extractive_match_metric,
)
from lighteval.tasks.lighteval_task import LightevalTaskConfig
from lighteval.tasks.requests import Doc
from lighteval.utils.language import Language
  • 导入了 random 模块,用于生成随机数。
  • lighteval 相关模块中导入了一些配置类和函数,用于定义评估任务和指标。
latex_gold_metric = multilingual_extractive_match_metric(language=Language.ENGLISH,fallback_mode="first_match",precision=5,gold_extraction_target=(LatexExtractionConfig(),),# Match boxed first before trying other regexespred_extraction_target=(ExprExtractionConfig(), LatexExtractionConfig(boxed_match_priority=0)),aggregation_function=max,
)expr_gold_metric = multilingual_extractive_match_metric(language=Language.ENGLISH,fallback_mode="first_match",precision=5,gold_extraction_target=(ExprExtractionConfig(),),# Match boxed first before trying other regexespred_extraction_target=(ExprExtractionConfig(), LatexExtractionConfig(boxed_match_priority=0)),aggregation_function=max,
)gpqa_metric = multilingual_extractive_match_metric(language=Language.ENGLISH,gold_extraction_target=[IndicesExtractionConfig(prefix_for_extraction="NativeLetters")],pred_extraction_target=[IndicesExtractionConfig(prefix_for_extraction="NativeLetters")],precision=5,
)
  • 定义了三个评估指标:latex_gold_metricexpr_gold_metricgpqa_metric,用于后续评估任务的配置。

2. 提示函数定义

def prompt_fn(line, task_name: str = None):"""Assumes the model is either prompted to emit \\boxed{answer} or does so automatically"""return Doc(task_name=task_name,query=line["problem"],choices=[line["solution"]],gold_index=0,)def aime_prompt_fn(line, task_name: str = None):return Doc(task_name=task_name,query=line["problem"],choices=[line["answer"]],gold_index=0,)def gpqa_prompt_fn(line, task_name: str = None):"""Prompt template adapted from simple-evals: https://github.com/openai/simple-evals/blob/83ed7640a7d9cd26849bcb3340125002ef14abbe/common.py#L14"""gold_index = random.randint(0, 3)choices = [line["Incorrect Answer 1"], line["Incorrect Answer 2"], line["Incorrect Answer 3"]]choices.insert(gold_index, line["Correct Answer"])query_template = "Answer the following multiple choice question. The last line of your response should be of the following format: 'Answer: $LETTER' (without quotes) where LETTER is one of ABCD. Think step by step before answering.\n\n{Question}\n\nA) {A}\nB) {B}\nC) {C}\nD) {D}"query = query_template.format(A=choices[0], B=choices[1], C=choices[2], D=choices[3], Question=line["Question"])return Doc(task_name=task_name,query=query,choices=["A", "B", "C", "D"],gold_index=gold_index,instruction=query,)
  • 定义了三个提示函数:prompt_fnaime_prompt_fngpqa_prompt_fn,用于生成不同任务的提示信息。

3. 评估任务配置

aime24 = LightevalTaskConfig(name="aime24",suite=["custom"],prompt_function=aime_prompt_fn,hf_repo="HuggingFaceH4/aime_2024",hf_subset="default",hf_avail_splits=["train"],evaluation_splits=["train"],few_shots_split=None,few_shots_select=None,generation_size=32768,metric=[expr_gold_metric],version=1,
)
# Part I from AIME 2025 exam: https://artofproblemsolving.com/wiki/index.php/2025_AIME_I?srsltid=AfmBOoof5gaaqlt3-l6LH7Tt6qmJZtl_2PQEDYlLFlMqhq9dLL8FMCRR
aime25_part1 = LightevalTaskConfig(name="aime25:part1",suite=["custom"],prompt_function=aime_prompt_fn,hf_repo="open-r1/aime_2025_1",hf_subset="default",hf_avail_splits=["train"],evaluation_splits=["train"],few_shots_split=None,few_shots_select=None,generation_size=32768,metric=[expr_gold_metric],version=1,
)
math_500 = LightevalTaskConfig(name="math_500",suite=["custom"],prompt_function=prompt_fn,hf_repo="HuggingFaceH4/MATH-500",hf_subset="default",hf_avail_splits=["test"],evaluation_splits=["test"],few_shots_split=None,few_shots_select=None,generation_size=32768,metric=[latex_gold_metric],version=1,
)
gpqa_diamond = LightevalTaskConfig(name="gpqa:diamond",suite=["custom"],prompt_function=gpqa_prompt_fn,hf_repo="Idavidrein/gpqa",hf_subset="gpqa_diamond",hf_avail_splits=["train"],evaluation_splits=["train"],few_shots_split=None,few_shots_select=None,generation_size=32768,  # needed for reasoning models like R1metric=[gpqa_metric],stop_sequence=[],  # no stop sequence, will use eos tokentrust_dataset=True,version=1,
)
  • 定义了四个评估任务:aime24aime25_part1math_500gpqa_diamond,每个任务都配置了名称、套件、提示函数、数据集信息、评估指标等。

4. 任务表定义和模块逻辑

# Add tasks to the table
TASKS_TABLE = []
TASKS_TABLE.append(aime24)
TASKS_TABLE.append(aime25_part1)
TASKS_TABLE.append(math_500)
TASKS_TABLE.append(gpqa_diamond)# MODULE LOGIC
if __name__ == "__main__":print([t["name"] for t in TASKS_TABLE])print(len(TASKS_TABLE))
  • 将定义的四个评估任务添加到 TASKS_TABLE 列表中。
  • 如果该文件作为脚本直接运行,则打印任务表中每个任务的名称和任务数量。

generate.py

是一个用于构建并运行 Distilabel 管道以生成响应的 Python 脚本。下面我们将继续深入解析该文件的各个部分:

1. 导入模块

# Copyright 2025 The HuggingFace Team. All rights reserved.
# 省略版权和许可信息...from typing import Optionalfrom distilabel.llms import OpenAILLM
from distilabel.pipeline import Pipeline
from distilabel.steps import StepResources
from distilabel.steps.tasks import TextGeneration
  • Optional: 从 typing 模块导入,用于表示一个类型可以是指定类型或者 None
  • OpenAILLM: 从 distilabel.llms 导入,用于创建 OpenAI 风格的语言模型实例。
  • Pipeline: 从 distilabel.pipeline 导入,用于构建处理数据的管道。
  • StepResources: 从 distilabel.steps 导入,用于指定步骤的资源配置。
  • TextGeneration: 从 distilabel.steps.tasks 导入,用于执行文本生成任务。

2. build_distilabel_pipeline 函数

def build_distilabel_pipeline(model: str,base_url: str = "http://localhost:8000/v1",prompt_column: Optional[str] = None,prompt_template: str = "{{ instruction }}",temperature: Optional[float] = None,top_p: Optional[float] = None,max_new_tokens: int = 8192,num_generations: int = 1,input_batch_size: int = 64,client_replicas: int = 1,timeout: int = 900,retries: int = 0,
) -> Pipeline:generation_kwargs = {"max_new_tokens": max_new_tokens}if temperature is not None:generation_kwargs["temperature"] = temperatureif top_p is not None:generation_kwargs["top_p"] = top_pwith Pipeline().ray() as pipeline:TextGeneration(llm=OpenAILLM(base_url=base_url,api_key="something",model=model,timeout=timeout,max_retries=retries,generation_kwargs=generation_kwargs,),template=prompt_template,input_mappings={"instruction": prompt_column} if prompt_column is not None else {},input_batch_size=input_batch_size,num_generations=num_generations,group_generations=True,resources=StepResources(replicas=client_replicas),)return pipeline
  • 参数

    • model: 用于生成的模型名称,为必需参数。
    • base_url: 语言模型服务的基础 URL,默认为 http://localhost:8000/v1
    • prompt_column: 数据集中用于提示的列名,可选参数。
    • prompt_template: 提示的模板字符串,默认为 {{ instruction }}
    • temperature: 生成时的温度参数,可选参数。
    • top_p: 生成时的 top-p 参数,可选参数。
    • max_new_tokens: 生成的最大新令牌数,默认为 8192。
    • num_generations: 每个问题的生成次数,默认为 1。
    • input_batch_size: 输入处理的批量大小,默认为 64。
    • client_replicas: 并行处理的客户端副本数,默认为 1。
    • timeout: 请求超时时间(秒),默认为 900。
    • retries: 失败请求的重试次数,默认为 0。
  • 功能

    • 构建一个 Distilabel 管道,其中包含一个 TextGeneration 步骤。
    • 根据输入的参数配置 OpenAILLM 实例。
    • 最终返回构建好的管道。

3. main 部分

if __name__ == "__main__":import argparsefrom datasets import load_datasetparser = argparse.ArgumentParser(description="Run distilabel pipeline for generating responses with DeepSeek R1")# 省略一系列参数定义...args = parser.parse_args()print("\nRunning with arguments:")for arg, value in vars(args).items():print(f"  {arg}: {value}")print()print(f"Loading '{args.hf_dataset}' (config: {args.hf_dataset_config}, split: {args.hf_dataset_split}) dataset...")dataset = load_dataset(args.hf_dataset, args.hf_dataset_config, split=args.hf_dataset_split)print("Dataset loaded!")pipeline = build_distilabel_pipeline(model=args.model,base_url=args.vllm_server_url,prompt_template=args.prompt_template,prompt_column=args.prompt_column,temperature=args.temperature,top_p=args.top_p,max_new_tokens=args.max_new_tokens,num_generations=args.num_generations,input_batch_size=args.input_batch_size,client_replicas=args.client_replicas,timeout=args.timeout,retries=args.retries,)print("Running generation pipeline...")distiset = pipeline.run(dataset=dataset,dataset_batch_size=args.input_batch_size * 1000,use_cache=False,)print("Generation pipeline finished!")if args.hf_output_dataset:print(f"Pushing resulting dataset to '{args.hf_output_dataset}'...")distiset.push_to_hub(args.hf_output_dataset, private=args.private)print("Dataset pushed!")
  • 功能
    • 解析命令行参数,包括数据集相关参数、模型参数、生成参数等。
    • 打印运行参数。
    • 加载指定的 Hugging Face 数据集。
    • 调用 build_distilabel_pipeline 函数构建管道。
    • 运行管道进行文本生成。
    • 如果指定了输出数据集的名称,则将生成的数据集推送到 Hugging Face Hub。

grpo.py

是一个用于 GRPO训练脚本的 Python 文件,下面对其进行深度解析:

1. 导入模块

import logging
import os
import sys
from dataclasses import dataclass, fieldimport datasets
import torch
import transformers
from datasets import load_dataset
from transformers import set_seed
from transformers.trainer_utils import get_last_checkpointfrom open_r1.configs import GRPOConfig
from open_r1.rewards import (accuracy_reward,format_reward,get_cosine_scaled_reward,get_repetition_penalty_reward,reasoning_steps_reward,
)
from open_r1.utils.callbacks import get_callbacks
from open_r1.utils.logging import init_wandb_training
from trl import GRPOTrainer, ModelConfig, ScriptArguments, TrlParser, get_peft_config

这里导入了许多必要的模块,包括日志记录、操作系统相关、数据处理(datasets)、深度学习框架(torchtransformers),以及一些自定义模块。

2. 日志记录和常量定义

logger = logging.getLogger(__name__)SYSTEM_PROMPT = ("A conversation between User and Assistant. The user asks a question, and the Assistant solves it. The assistant ""first thinks about the reasoning process in the mind and then provides the user with the answer. The reasoning ""process and answer are enclosed within <think> </think> and <answer> </answer> tags, respectively, i.e., ""<think> reasoning process here </think><answer> answer here </answer>"
)
  • logger 用于记录日志信息。
  • SYSTEM_PROMPT 是一个系统提示,用于构建对话格式。

3. 定义脚本参数类 GRPOScriptArguments

@dataclass
class GRPOScriptArguments(ScriptArguments):...

这是一个数据类,用于存储脚本的参数,包括奖励函数列表、余弦缩放的相关参数、重复惩罚的相关参数等,并且对每个参数都有详细的说明和默认值。

4. 主函数 main

def main(script_args, training_args, model_args):...

主函数是整个脚本的核心,执行以下主要步骤:

4.1 设置随机种子
set_seed(training_args.seed)

确保实验的可重复性。

4.2 配置日志记录
logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%Y-%m-%d %H:%M:%S",handlers=[logging.StreamHandler(sys.stdout)],
)
log_level = training_args.get_process_log_level()
logger.setLevel(log_level)
datasets.utils.logging.set_verbosity(log_level)
transformers.utils.logging.set_verbosity(log_level)
transformers.utils.logging.enable_default_handler()
transformers.utils.logging.enable_explicit_format()

配置日志的格式、日期格式和处理程序,并设置日志级别。

4.3 记录基本信息
logger.warning(f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"+ f" distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}"
)
logger.info(f"Model parameters {model_args}")
logger.info(f"Script parameters {script_args}")
logger.info(f"Training parameters {training_args}")

记录进程的基本信息、模型参数、脚本参数和训练参数。

4.4 检查检查点
last_checkpoint = None
if os.path.isdir(training_args.output_dir):last_checkpoint = get_last_checkpoint(training_args.output_dir)
if last_checkpoint is not None and training_args.resume_from_checkpoint is None:logger.info(f"Checkpoint detected, resuming training at {last_checkpoint=}.")

检查是否有之前的检查点,如果有且没有指定从其他检查点恢复,则从该检查点继续训练。

4.5 初始化 WandB 训练(如果需要)
if "wandb" in training_args.report_to:init_wandb_training(training_args)

如果指定使用 WandB 进行报告,则初始化 WandB 训练。

4.6 加载数据集
dataset = load_dataset(script_args.dataset_name, name=script_args.dataset_config)

使用 load_dataset 函数加载指定的数据集。

4.7 获取奖励函数
REWARD_FUNCS_REGISTRY = {"accuracy": accuracy_reward,"format": format_reward,"reasoning_steps": reasoning_steps_reward,"cosine": get_cosine_scaled_reward(min_value_wrong=script_args.cosine_min_value_wrong,max_value_wrong=script_args.cosine_max_value_wrong,min_value_correct=script_args.cosine_min_value_correct,max_value_correct=script_args.cosine_max_value_correct,max_len=script_args.cosine_max_len,),"repetition_penalty": get_repetition_penalty_reward(ngram_size=script_args.repetition_n_grams,max_penalty=script_args.repetition_max_penalty,),
}
reward_funcs = [REWARD_FUNCS_REGISTRY[func] for func in script_args.reward_funcs]

定义奖励函数的注册表,并根据脚本参数选择相应的奖励函数。

4.8 格式化数据集为对话格式
def make_conversation(example):return {"prompt": [{"role": "system", "content": SYSTEM_PROMPT},{"role": "user", "content": example["problem"]},],}dataset = dataset.map(make_conversation)
for split in dataset:if "messages" in dataset[split].column_names:dataset[split] = dataset[split].remove_columns("messages")

将数据集的每个示例格式化为对话格式,并移除不必要的列。

4.9 初始化模型参数
torch_dtype = (model_args.torch_dtype if model_args.torch_dtype in ["auto", None] else getattr(torch, model_args.torch_dtype)
)
model_kwargs = dict(revision=model_args.model_revision,trust_remote_code=model_args.trust_remote_code,attn_implementation=model_args.attn_implementation,torch_dtype=torch_dtype,use_cache=False if training_args.gradient_checkpointing else True,
)
training_args.model_init_kwargs = model_kwargs

根据模型参数和训练参数初始化模型的关键字参数。

4.10 初始化 GRPO 训练器
trainer = GRPOTrainer(model=model_args.model_name_or_path,reward_funcs=reward_funcs,args=training_args,train_dataset=dataset[script_args.dataset_train_split],eval_dataset=dataset[script_args.dataset_test_split] if training_args.eval_strategy != "no" else None,peft_config=get_peft_config(model_args),callbacks=get_callbacks(training_args, model_args),
)

使用 GRPOTrainer 类初始化训练器,传入模型、奖励函数、训练参数、数据集等。

4.11 训练模型
checkpoint = None
if training_args.resume_from_checkpoint is not None:checkpoint = training_args.resume_from_checkpoint
elif last_checkpoint is not None:checkpoint = last_checkpoint
train_result = trainer.train(resume_from_checkpoint=checkpoint)
metrics = train_result.metrics
metrics["train_samples"] = len(dataset[script_args.dataset_train_split])
trainer.log_metrics("train", metrics)
trainer.save_metrics("train", metrics)
trainer.save_state()

根据检查点情况开始训练模型,并记录训练结果和保存模型状态。

4.12 保存模型和创建模型卡片
trainer.save_model(training_args.output_dir)
logger.info(f"Model saved to {training_args.output_dir}")kwargs = {"dataset_name": script_args.dataset_name,"tags": ["open-r1"],
}
if trainer.accelerator.is_main_process:trainer.create_model_card(**kwargs)trainer.model.config.use_cache = Truetrainer.model.config.save_pretrained(training_args.output_dir)

保存训练好的模型,并在主进程中创建模型卡片。

4.13 评估模型(如果需要)
if training_args.do_eval:logger.info("*** Evaluate ***")metrics = trainer.evaluate()metrics["eval_samples"] = len(dataset[script_args.dataset_test_split])trainer.log_metrics("eval", metrics)trainer.save_metrics("eval", metrics)

如果指定进行评估,则使用训练好的模型进行评估,并记录评估结果。

4.14 推送模型到 Hugging Face Hub(如果需要)
if training_args.push_to_hub:logger.info("Pushing to hub...")trainer.push_to_hub(**kwargs)

如果指定将模型推送到 Hugging Face Hub,则执行推送操作。

5. 主程序入口

if __name__ == "__main__":parser = TrlParser((GRPOScriptArguments, GRPOConfig, ModelConfig))script_args, training_args, model_args = parser.parse_args_and_config()main(script_args, training_args, model_args)

解析命令行参数和配置文件,并调用 main 函数开始训练。

rewards.py

文件主要包含了一系列用于GRPO训练的奖励函数。下面对该文件的内容进行深度解析:

1. 模块导入

import math
import refrom latex2sympy2_extended import NormalizationConfig
from math_verify import LatexExtractionConfig, parse, verify
  • math 模块用于数学计算,例如 math.cos 用于计算余弦值。
  • re 模块用于正则表达式操作,在多个奖励函数中用于文本匹配。
  • latex2sympy2_extendedmath_verify 导入的模块和函数用于处理LaTeX表达式的解析和验证。

2. accuracy_reward 函数

def accuracy_reward(completions, solution, **kwargs):"""Reward function that checks if the completion is the same as the ground truth."""contents = [completion[0]["content"] for completion in completions]rewards = []for content, sol in zip(contents, solution):gold_parsed = parse(sol,extraction_mode="first_match",extraction_config=[LatexExtractionConfig()],)if len(gold_parsed) != 0:# We require the answer to be provided in correct latex (no malformed operators)answer_parsed = parse(content,extraction_config=[LatexExtractionConfig(normalization_config=NormalizationConfig(nits=False,malformed_operators=False,basic_latex=True,equations=True,boxed="all",units=True,),# Ensures that boxed is tried firstboxed_match_priority=0,try_extract_without_anchor=False,)],extraction_mode="first_match",)# Reward 1 if the content is the same as the ground truth, 0 otherwisereward = float(verify(answer_parsed, gold_parsed))else:# If the gold solution is not parseable, we reward 1 to skip this examplereward = 1.0print("Failed to parse gold solution: ", sol)rewards.append(reward)return rewards
  • 功能:检查模型生成的完成内容是否与真实答案相同,若相同则奖励为1,不同则为0。如果真实答案无法解析,则跳过该示例并给予奖励1。
  • 参数
    • completions:模型生成的完成内容列表,每个元素是一个字典列表,取其第一个元素的 "content" 作为实际完成内容。
    • solution:真实答案列表。
  • 实现步骤
    1. 提取 completions 中的内容。
    2. 遍历每个完成内容和对应的真实答案。
    3. 解析真实答案,如果解析成功则继续解析完成内容,并验证两者是否相同。
    4. 根据验证结果给予奖励。

3. format_reward 函数

def format_reward(completions, **kwargs):"""Reward function that checks if the completion has a specific format."""pattern = r"^<think>.*?</think>\s*<answer>.*?</answer>$"completion_contents = [completion[0]["content"] for completion in completions]matches = [re.match(pattern, content, re.DOTALL | re.MULTILINE) for content in completion_contents]return [1.0 if match else 0.0 for match in matches]
  • 功能:检查模型生成的完成内容是否符合特定格式,即是否以 <think> 开头,中间有内容,然后是 <answer> 结尾。
  • 参数
    • completions:模型生成的完成内容列表。
  • 实现步骤
    1. 提取 completions 中的内容。
    2. 使用正则表达式匹配每个完成内容。
    3. 根据匹配结果给予奖励,匹配成功为1,失败为0。

4. reasoning_steps_reward 函数

def reasoning_steps_reward(completions, **kwargs):r"""Reward function that checks for clear step-by-step reasoning.Regex pattern:Step \d+: - matches "Step 1:", "Step 2:", etc.^\d+\. - matches numbered lists like "1.", "2.", etc. at start of line\n- - matches bullet points with hyphens\n\* - matches bullet points with asterisksFirst,|Second,|Next,|Finally, - matches transition words"""pattern = r"(Step \d+:|^\d+\.|\n-|\n\*|First,|Second,|Next,|Finally,)"completion_contents = [completion[0]["content"] for completion in completions]matches = [len(re.findall(pattern, content)) for content in completion_contents]# Magic nubmer 3 to encourage 3 steps and more, otherwise partial rewardreturn [min(1.0, count / 3) for count in matches]
  • 功能:检查模型生成的完成内容中是否有清晰的逐步推理步骤,通过正则表达式匹配特定的标记。
  • 参数
    • completions:模型生成的完成内容列表。
  • 实现步骤
    1. 提取 completions 中的内容。
    2. 使用正则表达式查找每个完成内容中匹配的标记数量。
    3. 根据匹配数量给予奖励,匹配数量达到3个及以上则奖励为1,否则给予部分奖励。

5. get_cosine_scaled_reward 函数

def get_cosine_scaled_reward(min_value_wrong: float = -1.0,max_value_wrong: float = -0.5,min_value_correct: float = 0.5,max_value_correct: float = 1.0,max_len: int = 1000,
):def cosine_scaled_reward(completions, solution, **kwargs):"""Reward function that scales based on completion length using a cosine schedule.Shorter correct solutions are rewarded more than longer ones.Longer incorrect solutions are penalized less than shorter ones.Args:completions: List of model completionssolution: List of ground truth solutionsThis function is parameterized by the following arguments:min_value_wrong: Minimum reward for wrong answersmax_value_wrong: Maximum reward for wrong answersmin_value_correct: Minimum reward for correct answersmax_value_correct: Maximum reward for correct answersmax_len: Maximum length for scaling"""contents = [completion[0]["content"] for completion in completions]rewards = []for content, sol in zip(contents, solution):gold_parsed = parse(sol, extraction_mode="first_match", extraction_config=[LatexExtractionConfig()])if len(gold_parsed) == 0:rewards.append(1.0)  # Skip unparseable examplesprint("Failed to parse gold solution: ", sol)continueanswer_parsed = parse(content,extraction_config=[LatexExtractionConfig(normalization_config=NormalizationConfig(nits=False,malformed_operators=False,basic_latex=True,equations=True,boxed=True,units=True,),boxed_match_priority=0,try_extract_without_anchor=False,)],extraction_mode="first_match",)is_correct = verify(answer_parsed, gold_parsed)gen_len = len(content)# Apply cosine scaling based on lengthprogress = gen_len / max_lencosine = math.cos(progress * math.pi)if is_correct:min_value = min_value_correctmax_value = max_value_correctelse:# Swap min/max for incorrect answersmin_value = max_value_wrongmax_value = min_value_wrongreward = min_value + 0.5 * (max_value - min_value) * (1.0 + cosine)rewards.append(float(reward))return rewardsreturn cosine_scaled_reward
  • 功能:根据完成内容的长度使用余弦调度来计算奖励,较短的正确答案会得到更高的奖励,较长的错误答案会受到较少的惩罚。
  • 参数
    • min_value_wrong:错误答案的最小奖励,默认为 -1.0。
    • max_value_wrong:错误答案的最大奖励,默认为 -0.5。
    • min_value_correct:正确答案的最小奖励,默认为 0.5。
    • max_value_correct:正确答案的最大奖励,默认为 1.0。
    • max_len:用于缩放的最大长度,默认为 1000。
  • 实现步骤
    1. 提取 completions 中的内容。
    2. 遍历每个完成内容和对应的真实答案。
    3. 解析真实答案和完成内容,并验证两者是否相同。
    4. 根据完成内容的长度计算进度,并使用余弦函数进行缩放。
    5. 根据验证结果和缩放值计算奖励。

6. get_repetition_penalty_reward 函数

def get_repetition_penalty_reward(ngram_size: int, max_penalty: float):"""Computes N-gram repetition penalty as described in Appendix C.2 of https://arxiv.org/abs/2502.03373.Reference implementation from: https://github.com/eddycmu/demystify-long-cot/blob/release/openrlhf/openrlhf/reward/repetition.pyArgs:ngram_size: size of the n-gramsmax_penalty: Maximum (negative) penalty for wrong answers"""if max_penalty > 0:raise ValueError(f"max_penalty {max_penalty} should not be positive")def zipngram(text: str, ngram_size: int):words = text.lower().split()return zip(*[words[i:] for i in range(ngram_size)])def repetition_penalty_reward(completions, **kwargs) -> float:"""reward function the penalizes repetitionsref implementation: https://github.com/eddycmu/demystify-long-cot/blob/release/openrlhf/openrlhf/reward/repetition.pyArgs:completions: List of model completions"""contents = [completion[0]["content"] for completion in completions]rewards = []for completion in contents:if completion == "":rewards.append(0.0)continueif len(completion.split()) < ngram_size:rewards.append(0.0)continuengrams = set()total = 0for ng in zipngram(completion, ngram_size):ngrams.add(ng)total += 1scaling = 1 - len(ngrams) / totalreward = scaling * max_penaltyrewards.append(reward)return rewardsreturn repetition_penalty_reward
  • 功能:计算N-gram重复惩罚,用于惩罚生成内容中的重复内容。
  • 参数
    • ngram_size:N-gram的大小。
    • max_penalty:最大(负)惩罚值。
  • 实现步骤
    1. 检查 max_penalty 是否为正数,若是则抛出异常。
    2. 定义 zipngram 函数用于生成N-gram。
    3. 定义 repetition_penalty_reward 函数,遍历每个完成内容,计算N-gram的重复率,并根据重复率和 max_penalty 计算奖励。

相关文章:

【细看open_r1】精读训练和评估模型以及生成合成数据的脚本(src/open_r1)

src/open_r1 目录下主要包含了一些用于训练和评估模型以及生成合成数据的Python脚本&#xff0c;下面我们对其中几个主要的Python文件进行深度剖析。 configs.py 这个文件定义了两个数据类 GRPOConfig 和 SFTConfig&#xff0c;它们分别继承自 trl.GRPOConfig 和 trl.SFTConf…...

数据库数据恢复—MongoDB丢失_mdb_catalog.wt文件导致报错的数据恢复案例

MongoDB数据库存储模式为文档数据存储库&#xff0c;存储方式是将文档存储在集合之中。 MongoDB数据库是开源数据库&#xff0c;同时提供具有附加功能的商业版本。 MongoDB中的数据是以键值对(key-value pairs)的形式显示的。在模式设计上&#xff0c;数据库受到的约束更少。这…...

Qt 控件整理 —— 按钮类

一、PushButton 1. 介绍 在Qt中最常见的就是按钮&#xff0c;它的继承关系如下&#xff1a; 2. 常用属性 3. 例子 我们之前写过一个例子&#xff0c;根据上下左右的按钮去操控一个按钮&#xff0c;当时只是做了一些比较粗糙的去演示信号和槽是这么连接的&#xff0c;这次我们…...

当 LSTM 遇上 ARIMA!!

大家好&#xff0c;我是小青 ARIMA 和 LSTM 是两种常用于时间序列预测的模型&#xff0c;各有优劣。 ARIMA 擅长捕捉线性关系&#xff0c;而 LSTM 擅长处理非线性和长时间依赖的关系。将ARIMA 和 LSTM 融合&#xff0c;可以充分发挥它们各自的优势&#xff0c;构建更强大的时…...

SpringBoot实战:高效获取视频资源

文章目录 前言技术实现SpringBoot项目构建产品选取配置数据采集 号外号外 前言 在短视频行业高速发展的背景下&#xff0c;海量内容数据日益增长&#xff0c;每天都有新的视频、评论、点赞、分享等数据涌现。如何高效、精准地获取并处理这些庞大的数据&#xff0c;已成为各大平…...

MySQL索引数据结构详解

索引的定义&#xff1a;方便Mysql更高效的获取排好序的数据结构 数据结构分为&#xff1a; 二叉树红黑树hash表B-Tree 二叉树规则&#xff1a;可视化二叉树 从父节点查找数据&#xff0c;每个节点最多有两个子节点&#xff0c;左子节点比父节点小&#xff0c;右子节点比父节…...

Python----PyQt开发(PyQt基础,环境搭建,Pycharm中PyQttools工具配置,第一个PyQt程序)

一、QT与PyQT的概念和特点 1.1、QT QT是一个1991年由The Qt Company开发的跨平台C图形用户界面应用程序开发 框架&#xff0c;可构建高性能的桌面、移动及Web应用程序。也可用于开发非GUI程序&#xff0c;比如 控制台工具和服务器。Qt是面向对象的框架&#xff0c;使用特殊的代…...

C语言——排序(冒泡,选择,插入)

基本概念 排序是对数据进行处理的常见操作&#xff0c;即将数据按某字段规律排列。字段是数据节点的一个属性&#xff0c;比如学生信息中的学号、分数等&#xff0c;可针对这些字段进行排序。同时&#xff0c;排序算法有稳定性之分&#xff0c;若两个待排序字段一致的数据在排序…...

物联网智能语音控制灯光系统设计与实现

背景 随着物联网技术的蓬勃发展&#xff0c;智能家居逐渐成为现代生活的一部分。在众多智能家居应用中&#xff0c;智能灯光控制系统尤为重要。通过语音控制和自动调节灯光&#xff0c;用户可以更便捷地操作家中的照明设备&#xff0c;提高生活的舒适度与便利性。本文将介绍一…...

哪吒闹海!SCI算法+分解组合+四模型原创对比首发!SGMD-FATA-Transformer-LSTM多变量时序预测

哪吒闹海&#xff01;SCI算法分解组合四模型原创对比首发&#xff01;SGMD-FATA-Transformer-LSTM多变量时序预测 目录 哪吒闹海&#xff01;SCI算法分解组合四模型原创对比首发&#xff01;SGMD-FATA-Transformer-LSTM多变量时序预测效果一览基本介绍程序设计参考资料 效果一览…...

Python实现决策树(Decision Tree)算法

在 Python 中实现一个决策树算法&#xff0c;可以使用 sklearn 库中的 DecisionTreeClassifier 类。这个类实现了分类任务中的决策树算法。下面是一个简单的例子&#xff0c;展示如何使用 DecisionTreeClassifier 来训练决策树并进行预测。 1. 安装 scikit-learn 如果你还没有…...

刷题日记---二叉树递归专题

文章目录 1. 从根到叶的二进制数之和2. 二叉树的坡度3. 总结 1. 从根到叶的二进制数之和 描述&#xff1a; 给出一棵二叉树&#xff0c;其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。 例如&#xff0c;如果路径为 0 -> 1 ->…...

【C++】智能指针的使用及其原理

1. 智能指针的使用场景分析 下⾯程序中我们可以看到&#xff0c;new了以后&#xff0c;我们也delete了&#xff0c;但是因为抛异常导&#xff0c;后⾯的delete没有得到 执⾏&#xff0c;所以就内存泄漏了&#xff0c;所以我们需要new以后捕获异常&#xff0c;捕获到异常后dele…...

Jenkins 安装插件 二

Jenkins 安装插件 二 一. 打开 Dashboard 打开 Jenkins 界面&#xff0c;不管在任何界面&#xff0c;只需要点击左上角 Dashboard 按钮即可 二. 打开 Manage Jenkins 找到 Manage Jenkins -> System Configuration -> Plugins 点击 Plugins 打开界面如下 Updates&a…...

C++自研游戏引擎-碰撞检测组件-八叉树AABB检测算法实现

八叉树碰撞检测是一种在三维空间中高效处理物体碰撞检测的算法&#xff0c;其原理可以类比为一个管理三维空间物体的智能系统。这个示例包含两个部分&#xff1a;八叉树部分用于宏观检测&#xff0c;AABB用于微观检测。AABB可以更换为均值或节点检测来提高检测精度。 八叉树的…...

Java 大视界 -- 云计算时代 Java 大数据的云原生架构与应用实践(86)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

学习threejs,使用HemisphereLight半球光

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.HemisphereLight 二、…...

XML 命名空间

XML 命名空间 引言 XML&#xff08;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言。在XML中&#xff0c;命名空间&#xff08;Namespace&#xff09;是一个非常重要的概念&#xff0c;它主要用于解决XML文档中元素和属性的命名冲突问题。本文将详细介绍XML命…...

kubernetes-cni 框架源码分析

深入探索 Kubernetes 网络模型和网络通信 Kubernetes 定义了一种简单、一致的网络模型&#xff0c;基于扁平网络结构的设计&#xff0c;无需将主机端口与网络端口进行映射便可以进行高效地通讯&#xff0c;也无需其他组件进行转发。该模型也使应用程序很容易从虚拟机或者主机物…...

【嵌入式Linux应用开发基础】ioctl函数

目录 一、概述 1.1. ioctl 的功能 1.2. 函数原型 1.3. 参数说明 1.4. 返回值 1.5. request 命令的定义 二、典型应用场景 2.1. 串口通信控制 2.2. 网络设备配置与管理 2.3. 字符设备控制 2.4. 块设备管理 2.5. 多媒体设备控制 三、关键注意事项 3.1. request 命令…...

开源的轻量级分布式文件系统FastDFS

FastDFS 是一个开源的轻量级分布式文件系统&#xff0c;专为高性能的分布式文件存储设计&#xff0c;主要用于解决海量文件的存储、同步和访问问题。它特别适合以中小文件&#xff08;如图片、视频等&#xff09;为载体的在线服务&#xff0c;例如相册网站、视频网站等。 FastD…...

从VGG到Transformer:深度神经网络层级演进对模型性能的深度解析与技术实践指南

一、技术原理&#xff08;数学公式示意图&#xff09; 1. 层深与模型容量关系 数学表达&#xff1a;根据Universal Approximation Theorem&#xff0c;深度网络可表达复杂函数&#xff1a; f ( x ) f L ( f L − 1 ( ⋯ f 1 ( x ) ) ) f(x) f_L(f_{L-1}(\cdots f_1(x))) f…...

深入了解 Oracle 正则表达式

目录 深入了解 Oracle 正则表达式一、正则表达式基础概念二、Oracle 正则表达式语法&#xff08;一&#xff09;字符类&#xff08;二&#xff09;重复限定符&#xff08;三&#xff09;边界匹配符&#xff08;四&#xff09;分组和捕获 三、Oracle 正则表达式函数&#xff08;…...

机器学习-监督学习

1. 定义与原理 监督学习依赖于标记数据&#xff08;即每个输入样本都对应已知的输出标签&#xff09;&#xff0c;模型通过分析这些数据中的规律&#xff0c;建立从输入特征到目标标签的映射函数。例如&#xff0c;在垃圾邮件检测中&#xff0c;输入是邮件内容&#xff0c;输出…...

Leetcode:学习记录

一、滑动窗口 1. 找出数组中元素和大于给定值的子数组的最小长度 右指针从左到右遍历&#xff0c;在每个右指针下&#xff0c;如果去掉左边元素的元素和大于等于给定值则左指针右移一次&#xff0c;直到小于给定值&#xff0c;右指针右移一个。 2.找到乘积小于给定值的子数组…...

探索顶级汽车软件解决方案:驱动行业变革的关键力量

在本文中&#xff0c;将一同探索当今塑造汽车行业的最具影响力的软件解决方案。从设计到制造&#xff0c;软件正彻底改变车辆的制造与维护方式。让我们深入了解这个充满活力领域中的关键技术。 设计软件&#xff1a;创新车型的孕育摇篮 车辆设计软件对于创造创新型汽车模型至…...

AI前端开发:解放创造力,而非取代它

近年来&#xff0c;人工智能技术飞速发展&#xff0c;深刻地改变着各行各业&#xff0c;前端开发领域也不例外。越来越多的AI写代码工具涌现&#xff0c;为开发者带来了前所未有的效率提升。很多人担心AI会取代程序员的创造力&#xff0c;但事实并非如此。本文将探讨AI辅助前端…...

探讨使用ISVA代替“Open Liberty使用指南及微服务开发示例”中日志审计功能

在Open Liberty使用指南及开发示例&#xff08;四&#xff09;一文开始日志审计功能占有了一定的开发工作量&#xff0c;那么是否可以使用IBM Security Verify Access&#xff08;ISVA&#xff09;代替以节省开发工作&#xff1f;如果可行&#xff0c;那么以后各类应用的日志审…...

log4j2日志配置文件

log4j2配置文件每个项目都会用到,记录一个比较好用的配置文件,方便以后使用时调取,日志输出级别为debug,也可以修改 <?xml version"1.0" encoding"UTF-8"?> <Configuration monitorInterval"180" packages""><prope…...

python专栏导读

由于本人非python工程师&#xff0c;是在自学python&#xff0c;所以本专栏的内容会显得很基础&#xff0c;甚至有些内容在python工程师看来实在太过于简单&#xff0c;在此清楚嘲笑&#xff0c;因为毕竟每个人都是从不懂、从基础开始的。 本篇作为导读和目录形式存在&#xf…...

Ollama与Vllm使用对比与优劣

Ollama和vLLM是两个用于优化大型语言模型&#xff08;LLM&#xff09;推理的框架&#xff0c;它们在性能、资源利用率、部署复杂性等方面各有优劣。以下是对这两个框架的详细介绍&#xff1a; 1. Ollama Ollama是一个轻量级且易于使用的框架&#xff0c;旨在简化大型语言模型…...

K8s之存储卷

一、容忍、crodon和drain 1.容忍 即使节点上有污点&#xff0c;依然可以部署pod。 字段&#xff1a;tolerations 实例 当node01上有标签test11&#xff0c;污点类型为NoSchedule&#xff0c;而node02没有标签和污点&#xff0c;此时pod可以在node01 node02上都部署&#xff0c…...

luoguP8764 [蓝桥杯 2021 国 BC] 二进制问题

luogu题目传送门 题目描述 小蓝最近在学习二进制。他想知道 1 到 N 中有多少个数满足其二进制表示中恰好有 K 个 1。你能帮助他吗? 输入格式 输入一行包含两个整数 N 和 K。 输出格式 输出一个整数表示答案。 输入输出样例 输入 #1 7 2 输出 #1 3 说明/提示 对于…...

本地部署DeepSeek后的调用与删除全攻略

在本地成功部署DeepSeek模型后&#xff0c;如何高效调用它发挥其强大功能&#xff0c;以及在不需要时妥善删除&#xff0c;是很多用户关注的重点。我也在后台接到了很多粉丝的留言&#xff0c;询问 DeepSeek 本地部署之后的一些调用和删除的问题&#xff0c;于是我在网上找了现…...

Qt Designer菜鸟使用教程(实现一个本地英文翻译软件)

1 安装Qt Designer 安装这个包的时候会自带安装 Qt Designer, 安装目录为python的安装根目录的 Lib/site-packages/qt5_applications/Qt/bin 目录下。 pip install pyqt5-tools2 新建窗体 2.1 新建主窗体 创建之后如下图&#xff1a; 设置主窗口大小&#xff1a; 设置窗…...

C++ 洗牌函数std::shuffle的用法

目录 1.简介 2.工作原理 3.std::shuffle 与 std::random_shuffle 的区别 4.rand 和 srand 5.std::shuffle 的使用方法 6.随机数生成器和分布器 7.注意事项 1.简介 std::shuffle 是 C 标准库中用于对序列进行随机重排&#xff08;洗牌&#xff09;的一种算法。它可以将容…...

MySQL InnoDB引擎 MVCC

MVCC&#xff08;Multi-Version Concurrency Control&#xff09;即多版本并发控制&#xff0c;是 MySQL 的 InnoDB 存储引擎实现并发控制的一种重要技术。它在很多情况下避免了加锁操作&#xff0c;从而提高了数据库的并发性能。 一、原理 MVCC 的核心思想是通过保存数据在某…...

【Elasticsearch】simple_query_string

Elasticsearch 的simple_query_string查询是一种灵活且容错性较强的查询方式&#xff0c;它允许用户通过简单的语法构造查询字符串&#xff0c;以实现对文档的搜索。以下是关于simple_query_string查询的详细说明&#xff1a; 1.基本概念 simple_query_string查询是一种基于字…...

数据结构 04

4. 栈 4.2. 链式栈 4.2.1. 特性 逻辑结构&#xff1a;线性结构 存储结构&#xff1a;链式存储结构 操作&#xff1a;创建&#xff0c;入栈&#xff0c;出栈&#xff0c;清空&#xff0c;获取 4.2.2. 代码实现 头文件 LinkStack.h #ifndef __LINKSTACK_H__ #define __LINKST…...

Java并发中的上下文切换、死锁、资源限制

在Java并发编程中&#xff0c;上下文切换、死锁和资源限制是开发者经常需要面对的问题。这些问题不仅会影响程序的性能&#xff0c;还可能导致程序无法正常运行。本文将深入探讨这些问题的原理、影响以及如何在实际开发中避免或解决它们。 目录 1. 上下文切换&#xff08;Con…...

DeepSeek教unity------MessagePack-01

MessagePack是C# 的极速 MessagePack 序列化器。它比 MsgPack-Cli 快 10 倍&#xff0c;并且性能超过其他 C# 序列化器。MessagePack for C# 还内置支持 LZ4 压缩——一种极其快速的压缩算法。性能在诸如游戏、分布式计算、微服务或数据缓存等应用中尤为重要。 这个库通过 NuGe…...

【大语言模型】最新ChatGPT、DeepSeek等大语言模型助力高效办公、论文与项目撰写、数据分析、机器学习与深度学习建模等科研应用

ChatGPT、DeepSeek等大语言模型助力科研应用 随着人工智能技术的快速发展&#xff0c;大语言模型如ChatGPT和DeepSeek在科研领域的应用正在为科研人员提供强大的支持。这些模型通过深度学习和大规模语料库训练&#xff0c;能够帮助科研人员高效地筛选文献、生成论文内容、进行数…...

泰勒公式推导以及常用展开式与近似计算

泰勒公式的基本思想是通过函数在某点的导数来逐渐构建一个多项式&#xff0c;该多项式能够近似函数在该点附近的值。我们通过一次次引入导数来改进近似&#xff0c;从而得到一个无限级数的展开。 准备工作&#xff1a;函数的定义和导数 假设我们有一个函数 f ( x ) f(x) f(x)…...

深入解析A2DP v1.4协议:蓝牙高质量音频传输的技术与实现

1. A2DP概述 A2DP&#xff08;Advanced Audio Distribution Profile&#xff09;是一种高质量音频流媒体协议&#xff0c;旨在实现高质量音频内容的分发&#xff0c;通常用于通过蓝牙设备传输音频数据&#xff0c;例如将音乐从便携式播放器传输到耳机或扬声器。与传统的蓝牙语…...

STM32引脚VBAT和RTC的关系

一、RTC简介 1、RTC (Real Time Clock)&#xff1a;实时时钟。RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器&#xff0c;在相应的软件配置下&#xff0c;可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期。RTC还包含用于管理低功耗模式的自动唤醒单…...

untiy 3d 混合动画

1.创建动画控制器 挂在到人物模型上 效果 20250213_170924...

django配置跨域

1、第一种 from django.views.decorators.csrf import csrf_exemptcsrf_exempt第二种 安装 pip install django-cors-headers在配置文件settings.py进入 INSTALLED_APPS [..."corsheaders", # 添加 ]MIDDLEWARE [corsheaders.middleware.CorsMiddleware, # 添加…...

【设计模式】【行为型模式】迭代器模式(Iterator)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…...

前端面试题目---页面抖动的原因、如何避免、如何解决

前端页面抖动是一个常见且影响用户体验的问题&#xff0c;下面将从抖动发生的场景、解决办法以及预防措施三个方面进行详细阐述。 页面抖动发生的场景 1. 元素尺寸动态变化 图片加载&#xff1a;当页面中图片的宽高没有预先设定&#xff0c;在图片加载完成后&#xff0c;其实…...

DeepSeek 突然来袭,AI 大模型变革的危机与转机藏在哪?

随着人工智能技术的飞速发展&#xff0c;大模型领域不断涌现出具有创新性的成果。DeepSeek 的横空出世&#xff0c;为 AI 大模型领域带来了新的变革浪潮。本文将深入探讨 DeepSeek 出现后 AI 大模型面临的危机与转机。 冲冲冲&#xff01;&#xff01;&#xff01; 目录 一、…...