Este repositorio contiene el código para explotar preguntas de Cloze para la clasificación de texto de pocos disparos e inferencia del lenguaje natural y no es solo el tamaño que importa: los modelos de lenguaje pequeño también son alumnos de pocos disparos. Los documentos introducen capacitación de explotación de patrones (PET), un procedimiento de capacitación semi-supervisado que reformula los ejemplos de insumos como frases de estilo Cloze. En entornos de baja recursos, PET e IPET superan significativamente la capacitación supervisada regular, varias líneas de base semi-supervisadas e incluso GPT-3 a pesar de requerir un 99.9% menos de parámetros. La variante iterativa de PET (IPET) entrena múltiples generaciones de modelos e incluso puede usarse sin ningún datos de entrenamiento.
| #Examples | Modo de entrenamiento | Yelp (completo) | Noticias de AG | Preguntas de Yahoo | Mnli |
|---|---|---|---|---|---|
| 0 | no supervisado | 33.8 | 69.5 | 44.0 | 39.1 |
| ipet | 56.7 | 87.5 | 70.7 | 53.6 | |
| 100 | supervisado | 53.0 | 86.0 | 62.9 | 47.9 |
| MASCOTA | 61.9 | 88.3 | 69.2 | 74.7 | |
| ipet | 62.9 | 89.6 | 71.2 | 78.4 |
Nota : Para reproducir exactamente los resultados anteriores, asegúrese de usar V1.1.0 ( --branch v1.1.0 ).
? Configuración
Uso de CLI
Uso de API
? Entrena a tu propia mascota
Citación
Todos los requisitos para PET se pueden encontrar en requirements.txt . Puede instalar todos los paquetes requeridos con pip install -r requirements.txt .
La interfaz de línea de comando cli.py en este repositorio actualmente admite tres modos de capacitación diferentes (PET, IPET, capacitación supervisada), dos métodos de evaluación adicionales (sin supervisión y cebado) y 13 tareas diferentes. Para Yelp Reviews, AG's News, Yahoo Preguntas, MNLI y X-Stance, consulte el documento original para obtener más detalles. Para las 8 tareas de Superglue, vea este documento.
Para entrenar y evaluar un modelo de mascota para una de las tareas compatibles, simplemente ejecute el siguiente comando:
python3 cli.py
--method pet
--pattern_ids $PATTERN_IDS
--data_dir $DATA_DIR
--model_type $MODEL_TYPE
--model_name_or_path $MODEL_NAME_OR_PATH
--task_name $TASK
--output_dir $OUTPUT_DIR
--do_train
--do_eval
dónde
$PATTERN_IDS especifica los PVPS para usar. Por ejemplo, si desea utilizar todos los patrones, especifique PATTERN_IDS 0 1 2 3 4 para las preguntas de AG y Yahoo PREGUNTES o PATTERN_IDS 0 1 2 3 para las revisiones de Yelp y MNLI.$DATA_DIR es el directorio que contiene el tren y los archivos de prueba (verifique tasks.py para ver cómo estos archivos deben ser nombrados y formateados para cada tarea).$MODEL_TYPE es el nombre del modelo que se está utilizando, por ejemplo, albert , bert o roberta .$MODEL_NAME es el nombre de un modelo previamente (por ejemplo, roberta-large o albert-xxlarge-v2 ) o la ruta hacia un modelo previamente practicado.$TASK_NAME es el nombre de la tarea para entrenar y evaluar.$OUTPUT_DIR es el nombre del directorio en el que se guardan los resultados del modelo y la evaluación capacitados. Además, puede especificar varios parámetros de entrenamiento tanto para el conjunto de modelos PET correspondientes a PVPS individuales (prefijo --pet_ ) como para el modelo de clasificación de secuencia final (prefijo --sc_ ). Por ejemplo, los parámetros predeterminados utilizados para nuestra evaluación de supergeglue son:
--pet_per_gpu_eval_batch_size 8
--pet_per_gpu_train_batch_size 2
--pet_gradient_accumulation_steps 8
--pet_max_steps 250
--pet_max_seq_length 256
--pet_repetitions 3
--sc_per_gpu_train_batch_size 2
--sc_per_gpu_unlabeled_batch_size 2
--sc_gradient_accumulation_steps 8
--sc_max_steps 5000
--sc_max_seq_length 256
--sc_repetitions 1
Para cada patrón $P y repetición $I , ejecutar el comando anterior crea un directorio $OUTPUT_DIR/p$Pi$I que contiene los siguientes archivos:
pytorch_model.bin : el modelo Finetuned, posiblemente junto con algunos archivos específicos del modelo (por ejemplo, spiece.model , special_tokens_map.json )wrapper_config.json : la configuración del modelo que se utilizatrain_config.json : la configuración utilizada para el entrenamientoeval_config.json : la configuración utilizada para la evaluaciónlogits.txt : las predicciones del modelo en los datos no etiquetadoseval_logits.txt : la predicción del modelo en los datos de evaluaciónresults.json : un archivo JSON que contiene resultados como la precisión final del modelopredictions.jsonl : un archivo de predicción para el conjunto de evaluación establecido en formato de supergeglue El modelo final (destilado) para cada repetición $I se puede encontrar en $OUTPUT_DIR/final/p0-i$I , que contiene los mismos archivos que se describen anteriormente.
Si su GPU se queda fuera de la memoria durante el entrenamiento, puede intentar disminuir tanto el pet_per_gpu_train_batch_size como el sc_per_gpu_unlabeled_batch_size mientras aumentan pet_gradient_accumulation_steps y sc_gradient_accumulation_steps .
Para entrenar y evaluar un modelo IPET para una de las tareas compatibles, simplemente ejecute el mismo comando que el anterior, pero reemplace --method pet con --method ipet . Hay varios parámetros IPET adicionales que puede modificar; Todos ellos tienen el prefijo con --ipet_ .
Para cada generación $G , Patrón $P e iteración $I , esto crea un directorio $OUTPUT_DIR/g$G/p$Pi$I que está estructurado como para las mascotas regulares. El modelo final (destilado) se puede encontrar nuevamente en $OUTPUT_DIR/final/p0-i$I .
Si usa IPET con cero ejemplos de entrenamiento, debe especificar cuántos ejemplos para cada etiqueta deben elegirse en la primera generación y debe cambiar la estrategia de reducción para significar: --ipet_n_most_likely 100 --reduction mean .
Para entrenar y evaluar un clasificador de secuencia regular de manera supervisada, simplemente ejecute el mismo comando que el anterior, pero reemplace --method pet con --method sequence_classifier . Hay varios parámetros adicionales para el clasificador de secuencia que puede modificar; Todos ellos tienen el prefijo --sc_ .
Para evaluar un modelo de lenguaje previo a la aparición con los patrones y verbalizadores de PET predeterminados, pero sin ajuste, elimine el argumento --do_train y agregue --no_distillation para que no se realice una destilación final.
Si desea usar el cebado, elimine el argumento --do_train y agregue los argumentos --priming --no_distillation para que todos los ejemplos de entrenamiento se usen para el cebado y no se realice una destilación final.
Recuerde que es posible que deba aumentar la longitud de secuencia máxima a un valor mucho mayor, por ejemplo, --pet_max_seq_length 5000 . Esto solo funciona con modelos de lenguaje que admiten secuencias tan largas, por ejemplo, XLNet. Para usar xlnet, puede especificar --model_type xlnet --model_name_or_path xlnet-large-cased --wrapper_type plm .
En lugar de usar la interfaz de línea de comando, también puede usar directamente la API PET, la mayoría de las cuales se define en pet.modeling . Al incluir import pet , puede acceder a métodos como train_pet , train_ipet y train_classifier . Consulte su documentación para obtener más información.
Para usar PET para tareas personalizadas, debe definir dos cosas:
examples/custom_task_processor.py para un ejemplo.examples/custom_task_pvp.py para un ejemplo.Después de haber implementado el DataproCessor y el PVP, puede capacitar a un modelo de mascotas utilizando la línea de comandos como se describió anteriormente. A continuación, puede encontrar información adicional sobre cómo definir los dos componentes de un PVP, verbalizadores y patrones .
Los verbalizadores se utilizan para asignar etiquetas de tareas a palabras en lenguaje natural. Por ejemplo, en una tarea de clasificación de sentimientos binarios, puede asignar la etiqueta positiva ( +1 ) a la palabra good y la etiqueta negativa ( -1 ) a la palabra bad . Los verbalizadores se realizan a través del método de verbalize() de un PVP. La forma más simple de definir un verbalizador es usar un diccionario:
VERBALIZER = { "+1" : [ "good" ], "-1" : [ "bad" ]}
def verbalize ( self , label ) -> List [ str ]:
return self . VERBALIZER [ label ] Es importante destacar que, en la versión actual de PET, los verbalizadores están restringidos, por defecto, a tokens individuales en el vocabulario LMS subyacente (para usar más de un token, ver más abajo). Dado el tokenizador de un modelo de idioma, puede verificar fácilmente si una palabra corresponde a un solo token verificando ese len(tokenizer.tokenize(word)) == 1 .
También puede definir múltiples verbalizaciones para una sola etiqueta. Por ejemplo, si no está seguro de qué palabras representan mejor las etiquetas en una tarea de clasificación de sentimientos binarios, puede definir su verbalizador de la siguiente manera:
VERBALIZER = { "+1" : [ "great" , "good" , "wonderful" , "perfect" ], "-1" : [ "bad" , "terrible" , "horrible" ]} Los patrones se utilizan para que el modelo de idioma comprenda una tarea dada; Deben contener exactamente un token <MASK> que se llenará con el verbalizador. Para la clasificación de sentimientos binarios basados en el resumen de una revisión ( <A> ) y el cuerpo ( <B> ), un patrón adecuado puede ser <A>. <B>. Overall, it was <MASK>. Los patrones se realizan a través del método get_parts() de PVP, que devuelve un par de secuencias de texto (donde cada secuencia está representada por una lista de cadenas):
def get_parts ( self , example : InputExample ):
return [ example . text_a , '.' , example . text_b , '.' ], [ 'Overall, it was ' , self . mask ]Si no desea usar un par de secuencias, simplemente puede dejar la segunda secuencia vacía:
def get_parts ( self , example : InputExample ):
return [ example . text_a , '.' , example . text_b , '. Overall, it was ' , self . mask ], [] Si desea definir varios patrones, simplemente use el atributo PVP S pattern_id :
def get_parts ( self , example : InputExample ):
if self . pattern_id == 1 :
return [ example . text_a , '.' , example . text_b , '.' ], [ 'Overall, it was ' , self . mask ]
elif self . pattern_id == 2 :
return [ 'It was just ' , self . mask , '!' , example . text_a , '.' , example . text_b , '.' ], [] Al entrenar el modelo que usa la línea de comando, especifique todos los patrones que se utilizarán (por ejemplo, --pattern_ids 1 2 ).
Es importante destacar que si una secuencia es más larga que la longitud de secuencia máxima especificada de la LM subyacente, PET debe saber qué partes de la entrada se pueden acortar y cuáles no (por ejemplo, el token de la máscara siempre debe estar allí). Por lo tanto, PVP proporciona un método shortenable() para indicar que se puede acortar una pieza de texto:
def get_parts ( self , example : InputExample ):
text_a = self . shortenable ( example . text_a )
text_b = self . shortenable ( example . text_b )
return [ text_a , '.' , text_b , '. Overall, it was ' , self . mask ], []Por defecto, la implementación actual de PET e IPET solo admite un conjunto fijo de etiquetas que se comparte en todos los ejemplos y verbalizadores que corresponden a un solo token. Sin embargo, para algunas tareas puede ser necesario usar verbalizadores que corresponden a múltiples tokens (como se describe aquí). Para hacerlo, simplemente necesita las siguientes dos modificaciones:
Agregue las siguientes líneas en el DataProcessor de su tarea (consulte examples/custom_task_processor.py ):
from pet . tasks import TASK_HELPERS
from pet . task_helpers import MultiMaskTaskHelper
TASK_HELPERS [ 'my_task' ] = MultiMaskTaskHelper donde 'my_task' es el nombre de su tarea.
En su PVP , asegúrese de que el método get_parts() siempre inserta el número máximo de tokens de máscara requeridos para cualquier verbalización. Por ejemplo, si su verbalizador se asigna +1 a "realmente impresionante" y -1 a "terrible" y si se tocan como ["really", "awe", "##some"] y ["terrible"] , respectivamente, su método get_parts() siempre debe devolver una secuencia que contiene exactamente 3 tokens.
Con esta modificación, ahora puede usar verbalizadores que consisten en múltiples tokens:
VERBALIZER = { "+1" : [ "really good" ], "-1" : [ "just bad" ]}Sin embargo, hay varias limitaciones a considerar:
MultiMaskTaskHelper , el tamaño máximo de lotes para la evaluación es 1.MultiMaskTaskHelper es una característica experimental que no se prueba a fondo. En particular, esta característica solo se ha probado para PET y no para IPET. Si observa algo extraño, plantee un problema. Para obtener más flexibilidad, también puede escribir un TaskHelper personalizado. Como punto de partida, puede consultar las clases CopaTaskHelper , WscTaskHelper y RecordTaskHelper en pet/task_helpers.py .
Si utiliza el código en este repositorio, cite los siguientes documentos:
@article{schick2020exploiting,
title={Exploiting Cloze Questions for Few-Shot Text Classification and Natural Language Inference},
author={Timo Schick and Hinrich Schütze},
journal={Computing Research Repository},
volume={arXiv:2001.07676},
url={http://arxiv.org/abs/2001.07676},
year={2020}
}
@article{schick2020small,
title={It's Not Just Size That Matters: Small Language Models Are Also Few-Shot Learners},
author={Timo Schick and Hinrich Schütze},
journal={Computing Research Repository},
volume={arXiv:2009.07118},
url={http://arxiv.org/abs/2009.07118},
year={2020}
}