赞
踩
目的是在标记化的过程中监控可能的问题,特别是针对输入文本长度的问题。通过记录警告,可以更好地了解标记化过程中可能发生的问题,并在必要时采取适当的措施,例如将长输入文本分块。
""" 目的是在标记化的过程中监控可能的问题,特别是针对输入文本长度的问题。通过记录警告,可以更好地了解标记化过程中可能发生的问题,并在必要时采取适当的措施,例如将长输入文本分块。 """ def tokenize_function(examples): """ 使用 CaptureLogger(tok_logger) 上下文管理器捕获 tok_logger 中的日志输出。 如果捕获到了特定的警告消息:"Token indices sequence length is longer than the",则说明输入文本的标记序列长度超过了某个限制。 """ with CaptureLogger(tok_logger) as cl: #使用 tokenizer 进行标记化: # output = tokenizer(examples[text_column_name]) 使用给定的 tokenizer 对输入文本进行标记化,结果存储在 output 中。 output = tokenizer(examples[text_column_name]) # clm input could be much much longer than block_size """ 记录警告: 如果存在上述警告,通过 tok_logger.warning 记录一条新的警告消息,说明输入文本的长度较长,将在传递给模型之前被分块成较小的部分 """ """ 返回标记化的输出: 返回标记化后的输出 output。 """ if "Token indices sequence length is longer than the" in cl.out: tok_logger.warning( "^^^^^^^^^^^^^^^^ Please ignore the warning above - this long input will be chunked into smaller bits" " before being passed to the model." ) return output
通常用于在训练之前对数据集进行标记化处理。
使用多进程可以加速处理过程,特别是对于大规模的数据集。流式处理则适用于无法将整个数据集一次性加载到内存中的情况
""" 通常用于在训练之前对数据集进行标记化处理。 使用多进程可以加速处理过程,特别是对于大规模的数据集。流式处理则适用于无法将整个数据集一次性加载到内存中的情况。 """ """ with training_args.main_process_first(desc="dataset map tokenization"):: 使用 main_process_first 上下文管理器,确保在主进程中执行以下代码块。 desc="dataset map tokenization" 提供了一个描述,用于在进度条中显示。 """ with training_args.main_process_first(desc="dataset map tokenization"): # 如果不是流式处理(not data_args.streaming),执行以下操作: if not data_args.streaming: # 使用 raw_datasets.map 函数对原始数据集进行标记化处理 # batched=True 表示对数据集进行批处理。 # num_proc=data_args.preprocessing_num_workers 表示使用多进程进行处理,可以提高效率。 tokenized_datasets = raw_datasets.map( tokenize_function, batched=True, num_proc=data_args.preprocessing_num_workers, # remove_columns=column_names 表示移除不再需要的列,即之前确定的 column_names remove_columns=column_names, # load_from_cache_file=not data_args.overwrite_cache # 表示尝试从缓存文件加载数据,如果缓存文件不存在或用户选择覆盖缓存,则重新生成。 load_from_cache_file=not data_args.overwrite_cache, # desc="Running tokenizer on dataset" 提供了一个进度描述。 desc="Running tokenizer on dataset", ) else: tokenized_datasets = raw_datasets.map( tokenize_function, batched=True, remove_columns=column_names, )
这段代码的目的是在模型配置中查找 max_position_embeddings 属性,并将其值存储在变量 max_pos_embeddings 中。这个属性通常表示模型支持的最大位置嵌入数,即模型能够处理的最大序列长度。如果模型配置中未定义该属性,则使用默认值 1024
# 这段代码的目的是在模型配置中查找 max_position_embeddings 属性,并将其值存储在变量 max_pos_embeddings 中。
# 这个属性通常表示模型支持的最大位置嵌入数,即模型能够处理的最大序列长度。如果模型配置中未定义该属性,则使用默认值 1024
# 使用 hasattr(config, "max_position_embeddings") 检查模型配置 config 是否具有名为 max_position_embeddings 的属性。
if hasattr(config, "max_position_embeddings"):
max_pos_embeddings = config.max_position_embeddings
else:
# Define a default value if the attribute is missing in the config.
max_pos_embeddings = 1024
代码确保了 block_size 的合理设置,以适应模型的最大长度,并在用户指定块大小时进行相应的处理和警告。这对于确保输入数据的长度适应模型输入的限制是很重要的。
""" 代码确保了 block_size 的合理设置,以适应模型的最大长度,并在用户指定块大小时进行相应的处理和警告。这对于确保输入数据的长度适应模型输入的限制是很重要的。 """ """ 检查 data_args.block_size 是否为 None: 如果 data_args.block_size 为 None,表示用户没有指定块大小,执行以下操作: 将 block_size 设置为 tokenizer.model_max_length,即 tokenizer 所使用的模型的最大长度。 如果 block_size 大于 max_pos_embeddings(模型的最大位置嵌入数),则发出警告,并将 block_size 重新设置为 min(1024, max_pos_embeddings)。 如果 max_pos_embeddings 大于 0,则将 block_size 重新设置为 min(1024, max_pos_embeddings),否则将 block_size 设置为 1024。 """ if data_args.block_size is None:# 检查 data_args.block_size 是否为 None: block_size = tokenizer.model_max_length # 最大长度 if block_size > max_pos_embeddings: logger.warning( f"The tokenizer picked seems to have a very large `model_max_length` ({tokenizer.model_max_length}). " f"Using block_size={min(1024, max_pos_embeddings)} instead. You can change that default value by passing --block_size xxx." ) if max_pos_embeddings > 0: block_size = min(1024, max_pos_embeddings) else: block_size = 1024 else: if data_args.block_size > tokenizer.model_max_length: logger.warning( f"The block_size passed ({data_args.block_size}) is larger than the maximum length for the model " f"({tokenizer.model_max_length}). Using block_size={tokenizer.model_max_length}." ) block_size = min(data_args.block_size, tokenizer.model_max_length)
这段代码定义了一个名为 group_texts 的函数,该函数的主要目的是将文本数据组合成固定长度的块(chunks)。函数的解释如下:
# 这段代码定义了一个名为 group_texts 的函数,该函数的主要目的是将文本数据组合成固定长度的块(chunks)。函数的解释如下: # Main data processing function that will concatenate all texts from our dataset and generate chunks of block_size. def group_texts(examples): # Concatenate all texts. # 拼接所有的文本 # 将输入的 examples 中的文本进行拼接。这是通过将每个键(例如,"input_ids")对应的文本列表展平成一个长列表来完成的。 concatenated_examples = {k: list(chain(*examples[k])) for k in examples.keys()} # 计算拼接后文本的总长度。 # 接着,将 total_length 除以 block_size 并取整,以确保整个文本序列被均匀地划分成大小为 block_size 的块。 total_length = len(concatenated_examples[list(examples.keys())[0]]) # We drop the small remainder, and if the total_length < block_size we exclude this batch and return an empty dict. # We could add padding if the model supported it instead of this drop, you can customize this part to your needs. total_length = (total_length // block_size) * block_size # result 是一个字典,其中包含了将文本拆分成块的结果。 # 对于每个键 k,通过列表推导式将拼接的文本按 block_size 大小切割成块,存储在 result[k] 中。 # 最终的 result["labels"] 被设置为 result["input_ids"] 的副本。 # Split by chunks of max_len. result = { k: [t[i : i + block_size] for i in range(0, total_length, block_size)] for k, t in concatenated_examples.items() } #返回一个包含拆分后文本的字典。 result["labels"] = result["input_ids"].copy() return result
这段代码使用 group_texts 函数将标记化后的数据集 tokenized_datasets 组织成适应模型输入的块,并生成一个新的数据集 lm_datasets。
这样的处理过程通常用于准备数据集以用于训练语言模型。通过将文本按块组合,确保输入的序列长度符合模型的要求,并且在处理大规模数据集时能够高效地进行。
# 这段代码定义了一个名为 group_texts 的函数,该函数的主要目的是将文本数据组合成固定长度的块(chunks)。函数的解释如下: # Main data processing function that will concatenate all texts from our dataset and generate chunks of block_size. def group_texts(examples): # Concatenate all texts. # 拼接所有的文本 # 将输入的 examples 中的文本进行拼接。这是通过将每个键(例如,"input_ids")对应的文本列表展平成一个长列表来完成的。 concatenated_examples = {k: list(chain(*examples[k])) for k in examples.keys()} # 计算拼接后文本的总长度。 # 接着,将 total_length 除以 block_size 并取整,以确保整个文本序列被均匀地划分成大小为 block_size 的块。 total_length = len(concatenated_examples[list(examples.keys())[0]]) # We drop the small remainder, and if the total_length < block_size we exclude this batch and return an empty dict. # We could add padding if the model supported it instead of this drop, you can customize this part to your needs. total_length = (total_length // block_size) * block_size # result 是一个字典,其中包含了将文本拆分成块的结果。 # 对于每个键 k,通过列表推导式将拼接的文本按 block_size 大小切割成块,存储在 result[k] 中。 # 最终的 result["labels"] 被设置为 result["input_ids"] 的副本。 # Split by chunks of max_len. result = { k: [t[i : i + block_size] for i in range(0, total_length, block_size)] for k, t in concatenated_examples.items() } #返回一个包含拆分后文本的字典。 result["labels"] = result["input_ids"].copy() return result
数用于预处理模型输出的logits以便进行度量评估
if training_args.do_eval: if "validation" not in tokenized_datasets: raise ValueError("--do_eval requires a validation dataset") eval_dataset = lm_datasets["validation"] if data_args.max_eval_samples is not None: max_eval_samples = min(len(eval_dataset), data_args.max_eval_samples) eval_dataset = eval_dataset.select(range(max_eval_samples)) # 模型输出的 logits,这里假设是一个张量(tensor) # 标签,用于计算评估指标。 def preprocess_logits_for_metrics(logits, labels): # 如果 logits 是一个元组(tuple),则说明模型输出的 logits 包含了额外的张量 # ,例如 past_key_values,但是我们只关心 logits 本身,因此取元组中的第一个元素:logits = logits[0]。 if isinstance(logits, tuple): # Depending on the model and config, logits may contain extra tensors, # like past_key_values, but logits always come first logits = logits[0] # 返回预处理后的 logits,通过 logits.argmax(dim=-1) 取得在最后一个维度上的最大值的索引,即模型预测的标签。 return logits.argmax(dim=-1) """ evaluate.load("accuracy"): evaluate.load 是 Transformers 库中用于加载评估指标的函数。 通过传递字符串参数 "accuracy",该函数加载了一个计算准确度的评估指标。 metric = evaluate.load("accuracy"): 将加载的 "accuracy" 评估指标存储在变量 metric 中,以便后续使用。 """ metric = evaluate.load("accuracy") # 函数的目的是计算在评估阶段使用的指标,通常用于评估模型在测试集上的性能。 # 在计算指标时,需要将模型的预测与真实标签进行比较,并将结果传递给特定的评估指标计算函数(例如,准确度、精确度、召回率等)。 def compute_metrics(eval_preds): # 调用预先加载的评估指标 (metric) 的 compute 方法,传递模型的预测 (predictions) 和真实标签 (references)。 # 返回计算得到的指标值。 preds, labels = eval_preds # preds have the same shape as the labels, after the argmax(-1) has been calculated # by preprocess_logits_for_metrics but we need to shift the labels labels = labels[:, 1:].reshape(-1) preds = preds[:, :-1].reshape(-1) return metric.compute(predictions=preds, references=labels)
""" 检查是否执行评估 (training_args.do_eval):如果 training_args.do_eval 为 True,表示要执行评估,执行以下操作。 打印评估信息 (logger.info("*** Evaluate ***")): 使用 logger 打印评估的信息。执行评估 (trainer.evaluate): 调用 trainer.evaluate 方法对验证集进行评估,获取评估指标。 获取评估结果的指标 (metrics): 将评估结果中的指标存储在变量 metrics 中。 限制最大评估样本数 (max_eval_samples): 如果用户指定了 data_args.max_eval_samples,则将最大评估样本数设置为该值。 否则,将最大评估样本数设置为验证集的长度。 计算困惑度 (perplexity) 通过将指数函数应用于评估损失 (metrics["eval_loss"]) 计算困惑度。困惑度是语言模型性能的一种度量,它衡量模型对给定数据的预测的不确定性。 记录评估指标 (trainer.log_metrics): 调用 trainer.log_metrics 方法记录评估指标,包括损失、困惑度等。 保存评估指标 (trainer.save_metrics): 调用 trainer.save_metrics 方法将评估指标保存到磁盘。 """ # Evaluation # 检查是否执行评估 if training_args.do_eval: # 打印评估信息 logger.info("*** Evaluate ***") # 获取评估结果的指标:执行评估 metrics = trainer.evaluate() # 限制最大评估样本数 # 如果用户指定了data_args.max_eval_samples,则将最大评估样本数设置为该值 # 否则,将最大评估样本数设置为验证机的长度 max_eval_samples = data_args.max_eval_samples if data_args.max_eval_samples is not None else len(eval_dataset) # 计算困惑度 metrics["eval_samples"] = min(max_eval_samples, len(eval_dataset)) try: perplexity = math.exp(metrics["eval_loss"]) except OverflowError: perplexity = float("inf") metrics["perplexity"] = perplexity # 记录评估指标 trainer.log_metrics("eval", metrics) # 保存评估指标 trainer.save_metrics("eval", metrics)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。