使用 TRL 训练Reward Model奖励模型
训练过程
在此示例中,将微调“distilroberta-base”模型。
该formatting_func函数将指令与所选和拒绝的响应相结合,创建两个新字符串。这些字符串被标记化,成为奖励模型的输入,该模型根据这些示例学习区分好响应和坏响应。损失函数的设计方式是最大化所选和拒绝响应的分数之间的差异。使用 trl 的 RewardTrainer 来微调基础模型。它是该类的子类,transformers.Trainer并继承了其所有属性和方法。
#Select a base model whch we need to train for reward modeling.
model_name = "distilroberta-base"
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1)
tokenizer = AutoTokenizer.from_pretrained(model_name)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
model.config.pad_token_id = model.config.eos_token_id
def formatting_func(examples):
kwargs = {"padding": "max_length", "truncation": True, "max_length": 512, "return_tensors": "pt"}
prompt_plus_chosen_response = examples["instruction"] + "\n" + examples["chosen_response"]
prompt_plus_rejected_response = examples["instruction"] + "\n" + examples["rejected_response"]
tokens_chosen = tokenizer.encode_plus(prompt_plus_chosen_response, **kwargs)
tokens_rejected = tokenizer.encode_plus(prompt_plus_rejected_response, **kwargs)
return {
"input_ids_chosen": tokens_chosen["input_ids"][0], "attention_mask_chosen": tokens_chosen["attention_mask"][0],
"input_ids_rejected": tokens_rejected["input_ids"][0], "attention_mask_rejected": tokens_rejected["attention_mask"][0]
}
formatted_dataset = prepared_dataset.map(formatting_func)
formatted_dataset = formatted_dataset.train_test_split()
# Configuring the training arguments
training_args = TrainingArguments(
output_dir="./reward_model",
per_device_train_batch_size=16,
evaluation_strategy="steps",
logging_steps=1,
num_train_epochs = 10,
report_to=None,
)
# Loading the RewardTrainer from TRL
trainer = RewardTrainer(
model=model,
args=training_args,
tokenizer=tokenizer,
train_dataset=formatted_dataset["train"],
eval_dataset=formatted_dataset["test"],
)
trainer.train()
这段代码是用于训练奖励模型(reward model)的Python脚本
model_name = "distilroberta-base":
# 设置要训练的基础模型名称为distilroberta-base,这是一个预训练的模型,适用于序列分类任务。
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=1):
# 加载预训练的模型,并指定这是一个单标签分类任务。
tokenizer = AutoTokenizer.from_pretrained(model_name):
# 加载与模型相对应的分词器。
if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token; model.config.pad_token_id = model.config.eos_token_id:
# 如果分词器没有指定填充(padding)标记,则将其设置为结束(end-of-sequence)标记,并更新模型配置以匹配。
def formatting_func(examples): ...:
# 定义一个函数formatting_func,该函数用于格式化输入数据,使其适合模型训练。
formatted_dataset = prepared_dataset.map(formatting_func):
# 使用formatting_func函数处理prepared_dataset数据集,将其转换为模型训练所需的格式。
formatted_dataset = formatted_dataset.train_test_split():
# 将格式化后的数据集分割为训练集和测试集。
training_args = TrainingArguments(...):
# 配置训练参数,包括输出目录、每个设备的训练批次大小、评估策略、日志记录步骤、训练轮数等。
trainer = RewardTrainer(...):
# 从TRL(Training with Rewards Library)加载RewardTrainer,用于奖励模型的训练。
trainer.train():
# 启动训练过程。
以上代码首先加载了一个预训练的模型和相应的分词器,然后定义了一个数据格式化函数,该函数将指令和选择的答案或拒绝的答案组合起来,并使用分词器进行编码。接着,它将数据集映射到这个格式化函数上,并将其分割为训练集和测试集。然后,它设置了训练参数,并使用RewardTrainer来训练模型。 然后, 调用trainer.train()来开始训练过程。
这是一个能够评估答案质量的模型,其中选择的答案和拒绝的答案将被用来训练模型识别高质量和低质量的答案。
官网提供的日志记录:
Some weights of the model checkpoint at distilroberta-base were not used when initializing RobertaForSequenceClassification: ['lm_head.bias', 'roberta.pooler.dense.bias', 'lm_head.layer_norm.bias', 'roberta.pooler.dense.weight', 'lm_head.dense.weight', 'lm_head.decoder.weight', 'lm_head.dense.bias', 'lm_head.layer_norm.weight']
- This IS expected if you are initializing RobertaForSequenceClassification from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing RobertaForSequenceClassification from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
Some weights of RobertaForSequenceClassification were not initialized from the model checkpoint at distilroberta-base and are newly initialized: ['classifier.dense.bias', 'classifier.out_proj.bias', 'classifier.out_proj.weight', 'classifier.dense.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
Map: 0%| | 0/9 [00:00<?, ? examples/s]
You're using a RobertaTokenizerFast tokenizer. Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to encode the text followed by a call to the `pad` method to get a padded encoding.
Could not estimate the number of tokens of the input, floating-point operations will not be computed
[10/10 00:03, Epoch 10/10]
trl/trainer/reward_trainer.py源代码
# Copyright 2023 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import inspect
import warnings
from collections import defaultdict
from dataclasses import FrozenInstanceError, replace
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
import pandas as pd
import torch
import torch.nn as nn
from accelerate.utils import gather_object
from datasets import Dataset
from transformers import DataCollator, PreTrainedModel, PreTrainedTokenizerBase, Trainer, TrainingArguments
from transformers.trainer_callback import TrainerCallback
from transformers.trainer_pt_utils import nested_detach
from transformers.trainer_utils import EvalPrediction
from ..import_utils import is_peft_available
from .reward_config import RewardConfig
from .utils import RewardDataCollatorWithPadding, compute_accuracy, print_rich_table
if is_peft_available():
from peft import PeftModel, get_peft_model, prepare_model_for_kbit_training
class RewardTrainer(Trainer):
r"""
The RewardTrainer can be used to train your custom Reward Model. It is a subclass of the
`transformers.Trainer` class and inherits all of its attributes and methods. It is recommended to use
an `AutoModelForSequenceClassification` as the reward model. The reward model should be trained on a dataset
of paired examples, where each example is a tuple of two sequences. The reward model should be trained to
predict which example in the pair is more relevant to the task at hand.
The reward trainer expects a very specific format for the dataset. The dataset should contain two 4 entries at least
if you don't use the default `RewardDataCollatorWithPadding` data collator. The entries should be named
- `input_ids_chosen`
- `attention_mask_chosen`
- `input_ids_rejected`
- `attention_mask_rejected`
Optionally, you can also pass a `margin` entry to the dataset. This entry should contain the margin used to modulate the
loss of the reward model as outlined in https://ai.meta.com/research/publications/llama-2-open-foundation-and-fine-tuned-chat-models/.
If you don't pass a margin, no margin will be used.
"""
_tag_names = ["trl", "reward-trainer"]
def __init__(
self,
model: Optional[Union[PreTrainedModel, nn.Module]] = None,
args: Optional[RewardConfig] = None,
data_collator: Optional[DataCollator] = None,
train_dataset: Optional[Dataset] = None,
eval_dataset: Optional[Union[Dataset, Dict[str, Dataset]]] = None,
tokenizer: Optional[PreTrainedTokenizerBase] = None,
model_init: Optional[Callable[[], PreTrainedModel]] = None,
compute_metrics: Optional[Callable[[EvalPrediction], Dict]] = None,
callbacks: Optional[List[TrainerCallback]] = None,
optimizers: Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (
None,
None,
),
preprocess_logits_for_metrics: Optional[Callable[[torch.Tensor, torch.Tensor], torch.Tensor]] = None,
max_length: Optional[int] = None,
peft_config: Optional[Dict] = None,
):
"""
Initialize RewardTrainer.
Args:
model (`transformers.PreTrainedModel`):
The model to train, preferably an `AutoModelForSequenceClassification`.
args (`RewardConfig`):
The arguments to use for training.
data_collator (`transformers.DataCollator`):
The data collator to use for training. If None is specified, the default data collator (`RewardDataCollatorWithPadding`) will be used
which will pad the sequences to the maximum length of the sequences in the batch, given a dataset of paired sequences.
train_dataset (`datasets.Dataset`):
The dataset to use for training.
eval_dataset (`datasets.Dataset`):
The dataset to use for evaluation.
tokenizer (`transformers.PreTrainedTokenizerBase`):
The tokenizer to use for training. This argument is required if you want to use the default data collator.
model_init (`Callable[[], transformers.PreTrainedModel]`):
The model initializer to use for training. If None is specified, the default model initializer will be used.
compute_metrics (`Callable[[transformers.EvalPrediction], Dict]`, *optional* defaults to `compute_accuracy`):
The metrics to use for evaluation. If no metrics are specified, the default metric (`compute_accuracy`) will be used.
callbacks (`List[transformers.TrainerCallback]`):
The callbacks to use for training.
optimizers (`Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR]`):
The optimizer and scheduler to use for training.
preprocess_logits_for_metrics (`Callable[[torch.Tensor, torch.Tensor], torch.Tensor]`):
The function to use to preprocess the logits before computing the metrics.
max_length (`int`, defaults to `None`):
The maximum length of the sequences in the batch. This argument is required if you want to use the default data collator.
peft_config (`Dict`, defaults to `None`):
The PEFT configuration to use for training. If you pass a PEFT configuration, the model will be wrapped in a PEFT model.
"""
if type(args) == TrainingArguments:
warnings.warn(
"Using `transformers.TrainingArguments` for `args` is deprecated and will be removed in a future version. Please use `RewardConfig` instead.",
FutureWarning,
)
if max_length is not None:
warnings.warn(
"The `max_length` argument is deprecated and will be removed in a future version. Please use the `RewardConfig` to set `max_length` instead.",
FutureWarning,
)
else:
if max_length is not None and args.max_length is not None:
raise ValueError(
"You cannot specify both `max_length` and `args.max_length`. Please use the `RewardConfig` to set `max_length` once."
)
if max_length is not None and args.max_length is None:
warnings.warn(
"The `max_length` argument is deprecated and will be removed in a future version. Please use the `RewardConfig` to set `max_length` instead.",
FutureWarning,
)
if not is_peft_available() and peft_config is not None:
raise ValueError(
"PEFT is not installed and you passed a `peft_config` in the trainer's kwargs, please install it to use the PEFT models"
)
elif is_peft_available() and peft_config is not None:
if not isinstance(model, PeftModel):
if getattr(model, "is_loaded_in_8bit", False) or getattr(model, "is_quantized", False):
_supports_gc_kwargs = "gradient_checkpointing_kwargs" in list(
inspect.signature(prepare_model_for_kbit_training).parameters
)
prepare_model_kwargs = {"use_gradient_checkpointing": args.gradient_checkpointing}
if not _supports_gc_kwargs and args.gradient_checkpointing_kwargs is not None:
warnings.warn(
"You passed `gradient_checkpointing_kwargs` in the trainer's kwargs, but your peft version does not support it. "
"please update to the latest version of peft to use `gradient_checkpointing_kwargs`."
)
elif _supports_gc_kwargs and args.gradient_checkpointing_kwargs is not None:
prepare_model_kwargs["gradient_checkpointing_kwargs"] = args.gradient_checkpointing_kwargs
model = prepare_model_for_kbit_training(model, **prepare_model_kwargs)
model = get_peft_model(model, peft_config)
if compute_metrics is None:
compute_metrics = compute_accuracy
if data_collator is None:
if tokenizer is None:
raise ValueError(
"max_length or a tokenizer must be specified when using the default RewardDataCollatorWithPadding"
)
if type(args) == TrainingArguments:
if max_length is None:
warnings.warn(
"When using RewardDataCollatorWithPadding, you should set `max_length` in RewardConfig."
" It will be set to `512` by default, but you should do it yourself in the future.",
UserWarning,
)
max_length = 512
else:
if max_length is None and args.max_length is None:
warnings.warn(
"When using RewardDataCollatorWithPadding, you should set `max_length` in RewardConfig."
" It will be set to `512` by default, but you should do it yourself in the future.",
UserWarning,
)
max_length = 512
if max_length is None and args.max_length is not None:
max_length = args.max_length
data_collator = RewardDataCollatorWithPadding(tokenizer, max_length=max_length)
if args.remove_unused_columns:
try: # for bc before https://github.com/huggingface/transformers/pull/25435
args.remove_unused_columns = False
except FrozenInstanceError:
args = replace(args, remove_unused_columns=False)
# warn users
warnings.warn(
"When using RewardDataCollatorWithPadding, you should set `remove_unused_columns=False` in your RewardConfig"
" we have set it for you, but you should do it yourself in the future.",
UserWarning,
)
self.use_reward_data_collator = True
else:
self.use_reward_data_collator = False
super().__init__(
model=model,
args=args,
data_collator=data_collator,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
tokenizer=tokenizer,
model_init=model_init,
compute_metrics=compute_metrics,
callbacks=callbacks,
optimizers=optimizers,
preprocess_logits_for_metrics=preprocess_logits_for_metrics,
)
# Add tags for models that have been loaded with the correct transformers version
if hasattr(self.model, "add_model_tags"):
self.model.add_model_tags(self._tag_names)
def compute_loss(
self,
model: Union[PreTrainedModel, nn.Module],
inputs: Dict[str, Union[torch.Tensor, Any]],
return_outputs=False,
) -> Union[torch.Tensor, Tuple[torch.Tensor, Dict[str, torch.Tensor]]]:
if not self.use_reward_data_collator:
warnings.warn(
"The current compute_loss is implemented for RewardDataCollatorWithPadding,"
" if you are using a custom data collator make sure you know what you are doing or"
" implement your own compute_loss method."
)
rewards_chosen = model(
input_ids=inputs["input_ids_chosen"],
attention_mask=inputs["attention_mask_chosen"],
return_dict=True,
)["logits"]
rewards_rejected = model(
input_ids=inputs["input_ids_rejected"],
attention_mask=inputs["attention_mask_rejected"],
return_dict=True,
)["logits"]
# calculate loss, optionally modulate with margin
if "margin" in inputs:
loss = -nn.functional.logsigmoid(rewards_chosen - rewards_rejected - inputs["margin"]).mean()
else:
loss = -nn.functional.logsigmoid(rewards_chosen - rewards_rejected).mean()
if return_outputs:
return loss, {
"rewards_chosen": rewards_chosen,
"rewards_rejected": rewards_rejected,
}
return loss
def prediction_step(
self,
model: Union[PreTrainedModel, nn.Module],
inputs: Dict[str, Union[torch.Tensor, Any]],
prediction_loss_only: bool,
ignore_keys: Optional[List[str]] = None,
) -> Tuple[Optional[torch.Tensor], Optional[torch.Tensor], Optional[torch.Tensor]]:
inputs = self._prepare_inputs(inputs)
if ignore_keys is None:
if hasattr(self.model, "config"):
ignore_keys = getattr(self.model.config, "keys_to_ignore_at_inference", [])
else:
ignore_keys = []
with torch.no_grad():
loss, logits_dict = self.compute_loss(model, inputs, return_outputs=True)
if prediction_loss_only:
return (loss, None, None)
loss = loss.detach()
logits = tuple(v for k, v in logits_dict.items() if k not in ignore_keys)
logits = nested_detach(logits)
# Stack accepted against rejected, mean over logits
# and softmax to get preferences between accepted and rejected to sum to 1
logits = torch.stack(logits).mean(dim=2).softmax(dim=0).T
labels = torch.zeros(logits.shape[0])
labels = self._prepare_inputs(labels)
return loss, logits, labels
def evaluate(self, *args, **kwargs):
num_print_samples = kwargs.pop("num_print_samples", 4)
self.visualize_samples(num_print_samples)
return super().evaluate(*args, **kwargs)
def visualize_samples(self, num_print_samples: int):
"""
Visualize the reward model logits prediction
Args:
num_print_samples (`int`, defaults to `4`):
The number of samples to print. Set to `-1` to print all samples.
"""
eval_dataloader = self.get_eval_dataloader()
table = defaultdict(list)
for _, inputs in enumerate(eval_dataloader):
_, logits, _ = self.prediction_step(self.model, inputs, prediction_loss_only=False)
chosen_text = self.tokenizer.batch_decode(inputs["input_ids_chosen"], skip_special_tokens=True)
rejected_text = self.tokenizer.batch_decode(inputs["input_ids_rejected"], skip_special_tokens=True)
table["chosen_text"].extend(gather_object(chosen_text))
table["rejected_text"].extend(gather_object(rejected_text))
table["logits"].extend(
gather_object([[round(inner_item, 4) for inner_item in item] for item in logits.tolist()])
)
if num_print_samples >= 0 and len(table["chosen_text"]) >= num_print_samples:
break
df = pd.DataFrame(table)
print_rich_table(pd.DataFrame(table))
if self.accelerator.process_index == 0:
print_rich_table(df[:num_print_samples])
if "wandb" in self.args.report_to:
import wandb
if wandb.run is not None:
wandb.log({"completions": wandb.Table(dataframe=df)})
这段代码是 Hugging Face的Transformers 、Trl 库的一部分。RewardTrainer类是transformers.Trainer类的子类,用于训练自定义的奖励模型(Reward Model)。
版权声明:代码开头的注释说明了该文件的版权属于HuggingFace团队,并根据Apache License 2.0版获得许可。
导入依赖:代码导入了多个Python模块和类,包括inspect、warnings、defaultdict、dataclasses、pandas、torch、transformers等,这些是实现RewardTrainer类所需的依赖。
RewardTrainer类定义:定义了一个名为RewardTrainer的类,它包含了训练奖励模型所需的方法和属性。
初始化方法:__init__方法初始化RewardTrainer类的实例。它接受多个参数,如模型(model)、训练参数(args)、数据整理器(data_collator)、训练数据集(train_dataset)、评估数据集(eval_dataset)、分词器(tokenizer)等。
PEFT配置:如果提供了PEFT(Prompt Engineering with Frozen Transformers)配置,则会使用该配置来包装模型。
数据整理:如果未指定数据整理器,则会使用默认的RewardDataCollatorWithPadding,该整理器会根据批处理中序列的最大长度来填充序列。
损失计算:compute_loss方法用于计算模型的损失。它使用模型为接受的(chosen)和拒绝的(rejected)输入序列生成的logits,并计算它们之间的差异。
预测步骤:prediction_step方法在模型上执行预测步骤,并返回损失、logits和标签。
评估:evaluate方法在评估期间被调用,它还调用了一个visualize_samples方法来可视化模型对样本的预测。
可视化样本:visualize_samples方法打印了模型预测的一些样本,以帮助理解模型是如何在给定的接受和拒绝序列之间进行选择的。
使用 TRL 训练Reward Model奖励模型的更多相关文章
- Keras Model Sequential模型接口
Sequential 模型 API 在阅读这片文档前,请先阅读 Keras Sequential 模型指引. Sequential 模型方法 compile compile(optimizer, lo ...
- 机器学习在入侵检测方面的应用 - 基于ADFA-LD训练集训练入侵检测判别模型
1. ADFA-LD数据集简介 ADFA-LD数据集是澳大利亚国防学院对外发布的一套主机级入侵检测数据集合,包括Linux和Windows,是一个包含了入侵事件的系统调用syscall序列的数据集(以 ...
- Model Validation(模型验证)
Model Validation(模型验证) 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/344 ...
- 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】
Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...
- Tensorflow Mask-RCNN训练识别箱子的模型运行结果(练习)
Tensorflow Mask-RCNN训练识别箱子的模型
- Box Model 盒子模型
Box Model盒子模型,是初学者在学习HTMl5时会学到的一个重要的模型,也有一些人称它为框模型,因为盒子是属于3维,而框是平面的.称之为盒子模型,是因为其结构和盒子十分相似,其最外面是margi ...
- LUSE: 无监督数据预训练短文本编码模型
LUSE: 无监督数据预训练短文本编码模型 1 前言 本博文本应写之前立的Flag:基于加密技术编译一个自己的Python解释器,经过半个多月尝试已经成功,但考虑到安全性问题就不公开了,有兴趣的朋友私 ...
- Gensim进阶教程:训练word2vec与doc2vec模型
本篇博客是Gensim的进阶教程,主要介绍用于词向量建模的word2vec模型和用于长文本向量建模的doc2vec模型在Gensim中的实现. Word2vec Word2vec并不是一个模型--它其 ...
- 机器学习进阶-目标追踪-SSD多进程执行 1.cv2.dnn.readnetFromCaffe(用于读取已经训练好的caffe模型) 2.delib.correlation_tracker(生成追踪器) 5.cv2.writer(将图片写入视频中) 6.cv2.dnn.blobFromImage(图片归一化) 10.multiprocessing.process(生成进程)
1. cv2.dnn.readNetFromCaffe(prototxt, model) 用于进行SSD网络的caffe框架的加载 参数说明:prototxt表示caffe网络的结构文本,model ...
- 深度学习方法(九):自然语言处理中的Attention Model注意力模型
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.NET/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 上一篇博文深度学习方法(八):Enc ...
随机推荐
- Docker Hub 镜像加速器——持续更新(2025年3月12日)
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.Docker 官方和国内很多云服务商都提供了国内加速器服务. 配置加速地址 Ubuntu 16.04+.Debian 8+ ...
- 最新活动 ISS 国际空间站 MAI-75 SSTV活动计划于2020年8月4日至5日
MAI-75 SSTV活动计划于2020年8月4日和5日举行 8月3日至9日这一周的最后宇航员时间表最近公布了,它显示了定于8月4日和5日进行的MAI-75活动.这是在Space X Demo-2脱 ...
- BUUCTF---佛说:只能四天
题目 尊即寂修我劫修如婆愍闍嚤婆莊愍耨羅嚴是喼婆斯吶眾喼修迦慧迦嚩喼斯願嚤摩隸所迦摩吽即塞願修咒莊波斯訶喃壽祗僧若即亦嘇蜜迦須色喼羅囉咒諦若陀喃慧愍夷羅波若劫蜜斯哆咒塞隸蜜波哆咤慧聞亦吽念彌諸嘚嚴諦咒 ...
- c-primer-plus深入解读系列-从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
前言 小提示:阅读本篇内容,至少需要了解double和float的二进制表示规则. 书中的代码示例如下: #include <stdio.h> int main(void) { float ...
- Oracle SQL%ROWCOUNT
SQL%ROWCOUNT 用于记录受影响的行数, 必须紧跟在一个新增/修改/删除类语句后. 当执行多条修改语句时, 按照 sql%rowcount 之前执行的最后一条语句受影响行数为准. 应用场景 可 ...
- python练习-爬虫
场景: 1.网址hppt://xxx.yyy.zzz.cn2.打开网页后显示 : 3.填上姓名 身份证和验证码,点击查询后,返回查询结果. 4.页面有cookie. 方案一: 程序中嵌入浏览器根据网址 ...
- 子图,生成子图(Spanning Subgraph),导出子图(Induced Subgraph)的定义
原图G用\(G=(V,E)\)表示,\(V\)是\(G\)中的所有顶点的集合:\(E\)是\(G\)中所有边的集合. 子图 定义:子图\(G '\)中的所有顶点和边均包含于原图\(G\).即\(E'∈ ...
- RL · Exploration | 使用时序距离构造 intrinsic reward,鼓励 agent 探索
论文标题:Episodic Novelty Through Temporal Distance. ICLR 2025,8 8 6 5 poster. arxiv:https://arxiv.org/a ...
- rabbitmq学习与总结
一.rabbitmq的使用场景 1.高并发的流量削峰 举个例子,假设某订单系统每秒最多能处理一万次订单,也就是最多承受的10000qps,这个处理能力应付正常时段的下单时绰绰有余,正常时段我们下单一秒 ...
- 智能简历解析器实战教程:基于Spacy+Flask构建自动化人才筛选系统
一.项目背景与技术选型 在人力资源领域,每天需要处理数百份简历的HR团队面临巨大挑战:人工筛选效率低下.关键信息遗漏风险高.跨文档对比分析困难.本教程将构建一个端到端的智能简历解析系统,通过NLP技术 ...