#
Transformadores, ¿qué pueden hacer?

En esta sección, veremos qué pueden hacer los Transformadores y usaremos nuestra primera herramienta de la librería 🤗 Transformers: la función `pipeline()`.

👀 Ves el botón Open in Colab en la parte superior derecha? Haz clic en él para abrir un cuaderno de Google Colab con todos los ejemplos de código de esta sección. Este botón aparecerá en cualquier sección que tenga ejemplos de código.

Si quieres ejecutar los ejemplos localmente, te recomendamos revisar la configuración.

##
¡Los Transformadores están en todas partes!

Los Transformadores se usan para resolver todo tipo de tareas de PLN, como las mencionadas en la sección anterior. Aquí te mostramos algunas de las compañías y organizaciones que usan Hugging Face y Transformadores, que también contribuyen de vuelta a la comunidad al compartir sus modelos:

La librería 🤗 Transformers provee la funcionalidad de crear y usar estos modelos compartidos. El Hub de Modelos contiene miles de modelos preentrenados que cualquiera puede descargar y usar. ¡Tú también puedes subir tus propios modelos al Hub!

⚠️ El Hub de Hugging Face no se limita a Transformadores. ¡Cualquiera puede compartir los tipos de modelos o conjuntos de datos que quiera! ¡Crea una cuenta de huggingface.co para beneficiarte de todas las funciones disponibles!

Antes de ver cómo funcionan internamente los Transformadores, veamos un par de ejemplos sobre cómo pueden ser usados para resolver tareas de PLN.

##
Trabajando con pipelines

El objeto más básico en la librería 🤗 Transformers es la función `pipeline()`. Esta función conecta un modelo con los pasos necesarios para su preprocesamiento y posprocesamiento, permitiéndonos introducir de manera directa cualquier texto y obtener una respuesta inteligible:

    from transformers import pipeline

    classifier = pipeline("sentiment-analysis")
    classifier("I've been waiting for a HuggingFace course my whole life.")

    [{'label': 'POSITIVE', 'score': 0.9598047137260437}]

¡Incluso podemos pasar varias oraciones!

    classifier(
        ["I've been waiting for a HuggingFace course my whole life.", "I hate this so much!"]
    )

    [{'label': 'POSITIVE', 'score': 0.9598047137260437},
     {'label': 'NEGATIVE', 'score': 0.9994558095932007}]

Por defecto, este pipeline selecciona un modelo particular preentrenado que ha sido ajustado para el análisis de sentimientos en Inglés. El modelo se descarga y se almacena en el caché cuando creas el objeto `classifier`. Si vuelves a ejecutar el comando, se usará el modelo almacenado en caché y no habrá necesidad de descargarlo de nuevo.

Hay tres pasos principales que ocurren cuando pasas un texto a un pipeline:

1. El texto es preprocesado en un formato que el modelo puede entender.
2. La entrada preprocesada se pasa al modelo.
3. Las predicciones del modelo son posprocesadas, de tal manera que las puedas entender.

Algunos de los pipelines disponibles son:

- `feature-extraction` (obtener la representación vectorial de un texto)
- `fill-mask`
- `ner` (reconocimiento de entidades nombradas)
- `question-answering`
- `sentiment-analysis`
- `summarization`
- `text-generation`
- `translation`
- `zero-shot-classification`

¡Veamos algunas de ellas!

##
Clasificación *zero-shot*

Empezaremos abordando una tarea más compleja, en la que necesitamos clasificar textos que no han sido etiquetados. Este es un escenario común en proyectos de la vida real porque anotar texto usualmente requiere mucho tiempo y dominio del tema. Para este caso de uso, el pipeline `zero-shot-classification` es muy poderoso: permite que especifiques qué etiquetas usar para la clasificación, para que no dependas de las etiquetas del modelo preentrenado. Ya viste cómo el modelo puede clasificar una oración como positiva o negativa usando esas dos etiquetas — pero también puede clasificar el texto usando cualquier otro conjunto de etiquetas que definas.

    from transformers import pipeline

    classifier = pipeline("zero-shot-classification")
    classifier(
        "This is a course about the Transformers library",
        candidate_labels=["education", "politics", "business"],
    )

    {'sequence': 'This is a course about the Transformers library',
     'labels': ['education', 'business', 'politics'],
     'scores': [0.8445963859558105, 0.111976258456707, 0.043427448719739914]}

Este pipeline se llama zero-shot porque no necesitas ajustar el modelo con tus datos para usarlo. ¡Puede devolver directamente puntajes de probabilidad para cualquier lista de de etiquetas que escojas!

✏️ ¡Pruébalo! Juega con tus propias secuencias y etiquetas, y observa cómo se comporta el modelo.

##
Generación de texto

Ahora veamos cómo usar un pipeline para generar texto. La idea es que proporciones una indicación (prompt) y el modelo la va a completar automáticamente al generar el texto restante. Esto es parecido a la función de texto predictivo que está presente en muchos teléfonos. La generación de texto involucra aleatóriedad, por lo que es normal que no obtengas el mismo resultado que se muestra abajo.

    from transformers import pipeline

    generator = pipeline("text-generation")
    generator("In this course, we will teach you how to")

    [{'generated_text': 'In this course, we will teach you how to understand and use '
                        'data flow and data interchange when handling user data. We '
                        'will be working with one or more of the most commonly used '
                        'data flows — data flows of various types, as seen by the '
                        'HTTP'}]

Puedes controlar cuántas secuencias diferentes se generan con el argumento `num_return_sequences` y la longitud total del texto de salida con el argumento `max_length`.

✏️ ¡Pruébalo! Usa los argumentos `num_return_sequences` y `max_length` para generar dos oraciones de 15 palabras cada una.

##
Usa cualquier modelo del Hub en un pipeline

Los ejemplos anteriores usaban el modelo por defecto para cada tarea, pero también puedes escoger un modelo particular del Hub y usarlo en un pipeline para una tarea específica - por ejemplo, la generación de texto. Ve al Hub de Modelos y haz clic en la etiqueta correspondiente en la parte izquierda para mostrar únicamente los modelos soportados para esa tarea. Deberías ver una página como esta.

¡Intentemos con el modelo `distilgpt2`! Puedes cargarlo en el mismo pipeline de la siguiente manera:

    from transformers import pipeline

    generator = pipeline("text-generation", model="distilgpt2")
    generator(
        "In this course, we will teach you how to",
        max_length=30,
        num_return_sequences=2,
    )

    [{'generated_text': 'In this course, we will teach you how to manipulate the world and '
                        'move your mental and physical capabilities to your advantage.'},
     {'generated_text': 'In this course, we will teach you how to become an expert and '
                        'practice realtime, and with a hands on experience on both real '
                        'time and real'}]

Puedes refinar tu búsqueda de un modelo haciendo clic en las etiquetas de idioma y escoger uno que genere textos en otro idioma. El Hub de Modelos también contiene puntos de control (checkpoints) para modelos que soportan múltiples lenguajes.

Una vez has seleccionado un modelo haciendo clic en él, verás que hay un widget que te permite probarlo directamente en línea. De esta manera puedes probar rápidamente las capacidades del modelo antes de descargarlo.

✏️ ¡Pruébalo! Usa los filtros para encontrar un modelo de generación de texto para un idioma diferente. ¡Siéntete libre de jugar con el widget y úsalo en un pipeline!

###
La API de Inferencia

Todos los modelos pueden ser probados directamente en tu navegador usando la API de Inferencia, que está disponible en el sitio web de Hugging Face. Puedes jugar con el modelo directamente en esta página al pasar tu texto personalizado como entrada y ver cómo lo procesa.

La API de Inferencia que hace funcionar al widget también está disponible como un producto pago, algo útil si lo necesitas para tus flujos de trabajo. Dirígete a la página de precios para más detalles.

##
Llenado de ocultos (*Mask filling*)

El siguiente pipeline con el que vas a trabajar es `fill-mask`. La idea de esta tarea es llenar los espacios en blanco de un texto dado:

    from transformers import pipeline

    unmasker = pipeline("fill-mask")
    unmasker("This course will teach you all about <mask> models.", top_k=2)

    [{'sequence': 'This course will teach you all about mathematical models.',
      'score': 0.19619831442832947,
      'token': 30412,
      'token_str': ' mathematical'},
     {'sequence': 'This course will teach you all about computational models.',
      'score': 0.04052725434303284,
      'token': 38163,
      'token_str': ' computational'}]

El argumento `top_k` controla el número de posibilidades que se van a mostrar. Nota que en este caso el modelo llena la palabra especial `<mask>`, que se denomina comúnmente como mask token. Otros modelos pueden tener diferentes tokens, por lo que es una buena idea verificar la palabra especial adecuada cuando estés explorando diferentes modelos. Una manera de confirmar es revisar la palabra usada en el widget.

✏️ ¡Pruébalo! Busca el modelo `bert-base-cased` en el Hub e identifica su mask token en el widget de la API de Inferencia. ¿Qué predice este modelo para la oración que está en el ejemplo de `pipeline` anterior?

##
Reconocimiento de entidades nombradas

El reconocimiento de entidades nombradas (REN) es una tarea en la que el modelo tiene que encontrar cuáles partes del texto introducido corresponden a entidades como personas, ubicaciones u organizaciones. Veamos un ejemplo:

    from transformers import pipeline

    ner = pipeline("ner", grouped_entities=True)
    ner("My name is Sylvain and I work at Hugging Face in Brooklyn.")

    [{'entity_group': 'PER', 'score': 0.99816, 'word': 'Sylvain', 'start': 11, 'end': 18},
     {'entity_group': 'ORG', 'score': 0.97960, 'word': 'Hugging Face', 'start': 33, 'end': 45},
     {'entity_group': 'LOC', 'score': 0.99321, 'word': 'Brooklyn', 'start': 49, 'end': 57}
    ]

En este caso el modelo identificó correctamente que Sylvain es una persona (PER), Hugging Face una organización (ORG) y Brooklyn una ubicación (LOC).

Pasamos la opción `grouped_entities=True` en la función de creación del pipeline para decirle que agrupe las partes de la oración que corresponden a la misma entidad: Aquí el modelo agrupó correctamente “Hugging” y “Face” como una sola organización, a pesar de que su nombre está compuesto de varias palabras. De hecho, como veremos en el siguente capítulo, el preprocesamiento puede incluso dividir palabras en partes más pequeñas. Por ejemplo, ‘Sylvain’ se separa en cuatro piezas: `S`, `##yl`, `##va` y`##in`. En el paso de prosprocesamiento, el pipeline reagrupa de manera exitosa dichas piezas.

✏️ ¡Pruébalo! Busca en el Model Hub un modelo capaz de hacer etiquetado part-of-speech (que se abrevia usualmente como POS) en Inglés. ¿Qué predice este modelo para la oración en el ejemplo de arriba?

##
Responder preguntas

El pipeline `question-answering` responde preguntas usando información de un contexto dado:

    from transformers import pipeline

    question_answerer = pipeline("question-answering")
    question_answerer(
        question="Where do I work?",
        context="My name is Sylvain and I work at Hugging Face in Brooklyn",
    )

    {'score': 0.6385916471481323, 'start': 33, 'end': 45, 'answer': 'Hugging Face'}

Observa que este pipeline funciona extrayendo información del contexto ofrecido; más no genera la respuesta.

##
Resumir (*Summarization*)

Resumir es la tarea de reducir un texto en uno más corto, conservando todos (o la mayor parte de) los aspectos importantes mencionados. Aquí va un ejemplo:

    from transformers import pipeline

    summarizer = pipeline("summarization")
    summarizer(
        """
        America has changed dramatically during recent years. Not only has the number of
        graduates in traditional engineering disciplines such as mechanical, civil,
        electrical, chemical, and aeronautical engineering declined, but in most of
        the premier American universities engineering curricula now concentrate on
        and encourage largely the study of engineering science. As a result, there
        are declining offerings in engineering subjects dealing with infrastructure,
        the environment, and related issues, and greater concentration on high
        technology subjects, largely supporting increasingly complex scientific
        developments. While the latter is important, it should not be at the expense
        of more traditional engineering.

        Rapidly developing economies such as China and India, as well as other
        industrial countries in Europe and Asia, continue to encourage and advance
        the teaching of engineering. Both China and India, respectively, graduate
        six and eight times as many traditional engineers as does the United States.
        Other industrial countries at minimum maintain their output, while America
        suffers an increasingly serious decline in the number of engineering graduates
        and a lack of well-educated engineers.
    """
    )

    [{'summary_text': ' America has changed dramatically during recent years . The '
                      'number of engineering graduates in the U.S. has declined in '
                      'traditional engineering disciplines such as mechanical, civil '
                      ', electrical, chemical, and aeronautical engineering . Rapidly '
                      'developing economies such as China and India, as well as other '
                      'industrial countries in Europe and Asia, continue to encourage '
                      'and advance engineering .'}]

Similar a la generación de textos, puedes especificar los argumentos `max-length` o `min_length` para definir la longitud del resultado.

##
Traducción

Para la traducción, puedes usar el modelo por defecto si indicas una pareja de idiomas en el nombre de la tarea (como `"translation_en_to_fr"`), pero la forma más sencilla es escoger el modelo que quieres usar en el Hub de Modelos. Aquí intentaremos traducir de Francés a Inglés:

    from transformers import pipeline

    translator = pipeline("translation", model="Helsinki-NLP/opus-mt-fr-en")
    translator("Ce cours est produit par Hugging Face.")

    [{'translation_text': 'This course is produced by Hugging Face.'}]

Al igual que los pipelines de generación de textos y resumen, puedes especificar una longitud máxima (`max_length`) o mínima (`min_length`) para el resultado.

✏️ ¡Pruébalo! Busca modelos de traducción en otros idiomas e intenta traducir la oración anterior en varios de ellos.

Los pipelines vistos hasta el momento son principalmente para fines demostrativos. Fueron programados para tareas específicas y no pueden desarrollar variaciones de ellas. En el siguiente capítulo, aprenderás qué está detrás de una función `pipeline()` y cómo personalizar su comportamiento.