Compartir tecnología

Disposición simple de [Evaluar PEGASUS] / [Ajustar PEGASUS] / [Generar resumen de conversación] de [Resumen de texto] de la [Cara de abrazo] de AGI

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Disposición simple de [Evaluar PEGASUS] / [Ajustar PEGASUS] / [Generar resumen de conversación] de [Resumen de texto] de la [Cara de abrazo] de AGI

Tabla de contenido

Disposición simple de [Evaluar PEGASUS] / [Ajustar PEGASUS] / [Generar resumen de conversación] de [Resumen de texto] de la [Cara de abrazo] de AGI

1. Breve introducción

2. Resumen del texto

3. Evalúe PEGASUS en el conjunto de datos de CNN/DailyMail

4. Modelo de resumen de formación

1. Evaluar el desempeño de PEGASUS en SAMSum

2. Afinar PEGASO

3. Generar resumen de conversación


1. Breve introducción

AGI, o Inteligencia General Artificial, es un sistema de inteligencia artificial con niveles de inteligencia humana. No sólo puede realizar tareas específicas, sino también comprender, aprender y aplicar conocimientos para resolver una amplia gama de problemas, con alta autonomía y adaptabilidad. Las capacidades de AGI incluyen, entre otras, el autoaprendizaje, la superación personal, el autoajuste y la capacidad de resolver diversos problemas complejos sin intervención humana.

  • Lo que AGI puede hacer es muy amplio:

Ejecución de tareas entre dominios: AGI puede manejar tareas en múltiples dominios y no se limita a escenarios de aplicaciones específicos.
Aprendizaje y adaptación autónomos: AGI puede aprender de la experiencia y adaptarse a nuevos entornos y situaciones.
Pensamiento creativo: AGI es capaz de pensar de forma innovadora y proponer nuevas soluciones.
Interacción social: AGI es capaz de realizar interacciones sociales complejas con humanos y comprende señales emocionales y sociales.

  • En cuanto a las perspectivas de desarrollo futuro de AGI, se considera uno de los objetivos finales de la investigación en inteligencia artificial y tiene un enorme potencial de cambio:

Innovación tecnológica: con el avance de tecnologías como el aprendizaje automático y las redes neuronales, la realización de AGI puede estar cada vez más cerca.
Integración interdisciplinaria: la implementación de AGI requiere integrar conocimientos de múltiples disciplinas como la informática, la neurociencia y la psicología.
Consideraciones éticas y sociales: el desarrollo de AGI requiere la consideración de cuestiones éticas y sociales como la privacidad, la seguridad y el empleo.
Capacidades mejoradas de aprendizaje y adaptación: los futuros sistemas AGI pueden utilizar algoritmos avanzados para aprender del entorno y optimizar el comportamiento.
Interacción multimodal: AGI tendrá múltiples métodos de percepción e interacción para interactuar con humanos y otros sistemas.

Como una de las comunidades y plataformas de aprendizaje automático de código abierto más populares del mundo, Hugging Face desempeña un papel importante en la era AGI. Proporciona abundantes recursos de modelos y conjuntos de datos previamente entrenados, lo que promueve el desarrollo del campo del aprendizaje automático. Hugging Face se caracteriza por su facilidad de uso y apertura. A través de su biblioteca Transformers, proporciona a los usuarios una forma conveniente para que los modelos procesen texto. Con el desarrollo de la tecnología de IA, la comunidad de Hugging Face seguirá desempeñando un papel importante en la promoción del desarrollo y la aplicación de la tecnología de IA, especialmente en el desarrollo de tecnología de IA multimodal. La comunidad de Hugging Face ampliará la diversidad de sus modelos. y conjuntos de datos, incluidos datos multimodales como imágenes, audio y vídeo.

  • En la era de AGI, Hugging Face podría entrar en juego de las siguientes maneras:

Intercambio de modelos: como plataforma para compartir modelos, Hugging Face continuará promoviendo el intercambio y la colaboración de modelos AGI avanzados.
Ecosistema de código abierto: el ecosistema de código abierto de Hugging Face ayudará a acelerar el desarrollo y la innovación de la tecnología AGI.
Herramientas y servicios: proporcione una gran cantidad de herramientas y servicios para apoyar a los desarrolladores e investigadores en sus investigaciones y aplicaciones en el campo AGI.
Ética y responsabilidad social: Hugging Face se centra en la ética de la IA y promoverá el desarrollo y la aplicación de modelos AGI responsables para garantizar el progreso tecnológico cumpliendo con los estándares éticos.

AGI, como forma avanzada de inteligencia artificial en el futuro, tiene amplias perspectivas de aplicación, y Hugging Face, como comunidad de código abierto, desempeñará un papel clave en la promoción del desarrollo y la aplicación de AGI.

(Nota: el siguiente código puede requerir acceso científico a Internet para ejecutarse)

2. Resumen del texto

Es posible que haya tenido que resumir un documento, incluido un artículo de investigación, un informe de ganancias financieras o una serie de correos electrónicos. Si lo piensas bien, esto requiere una variedad de habilidades, incluida la comprensión de contenido extenso, razonar sobre él y luego producir un texto fluido que abarque los temas principales del documento original. Además, resumir con precisión un artículo de noticias es muy diferente de resumir un contrato legal y, por lo tanto, requiere capacidades complejas de generalización de dominio. Por estas razones, resumir texto (el término técnico es resumen de texto) es una tarea difícil para los modelos de lenguaje neuronal, incluidos los modelos Transformer. A pesar de estos desafíos, el resumen de texto puede acelerar significativamente el flujo de trabajo de los expertos en el dominio. Las empresas pueden utilizar el resumen de texto para condensar el conocimiento interno, resumir contratos, generar automáticamente contenido de publicación en redes sociales, etc. Por lo tanto, la tarea de PNL de resumen de texto es valiosa.

Para ayudarlo a comprender los desafíos, esta sección explora cómo aprovechar los modelos previamente entrenados de Transformer para el resumen de texto. El resumen es una tarea clásica de secuencia a secuencia (seq2seq) que requiere entrada de texto y texto de destino.

El resumen de texto es una tarea de procesamiento del lenguaje natural cuyo objetivo es extraer información concisa e importante de un texto largo y generar una versión corta. El resumen de texto se puede dividir en dos tipos principales: resumen extractivo y resumen generativo.

  • Resumen extractivo

El resumen extractivo selecciona oraciones o párrafos importantes del texto original y extrae directamente estos contenidos como resúmenes. Este método no cambia las palabras ni la estructura de las oraciones en el texto original.

Principio de implementación:

  1. Extracción de características: primero, es necesario extraer varias características del texto, como la frecuencia de las palabras, la posición de la oración, las palabras clave, las entidades nombradas, etc.
  2. Puntuación de importancia: en función de las características extraídas, se calcula una puntuación para cada oración para determinar su importancia.
  3. Selección de oraciones: en función de la puntuación de importancia, se seleccionan las oraciones más importantes para construir el resumen.

dificultad:

  1. Medición de importancia: cómo medir con precisión la importancia relativa de las oraciones.
  2. Eliminación de redundancia: evite seleccionar oraciones con contenido repetido.

Método para realizar:

  1. Enfoque basado en reglas: utiliza reglas predefinidas y métodos estadísticos para seleccionar oraciones.
  2. Método de aprendizaje automático: utilice algoritmos de aprendizaje supervisado para aprender a seleccionar oraciones importantes en función de los datos de entrenamiento.
  • resumen generativo

El resumen generativo funciona comprendiendo el texto original y generando nuevas oraciones para resumir su contenido. Este enfoque crea un resumen más natural y coherente, pero también es más complejo.

Principio de implementación:

  1. Arquitectura codificador-decodificador: utiliza un modelo de secuencia a secuencia (Seq2Seq), donde el codificador codifica el texto de entrada en vectores de contexto y el decodificador genera resúmenes basados ​​en los vectores de contexto.
  2. Mecanismo de atención: durante el proceso de decodificación, el modelo puede centrarse en diferentes partes del texto de entrada para generar contenido más relevante.
  3. Modelo previamente entrenado: utilice modelos de lenguaje previamente entrenados (como BERT, GPT, etc.) para mejorar la calidad de los resúmenes generados.

dificultad:

  1. Coherencia del contenido: el resumen generado debe mantener una coherencia lógica y evitar interrupciones en el contenido.
  2. Integridad de la información: Garantiza que el resumen generado contenga información clave del texto original.
  3. Complejidad del modelo: los modelos de resumen generativos son generalmente más complejos que los modelos de resumen extractivos y requieren más recursos informáticos y datos de entrenamiento.

Método para realizar:

  1. Modelo clásico Seq2Seq: como el modelo codificador-decodificador basado en LSTM.
  2. Modelos de transformadores previamente entrenados: como BERTSUM, T5, BART, etc.
  • Resumen de texto en Hugging Face

Hugging Face proporciona una variedad de modelos y herramientas previamente entrenados para implementar fácilmente tareas de resumen de texto. Los siguientes son algunos modelos de resumen de texto comúnmente utilizados y cómo usarlos:

  1. Resumen utilizando modelos previamente entrenados

El siguiente es un código de muestra para el resumen de texto utilizando el modelo BART proporcionado por Hugging Face:

  1. from transformers import BartForConditionalGeneration, BartTokenizer
  2. # 加载预训练的BART模型和对应的tokenizer
  3. model_name = "facebook/bart-large-cnn"
  4. model = BartForConditionalGeneration.from_pretrained(model_name)
  5. tokenizer = BartTokenizer.from_pretrained(model_name)
  6. # 输入文本
  7. input_text = """Your text to summarize goes here."""
  8. # 对输入文本进行tokenize,并添加必要的模型输入
  9. inputs = tokenizer([input_text], max_length=1024, return_tensors='pt')
  10. # 使用模型生成摘要
  11. summary_ids = model.generate(inputs['input_ids'], num_beams=4, max_length=150, early_stopping=True)
  12. # 将生成的token序列转换回文本
  13. summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True)
  14. print(summary)
  1. Modelos de resumen soportados

Hugging Face proporciona una variedad de modelos previamente entrenados para el resumen de texto, que incluyen, entre otros:

  1. BART (facebook/bart-large-cnn)
  2. T5 (t5-pequeño, t5-base, t5-grande, t5-3b, t5-11b)
  3. PEGASO (google/pegasus-xsum, google/pegasus-cnn_dailymail)
  • Entrena tu propio modelo de resumen

Si necesita adaptarse mejor a las tareas de resumen de texto específicas de un dominio, puede ajustar el modelo previamente entrenado utilizando su propio conjunto de datos. A continuación se muestra un ejemplo sencillo de ajuste fino:

  1. from transformers import Trainer, TrainingArguments, BartForConditionalGeneration, BartTokenizer
  2. from datasets import load_dataset
  3. # 加载数据集
  4. dataset = load_dataset("cnn_dailymail", "3.0.0")
  5. # 加载预训练的BART模型和tokenizer
  6. model_name = "facebook/bart-large-cnn"
  7. model = BartForConditionalGeneration.from_pretrained(model_name)
  8. tokenizer = BartTokenizer.from_pretrained(model_name)
  9. # 数据预处理
  10. def preprocess_function(examples):
  11. inputs = [doc for doc in examples['article']]
  12. model_inputs = tokenizer(inputs, max_length=1024, truncation=True)
  13. # 设定摘要作为目标
  14. with tokenizer.as_target_tokenizer():
  15. labels = tokenizer(examples['highlights'], max_length=150, truncation=True)
  16. model_inputs['labels'] = labels['input_ids']
  17. return model_inputs
  18. tokenized_dataset = dataset.map(preprocess_function, batched=True)
  19. # 定义训练参数
  20. training_args = TrainingArguments(
  21. output_dir="./results",
  22. evaluation_strategy="epoch",
  23. learning_rate=2e-5,
  24. per_device_train_batch_size=4,
  25. per_device_eval_batch_size=4,
  26. num_train_epochs=3,
  27. weight_decay=0.01,
  28. )
  29. # 使用Trainer进行训练
  30. trainer = Trainer(
  31. model=model,
  32. args=training_args,
  33. train_dataset=tokenized_dataset["train"],
  34. eval_dataset=tokenized_dataset["validation"],
  35. )
  36. trainer.train()

El resumen de texto es una tarea de procesamiento del lenguaje natural compleja y desafiante. Al utilizar los modelos y herramientas previamente entrenados proporcionados por Hugging Face, el proceso de implementación del resumen de texto se puede simplificar enormemente. Los usuarios pueden seleccionar el modelo apropiado según las necesidades específicas y ajustarlo para obtener el mejor efecto resumido.

En esta sección, construiremos nuestro propio modelo de codificador-decodificador para comprimir conversaciones de varias personas en resúmenes concisos. Pero antes de eso, echemos un vistazo a un conjunto de datos clásico en el campo de resumen: el corpus CNN/DailyMail.

tres,nortenorte/DaiyoyMETROETROaiyonúmerode acuerdo acolocarsuperiorcomentarioestimarPAGAGAGmiGRAMORAMORAMOASS

Ahora tenemos todo lo que necesitamos para evaluar completamente el modelo: tenemos el conjunto de datos del conjunto de pruebas de CNN/DailyMail, la métrica ROUGE para evaluación y un modelo resumido.

  1. # 导入所需的库
  2. import matplotlib.pyplot as plt # 导入 matplotlib.pyplot,用于绘制图形
  3. import pandas as pd # 导入 pandas,用于数据处理
  4. from datasets import load_dataset, load_metric # 从 datasets 库中导入 load_dataset 和 load_metric 函数
  5. from transformers import AutoModelForSeq2SeqLM, AutoTokenizer # 从 transformers 库中导入 AutoModelForSeq2SeqLM 和 AutoTokenizer
  6. # 加载 CNN/DailyMail 数据集,版本为 3.0.0
  7. dataset = load_dataset("cnn_dailymail", "3.0.0")
  8. # 加载 ROUGE 评价指标,用于计算文本摘要的质量
  9. rouge_metric = load_metric("rouge", cache_dir=None)
  10. # 定义要计算的 ROUGE 分数的名称列表
  11. rouge_names = ["rouge1", "rouge2", "rougeL", "rougeLsum"]

Sólo tenemos que juntar las piezas. Primero, evaluamos el desempeño del modelo de referencia de tres oraciones:

  1. # 定义一个函数,用于评估基线模型生成的摘要
  2. def evaluate_summaries_baseline(dataset, metric, column_text="article", column_summary="highlights"):
  3. # 使用 three_sentence_summary 函数对数据集中的每篇文章生成摘要
  4. summaries = [three_sentence_summary(text) for text in dataset[column_text]]
  5. # 将生成的摘要和参考摘要添加到评价指标中
  6. metric.add_batch(predictions=summaries, references=dataset[column_summary])
  7. # 计算评价指标的分数
  8. score = metric.compute()
  9. # 返回评价指标的分数
  10. return score

Luego aplicamos la función a un subconjunto de datos. Dado que la parte de prueba del conjunto de datos de CNN/DailyMail contiene aproximadamente 10.000 muestras, generar resúmenes de todos estos artículos lleva mucho tiempo. Recuerde del Capítulo 5 que cada token generado debe pasarse hacia adelante a través del modelo. Generar 100 tokens por muestra requeriría 1 millón de pases hacia adelante y, si usáramos la búsqueda de haces, este número también tendría que multiplicarse por el número de haces. Para agilizar el cálculo, submuestrearemos el conjunto de prueba y, en última instancia, utilizaremos 1000 muestras para la evaluación. De esta manera, podemos completar la evaluación del modelo PEGASUS en menos de una hora en una sola GPU y obtener estimaciones de puntuación estables:

  1. # 从测试集中随机抽取1000条样本,用于评估
  2. test_sampled = dataset["test"].shuffle(seed=42).select(range(1000))
  3. # 使用基线模型生成摘要并评估其质量
  4. score = evaluate_summaries_baseline(test_sampled, rouge_metric)
  5. # 将评价指标的分数存储在字典中
  6. rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
  7. # 将评价指标的分数转换为DataFrame格式,并转置以便显示
  8. pd.DataFrame.from_dict(rouge_dict, orient="index", columns=["baseline"]).T

resultado de la operación:

 rojo1rojo2rojoLsuma roja
base0.389280.1712960.2450610.354239

Las puntuaciones son en su mayoría peores que las del ejemplo anterior, ¡pero aún mejores que las logradas por GPT-2! Ahora seguimos el mismo patrón para evaluar el modelo PEGASUS:

  1. # 导入 tqdm 模块,用于显示进度条
  2. from tqdm import tqdm
  3. # 导入 torch 模块,用于使用 GPU 或 CPU 进行计算
  4. import torch
  5. # 设置设备为 GPU(如果可用)或 CPU
  6. device = "cuda" if torch.cuda.is_available() else "cpu"
  7. def chunks(list_of_elements, batch_size):
  8. """将 list_of_elements 按 batch_size 切分成多个小块"""
  9. for i in range(0, len(list_of_elements), batch_size):
  10. yield list_of_elements[i : i + batch_size]
  11. def evaluate_summaries_pegasus(dataset, metric, model, tokenizer,
  12. batch_size=16, device=device,
  13. column_text="article",
  14. column_summary="highlights"):
  15. """评估使用 Pegasus 模型生成的摘要"""
  16. # 将文章和摘要分别按 batch_size 切分成多个小块
  17. article_batches = list(chunks(dataset[column_text], batch_size))
  18. target_batches = list(chunks(dataset[column_summary], batch_size))
  19. # 使用 tqdm 显示进度条,遍历每个文章批次和相应的摘要批次
  20. for article_batch, target_batch in tqdm(
  21. zip(article_batches, target_batches), total=len(article_batches)):
  22. # 对文章批次进行标记,将其转换为模型输入的张量
  23. inputs = tokenizer(article_batch, max_length=1024, truncation=True,
  24. padding="max_length", return_tensors="pt")
  25. # 使用 Pegasus 模型生成摘要
  26. summaries = model.generate(input_ids=inputs["input_ids"].to(device),
  27. attention_mask=inputs["attention_mask"].to(device),
  28. length_penalty=0.8, num_beams=8, max_length=128)
  29. # 解码生成的摘要,将其从张量转换为字符串
  30. decoded_summaries = [tokenizer.decode(s, skip_special_tokens=True,
  31. clean_up_tokenization_spaces=True)
  32. for s in summaries]
  33. decoded_summaries = [d.replace("", " ") for d in decoded_summaries]
  34. # 将生成的摘要和目标摘要添加到评价指标中
  35. metric.add_batch(predictions=decoded_summaries, references=target_batch)
  36. # 计算评价指标分数
  37. score = metric.compute()
  38. return score

Expliquemos este código de evaluación en detalle. Primero, dividimos el conjunto de datos en lotes más pequeños para que puedan procesarse simultáneamente. Luego, para cada lote, tokenizamos los artículos de entrada y los alimentamos a la función generate() para generar resúmenes mediante la búsqueda por haz. Utilizamos los mismos parámetros de generación que en el artículo. La nueva longitud del parámetro de penalización garantiza que el modelo no genere secuencias demasiado largas.Finalmente, decodificamos el texto generado, reemplazando<n> tokens y agregue el texto decodificado a la métrica junto con el texto de referencia. Finalmente, calculamos y devolvemos la puntuación de ROUGE. Ahora volvemos a utilizar la clase AutoModelForSeq2SeqLM para la tarea de generación de seq2seq para cargar el modelo y evaluarlo:

  1. # 从 transformers 库中导入用于序列到序列任务的模型和标记器
  2. from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
  3. # 设置模型检查点名称,使用 Google 的 PEGASUS 模型,预训练于 CNN/DailyMail 数据集
  4. model_ckpt = "google/pegasus-cnn_dailymail"
  5. # 从预训练的模型检查点中加载标记器和模型,并将模型移动到指定的设备(CPU 或 GPU)
  6. tokenizer = AutoTokenizer.from_pretrained(model_ckpt)
  7. model = AutoModelForSeq2SeqLM.from_pretrained(model_ckpt).to(device)
  8. # 使用评估函数 evaluate_summaries_pegasus 评估 PEGASUS 模型生成的摘要
  9. # 输入参数包括测试数据、ROUGE 评价指标、模型、标记器和批处理大小
  10. score = evaluate_summaries_pegasus(test_sampled, rouge_metric,
  11. model, tokenizer, batch_size=8)
  12. # 从评估结果中提取 ROUGE 分数,将其转换为字典格式,其中键为 ROUGE 指标名称,值为 F-measure 分数
  13. rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
  14. # 将 ROUGE 分数字典转换为 pandas 数据框,并以 "pegasus" 作为索引
  15. pd.DataFrame(rouge_dict, index=["pegasus"])

resultado de la operación:

(El error temporal se informa aquí:

TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto

, los resultados de ejecución como referencia utilizando ejemplos son los siguientes)

 rojo1rojo2rojoLsuma roja
Pegaso0.434380.2108830.3071950.373231

Estos números están muy cerca de los resultados del artículo. Lo importante a tener en cuenta aquí es que la pérdida y la precisión de cada token están algo desacopladas de la puntuación ROUGE. La pérdida es independiente de la estrategia de decodificación, mientras que la puntuación ROUGE está fuertemente acoplada.

Dado que ROUGE y BLEU logran una mejor pérdida o precisión que la evaluación humana, debe centrarse en ellos al crear modelos de generación de texto y explorar y seleccionar estrategias de decodificación con cuidado. Sin embargo, estas métricas están lejos de ser perfectas, por lo que siempre se debe considerar la evaluación humana.

Ahora que tenemos la función de evaluación, podemos entrenar nuestro propio modelo de resumen.

cuatro,capacitaciónprácticaelegirdesearmohotipo

En este punto, hemos analizado muchos detalles de resumen y evaluación de texto. ¡Ahora usamos este conocimiento para entrenar un modelo de resumen de texto personalizado! Para nuestra aplicación personalizada, utilizaremos el conjunto de datos SAMSum desarrollado por Samsung (yoaapags://oamiiyo.yoy/norte1gramoramogramoramoq ), este conjunto de datos contiene una serie de conversaciones y breves resúmenes. Estas conversaciones pueden representar interacciones entre clientes y centros de llamadas, generando resúmenes precisos para ayudar a mejorar el servicio al cliente y detectar patrones comunes en las solicitudes de los clientes. Primero carguemos el conjunto de datos y veamos una muestra:

  1. # 从 datasets 库中导入用于加载数据集的函数
  2. from datasets import load_dataset
  3. # 加载 SamSum 数据集,该数据集包含对话和相应的摘要
  4. dataset_samsum = load_dataset("samsum",trust_remote_code=True)
  5. # 获取数据集的每个划分(训练集、验证集、测试集)的长度,并存储在列表 split_lengths 中
  6. split_lengths = [len(dataset_samsum[split]) for split in dataset_samsum]
  7. # 打印每个数据集划分的长度
  8. print(f"Split lengths: {split_lengths}")
  9. # 打印训练集中列的名称(特征)
  10. print(f"Features: {dataset_samsum['train'].column_names}")
  11. # 打印测试集中第一个对话样本
  12. print("nDialogue:")
  13. print(dataset_samsum["test"][0]["dialogue"])
  14. # 打印测试集中第一个对话样本的摘要
  15. print("nSummary:")
  16. print(dataset_samsum["test"][0]["summary"])

(Nota: es posible que necesite instalar py7zr, pip install py7zr)

resultado de la operación:

Split lengths: [14732, 819, 818]
Features: ['id', 'dialogue', 'summary']

Dialogue:
Hannah: Hey, do you have Betty's number?
Amanda: Lemme check
Hannah: <file_gif>
Amanda: Sorry, can't find it.
Amanda: Ask Larry
Amanda: He called her last time we were at the park together
Hannah: I don't know him well
Hannah: <file_gif>
Amanda: Don't be shy, he's very nice
Hannah: If you say so..
Hannah: I'd rather you texted him
Amanda: Just text him 🙂
Hannah: Urgh.. Alright
Hannah: Bye
Amanda: Bye bye

Summary:
Hannah needs Betty's number but Amanda doesn't have it. She needs to contact Larry.

Las conversaciones se parecen a las que chatearías a través de mensajes de texto o WhatsApp, incluidos emojis y marcadores de posición para GIF. El campo de diálogo contiene el texto completo, mientras que el campo de resumen es un resumen del diálogo. ¿Puede un modelo ajustado en el conjunto de datos de CNN/DailyMail manejar este conjunto de datos? ¡Vamos a ver!

1 comentarioestimarPAGAGAGmiGRAMORAMORAMOASSexistirSAMETROETROSmetrosuperiordesexocapaz

Primero, ejecutaremos el mismo proceso de generación de resumen usando PEGASUS para ver el resultado. Podemos reutilizar el código generado por el resumen de CNN/DailyMail:

  1. # 使用已加载的summarization管道对测试集中的第一个对话样本进行摘要
  2. pipe_out = pipe(dataset_samsum["test"][0]["dialogue"])
  3. # 打印生成的摘要标题
  4. print("Summary:")
  5. # 打印生成的摘要文本,并将每个句子的句号后面的空格替换为换行符
  6. # 这行代码会输出生成的摘要,其中 ". " 替换为 ".n" 使其更易读
  7. print(pipe_out[0]["summary_text"].replace(" .", ".n"))

resultado de la operación:

Summary:
Hannah asks Amanda for Betty's number. Amanda can't find it. Hannah asks Larry. Amanda asks Larry to text him. Hannah says she'll text him back. Hannah calls it a day and says she's going to go home. Hannah: "Bye bye"

Podemos ver que el modelo intenta principalmente resumir extrayendo oraciones clave en la conversación. Esto puede funcionar relativamente bien en el conjunto de datos de CNN/DailyMail, pero en SAMSum, el resumen es más abstracto y el efecto no es necesariamente bueno. Podemos confirmar esto ejecutando la evaluación completa de ROUGE en el conjunto de prueba:

  1. # 使用评估函数 evaluate_summaries_pegasus 对 SamSum 数据集的测试集进行摘要生成评估
  2. # 传入的参数包括数据集、评价指标、模型、tokenizer、文本列名、摘要列名和批量大小
  3. score = evaluate_summaries_pegasus(dataset_samsum["test"], rouge_metric, model,
  4. tokenizer, column_text="dialogue",
  5. column_summary="summary", batch_size=8)
  6. # 创建一个字典 rouge_dict,用于存储 ROUGE 评分的中值 F-measure 值
  7. rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
  8. # 将 ROUGE 评分字典转换为 Pandas 数据框,并以 "pegasus" 为索引
  9. pd.DataFrame(rouge_dict, index=["pegasus"])

resultado de la operación:

(El error temporal se informa aquí:

TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto

, los resultados de ejecución como referencia utilizando ejemplos son los siguientes)

 rojo1rojo2rojoLsuma roja
Pegaso0.296170.0878030.2296040.229514

Aunque los resultados no son muy buenos, no es inesperado ya que está muy lejos de la distribución de datos de CNN/DailyMail. No obstante, establecer el proceso de evaluación antes de la capacitación tiene dos ventajas: podemos usar métricas directamente para medir el éxito de la capacitación y tenemos una buena base de referencia. Ajustar el modelo en nuestro conjunto de datos debería mejorar inmediatamente la métrica ROUGE; si no hay mejora, entonces sabemos que hay algún problema con nuestro ciclo de entrenamiento.

2.micromelodíaPAGAGAGmiGRAMORAMORAMOASS

Antes de entrenar con los datos, echamos un vistazo rápido a las distribuciones de longitud de entrada y salida:

  1. # 编码训练集中的对话文本和摘要,并计算其长度
  2. d_len = [len(tokenizer.encode(s)) for s in dataset_samsum["train"]["dialogue"]]
  3. s_len = [len(tokenizer.encode(s)) for s in dataset_samsum["train"]["summary"]]
  4. # 创建一个包含两个子图的图形对象
  5. fig, axes = plt.subplots(1, 2, figsize=(10, 3.5), sharey=True)
  6. # 绘制对话文本的长度分布直方图
  7. axes[0].hist(d_len, bins=20, color="C0", edgecolor="C0")
  8. axes[0].set_title("Dialogue Token Length")
  9. axes[0].set_xlabel("Length")
  10. axes[0].set_ylabel("Count")
  11. # 绘制摘要的长度分布直方图
  12. axes[1].hist(s_len, bins=20, color="C0", edgecolor="C0")
  13. axes[1].set_title("Summary Token Length")
  14. axes[1].set_xlabel("Length")
  15. # 调整子图布局,使其更加紧凑
  16. plt.tight_layout()
  17. # 显示绘制的图形
  18. plt.show()

resultado de la operación:

(El error temporal se informa aquí:

TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto

, los resultados de ejecución como referencia utilizando ejemplos son los siguientes)

Podemos ver que la mayoría de las conversaciones son mucho más cortas que los artículos de CNN/DailyMail, con alrededor de 100 a 200 tokens cada una. Asimismo, los resúmenes son mucho más cortos, entre 20 y 40 tokens (la misma longitud que un tweet promedio).

Recordemos estos resultados primero, los usaremos más tarde. Primero, necesitamos tokenizar el conjunto de datos. Establecemos la duración máxima del diálogo y el resumen en 1024 y 128 respectivamente:

  1. def convert_examples_to_features(example_batch):
  2. """
  3. 将示例批处理转换为模型输入特征。
  4. Args:
  5. - example_batch (dict): 包含对话和摘要的示例批处理字典。
  6. Returns:
  7. - dict: 包含转换后特征的字典,包括输入编码和目标编码。
  8. """
  9. # 对对话文本进行编码处理,生成输入编码
  10. input_encodings = tokenizer(example_batch["dialogue"], max_length=1024,
  11. truncation=True)
  12. # 使用目标编码器处理摘要文本,生成目标编码
  13. with tokenizer.as_target_tokenizer():
  14. target_encodings = tokenizer(example_batch["summary"], max_length=128,
  15. truncation=True)
  16. # 返回包含输入编码、目标标签和注意力掩码的字典
  17. return {
  18. "input_ids": input_encodings["input_ids"],
  19. "attention_mask": input_encodings["attention_mask"],
  20. "labels": target_encodings["input_ids"]
  21. }
  22. # 使用 map 方法将 SamSum 数据集转换为 PyTorch 格式
  23. dataset_samsum_pt = dataset_samsum.map(convert_examples_to_features,
  24. batched=True)
  25. # 设置数据集格式为 Torch 张量类型,并指定列名
  26. columns = ["input_ids", "labels", "attention_mask"]
  27. dataset_samsum_pt.set_format(type="torch", columns=columns)

resultado de la operación:

(El error temporal se informa aquí:

TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto)

Hay algo nuevo en el paso de tokenización: el contexto tokenizer.as_target_tokenizer(). Algunos modelos requieren tokens especiales en la entrada del decodificador, por lo que es importante separar los pasos de tokenización para las entradas del codificador y del decodificador. Dentro de una declaración with (llamada administrador de contexto), el tokenizador sabe que está tokenizando para el decodificador.

Ahora necesitamos crear el organizador de datos. En la mayoría de los casos, podemos utilizar el clasificador predeterminado, que recopila todos los tensores en un lote y simplemente los apila. Para la tarea de resumen, no solo necesitamos apilar las entradas, sino también preparar los objetivos en el lado del decodificador. PEGASUS es un transformador codificador-decodificador y, por lo tanto, tiene una arquitectura clásica seq2seq. En una configuración seq2seq, un enfoque común es aplicar el forzado del profesor en el decodificador. Cuando se utiliza esta estrategia, el decodificador recibe tokens de entrada (igual que un modelo solo decodificador como GPT-2), que la anotación desplaza una posición hacia la derecha, además de la salida del codificador. Por lo tanto, al predecir el siguiente token, el decodificador obtendrá como entrada el valor verdadero desplazado una posición hacia la derecha, como se muestra en la siguiente tabla:

  1. # 示例文本序列和标签生成过程
  2. text = ['PAD', 'Transformers', 'are', 'awesome', 'for', 'text', 'summarization']
  3. # 初始化存储每步结果的列表
  4. rows = []
  5. # 循环生成每步的数据行
  6. for i in range(len(text)-1):
  7. rows.append({
  8. 'step': i+1, # 步骤号,从1开始
  9. 'decoder_input': text[:i+1], # 解码器输入序列,从文本开始到当前位置
  10. 'label': text[i+1] # 标签,当前位置的下一个词
  11. })
  12. # 创建数据帧,并以步骤号作为索引
  13. pd.DataFrame(rows).set_index('step')

resultado de la operación:

pasoentrada del decodificadoretiqueta
1[ALMOHADILLA]Transformadores
2[PAD, Transformadores]son
3[PAD, Transformers, son]impresionante
4[PAD, Transformers, son, increíbles]para
5[PAD, Transformers, son, increíbles, para]texto
6[PAD, Transformers, son, increíbles, para, texto]resumen

Lo movemos una posición hacia la derecha para que el decodificador solo vea la anotación correcta anterior, no las anotaciones actuales o futuras. Simplemente cambiar es suficiente porque el decodificador tiene un mecanismo de autoatención enmascarado que enmascara todas las entradas actuales y futuras.

Por lo tanto, al preparar el lote, configuramos la entrada al decodificador moviendo la anotación una posición hacia la derecha. Luego, nos aseguramos de que los tokens de relleno en la función de pérdida se ignoren configurándolos en -100 en la anotación. En realidad, no tenemos que realizar estos pasos manualmente porque DataCollatorForSeq2Seq lo hace todo por nosotros:

  1. # 导入 Seq2Seq 数据集整理器模块
  2. from transformers import DataCollatorForSeq2Seq
  3. # 创建 Seq2Seq 数据集整理器实例
  4. seq2seq_data_collator = DataCollatorForSeq2Seq(tokenizer, model=model)

Luego, como de costumbre, configuramos TrainingArguments para el entrenamiento:

  1. # 导入训练参数和训练器模块
  2. from transformers import TrainingArguments, Trainer
  3. # 定义训练参数
  4. training_args = TrainingArguments(
  5. output_dir='pegasus-samsum', # 模型输出目录
  6. num_train_epochs=1, # 训练的轮数
  7. warmup_steps=500, # 学习率预热步数
  8. per_device_train_batch_size=1, # 每个设备的训练批次大小
  9. per_device_eval_batch_size=1, # 每个设备的评估批次大小
  10. weight_decay=0.01, # 权重衰减率
  11. logging_steps=10, # 训练日志记录步数
  12. push_to_hub=True, # 是否推送到模型中心
  13. evaluation_strategy='steps', # 评估策略
  14. eval_steps=500, # 评估步数间隔
  15. save_steps=1e6, # 模型保存步数间隔
  16. gradient_accumulation_steps=16 # 梯度累积步数
  17. )

La diferencia con la configuración anterior es que esta vez hay un nuevo parámetro gradient_accumulation_steps. Como el modelo es muy grande, debemos establecer el tamaño del lote en 1. Sin embargo, los tamaños de lote demasiado pequeños pueden afectar la convergencia. Para resolver este problema, podemos utilizar un truco inteligente llamado acumulación de gradiente. Como sugiere el nombre, en lugar de calcular los gradientes para todo el lote a la vez, calculamos y agregamos los gradientes en lotes. Cuando hayamos agregado suficientes gradientes, ejecutamos un paso de optimización. Naturalmente, esto es más lento que hacerlo todo de una vez, pero nos ahorra mucha memoria de la GPU.

Ahora, iniciamos sesión en Hugging Face para poder enviar el modelo al Hub después del entrenamiento:

  1. from huggingface_hub import notebook_login
  2. notebook_login()

resultado de la operación:

Ahora tenemos todo lo que necesitamos para inicializar el entrenador, incluido el modelo, el tokenizador, los parámetros de entrenamiento, los organizadores de datos y los conjuntos de datos de entrenamiento y evaluación:

  1. from transformers import TrainingArguments, Trainer
  2. # 创建一个 Trainer 实例用于训练序列到序列模型。
  3. trainer = Trainer(
  4. model=model, # 要训练的序列到序列模型
  5. args=training_args, # 定义的训练参数
  6. tokenizer=tokenizer, # 用于预处理输入数据的分词器
  7. data_collator=seq2seq_data_collator, # 用于批处理数据的数据整理器
  8. train_dataset=dataset_samsum_pt["train"], # 训练数据集
  9. eval_dataset=dataset_samsum_pt["validation"] # 评估数据集
  10. )

resultado de la operación:

(El error temporal se informa aquí:

TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto)

Estamos listos para entrenar. Una vez que se completa el entrenamiento, podemos ejecutar la función de evaluación directamente en el conjunto de prueba para ver cómo se desempeñó el modelo:

  1. from transformers import TrainingArguments, Trainer
  2. # 开始训练模型
  3. trainer.train()
  4. # 使用评估函数评估 Pegasus 模型的摘要质量
  5. score = evaluate_summaries_pegasus(
  6. dataset_samsum["test"], rouge_metric, trainer.model, tokenizer,
  7. batch_size=2, column_text="dialogue", column_summary="summary")
  8. # 提取 ROUGE 指标结果
  9. rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
  10. # 创建 DataFrame 显示 ROUGE 指标
  11. pd.DataFrame(rouge_dict, index=[f"pegasus"])

resultado de la operación:

(El error temporal se informa aquí:

TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto

, los resultados de ejecución como referencia utilizando ejemplos son los siguientes)

 rojo1rojo2rojoLsuma roja
Pegaso0.427610.2005710.3406480.340738

Podemos ver que la puntuación ROUGE mejora significativamente con respecto al modelo sin ajuste fino, por lo que aunque el modelo anterior también fue entrenado para la generación de resúmenes, no se adaptó bien al nuevo dominio. Empujemos nuestro modelo a Hub:

  1. # 将训练完成的模型推送到 Hub 上
  2. trainer.push_to_hub("Training complete!")

A continuación usaremos este modelo para generar algunos resúmenes para nosotros.

También puede evaluar los resultados generados como parte de un ciclo de entrenamiento: use la extensión TrainingArguments llamada Seq2SeqTrainingArguments y especifique predict_with_generate=True. Pase esto a un Entrenador dedicado llamado Seq2SeqTrainer, que utiliza la función generate() en lugar de un pase directo del modelo para crear predicciones para su evaluación. ¡Darle una oportunidad!

3. Generarbienhablarelegirdesear

Al observar las puntuaciones de pérdida y ROUGE, el modelo parece mostrar una mejora significativa con respecto al modelo original entrenado solo en CNN/DailyMail. Un resumen generado a partir de una muestra del conjunto de prueba tiene este aspecto:

  1. import transformers
  2. # 设置transformers的日志级别为错误,以减少输出日志
  3. transformers.logging.set_verbosity_error()
  4. # 定义生成摘要时的参数
  5. gen_kwargs = {"length_penalty": 0.8, "num_beams": 8, "max_length": 128}
  6. # 从测试集中选择一个示例
  7. sample_text = dataset_samsum["test"][0]["dialogue"]
  8. reference = dataset_samsum["test"][0]["summary"]
  9. # 使用预训练的pegasus-samsum模型创建摘要管道
  10. pipe = pipeline("summarization", model="transformersbook/pegasus-samsum")
  11. # 输出对话和参考摘要
  12. print("Dialogue:")
  13. print(sample_text)
  14. print("nReference Summary:")
  15. print(reference)
  16. # 使用模型生成摘要并输出
  17. print("nModel Summary:")
  18. print(pipe(sample_text, **gen_kwargs)[0]["summary_text"])

resultado de la operación:

Dialogue:
Hannah: Hey, do you have Betty's number?
Amanda: Lemme check
Hannah: <file_gif>
Amanda: Sorry, can't find it.
Amanda: Ask Larry
Amanda: He called her last time we were at the park together
Hannah: I don't know him well
Hannah: <file_gif>
Amanda: Don't be shy, he's very nice
Hannah: If you say so..
Hannah: I'd rather you texted him
Amanda: Just text him 🙂
Hannah: Urgh.. Alright
Hannah: Bye
Amanda: Bye bye

Reference Summary:
Hannah needs Betty's number but Amanda doesn't have it. She needs to contact
Larry.

Model Summary:
Amanda can't find Betty's number. Larry called Betty last time they were at the
park together. Hannah wants Amanda to text Larry instead of calling Betty.

Esto es muy similar a un resumen de referencia. Parece que el modelo ha aprendido a sintetizar conversaciones en resúmenes en lugar de simplemente extraer pasajes. Ahora, para la prueba final: ¿Cómo funciona el modelo en entradas personalizadas?

  1. # 自定义对话示例
  2. custom_dialogue = """
  3. Thom: Hi guys, have you heard of transformers?
  4. Lewis: Yes, I used them recently!
  5. Leandro: Indeed, there is a great library by Hugging Face.
  6. Thom: I know, I helped build it ;)
  7. Lewis: Cool, maybe we should write a book about it. What do you think?
  8. Leandro: Great idea, how hard can it be?!
  9. Thom: I am in!
  10. Lewis: Awesome, let's do it together!
  11. """
  12. # 使用预训练的pegasus-samsum模型生成摘要,并输出摘要结果
  13. print(pipe(custom_dialogue, **gen_kwargs)[0]["summary_text"])

resultado de la operación:

Thom and Lewis wanted to write a book about transformers. They came up with the idea with the help of Hugging Face's Leandro. The book will be called "Transformers: The Power of Transformers" and will be published in 2015. The project is currently in the planning stages.

El resumen de conversación personalizado generado tiene sentido. Hace un buen trabajo al resumir aquello sobre lo que todos los participantes en la discusión querían escribir un libro juntos, en lugar de simplemente extraer una sola oración. Por ejemplo, combina las filas 3 y 4 en una combinación lógica.