#
Transformers, o que eles podem fazer?

Nessa seção, observaremos sobre o que os modelos Transformers podem fazer e usar nossa primeira ferramenta da biblioteca 🤗 Transformers: a função `pipeline()` .

👀 Tá vendo o botão Open in Colab no topo direito? Clique nele e abra um notebook Google Colab notebook com todas as amostras de códigos dessa seção. Esse botão estará presente em cada seção contendo exemplos de códigos.

Se você deseja rodar os exemplos localmente, nós recomendamos dar uma olhada no setup.

##
Transformers estão por toda parte!

Os modelos Transformers são usados para resolver todos os tipos de tarefas de NLP, como algumas já mencionadas na seção anterior. Aqui estão algumas empresas e organizações usando a Hugging Face e os modelos Transformers, que também contribuem de volta para a comunidade compartilhando seus modelos:

A biblioteca 🤗 Transformers oferece a funcionalidade para criar e usar esses modelos compartilhados. O Model Hub contém milhares de modelos pré-treinados que qualquer um pode baixar e usar. Você pode também dar upload nos seus próprios modelos no Hub!

⚠️ O Hugging Face Hub não é limitado aos modelos Transformers. Qualquer um pode compartilhar quaisquer tipos de modelos ou datasets que quiserem! Crie uma conta na huggingface.co para se beneficiar de todos os recursos disponíveis!

Antes de aprofundarmos sobre como os modelos Transformers funcionam por debaixo dos panos, vamos olhar alguns exemplos de como eles podem ser usados para solucionar alguns problemas de NLP interessantes.

##
Trabalhando com pipelines

O objeto mais básico na biblioteca 🤗 Transformers é a função `pipeline()` . Ela conecta o modelo com seus passos necessários de pré e pós-processamento, permitindo-nos a diretamente inserir qualquer texto e obter uma resposta inteligível:

    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}]

Nós até podemos passar várias sentenças!

    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 padrão, esse pipeline seleciona particularmente um modelo pré-treinado que tem sido ajustado (fine-tuned) para análise de sentimentos em Inglês. O modelo é baixado e cacheado quando você criar o objeto `classifier`. Se você rodar novamente o comando, o modelo cacheado irá ser usado no lugar e não haverá necessidade de baixar o modelo novamente.

Há três principais passos envolvidos quando você passa algum texto para um pipeline:

1. O texto é pré-processado para um formato que o modelo consiga entender.
2. As entradas (inputs) pré-processados são passadas para o modelo.
3. As predições do modelo são pós-processadas, para que então você consiga atribuir sentido a elas.

Alguns dos pipelines disponíveis atualmente, são:

- `feature-extraction` (pega a representação vetorial do texto)
- `fill-mask` (preenchimento de máscara)
- `ner` (reconhecimento de entidades nomeadas)
- `question-answering` (responder perguntas)
- `sentiment-analysis` (análise de sentimentos)
- `summarization` (sumarização)
- `text-generation` (geração de texto)
- `translation` (tradução)
- `zero-shot-classification` (classificação “zero-shot”)

Vamos dar uma olhada em alguns desses!

##
Classificação Zero-shot

Nós começaremos abordando uma tarefa mais desafiadora da qual nós precisamos classificar texto que não tenham sido rotulados. Esse é um cenário comum nos projetos reais porque anotar texto geralmente consome bastante do nosso tempo e requer expertise no domínio. Para esse caso, o pipeline `zero-shot-classification` é muito poderoso: permite você especificar quais rótulos usar para a classificação, desse modo você não precisa “confiar” nos rótulos dos modelos pré-treinados. Você já viu como um modelo pode classificar uma sentença como positiva ou negativa usando esses dois rótulos - mas também pode ser classificado usando qualquer outro conjunto de rótulos que você quiser.

    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]}

Esse pipeline é chamado de zero-shot porque você não precisa fazer o ajuste fino do modelo nos dados que você o utiliza. Pode diretamente retornar scores de probabilidade para qualquer lista de rótulos que você quiser!

✏️ Experimente! Brinque com suas próprias sequências e rótulos e veja como o modelo se comporta.

##
Geração de Texto

Agora vamos ver como usar um pipeline para gerar uma porção de texto. A principal ideia aqui é que você coloque um pedaço de texto e o modelo irá autocompletá-lo ao gerar o texto restante. Isso é similar ao recurso de predição textual que é encontrado em inúmeros celulares. A geração de texto envolve aleatoriedade, então é normal se você não obter o mesmo resultado obtido mostrado abaixo.

    from transformers import pipeline

    generator = pipeline("text-generation")
    generator(
        "In this course, we will teach you how to"
    )  # nesse curso, nós te mostraremos como você

    [{'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'}] # nesse curso, nós te mostraremos como você pode entender e usar o fluxo de dados e a troca de dados quando for lidar com dados do usuário. Nós estaremos trabalhando com um ou um dos mais comuns fluxos de dados utilizados - fluxo de dados de vários tipos, como visto pelo 'HTTP'

Você pode controlar quão diferentes sequências são geradas com o argumento `num_return_sequences` e o tamanho total da saída de texto (output) com o argumento `max_length`.

✏️ Experimente! Use os argumentos `num_return_sequences` e `max_length` para gerar 2 textos com 15 palavras cada.

##
Usando qualquer modelo do Hub em um pipeline

Nos exemplos passados, usamos o modelo padrão para a tarefa que executamos, mas você pode usar um modelo particular do Hub para usá-lo no pipeline em uma tarefa específica — exemplo, geração de texto. Vá ao Model Hub e clique na tag correspondente na esquerda para mostrar apenas os modelos suportáveis para aquela tarefa. Você deverá ir a uma página como essa.

Vamos tentar o modelo `distilgpt2`! Aqui está como carrega-lo no mesmo pipeline como antes:

    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'}]

Você pode refinar sua pesquisa por um modelo clicando nas tags de linguagem, e pegando o modelo que gerará o texto em outra lingua. O Model Hub até mesmo contém checkpoints para modelos multilinguais que suportem várias linguas.

Uma vez que você seleciona o modelo clicando nele, você irá ver que há um widget que permite que você teste-o diretamente online. Desse modo você pode rapidamente testar as capacidades do modelo antes de baixa-lo.

✏️ Experimente! Use os filtros para encontrar um modelo de geração de texto em outra lingua. Fique à vontade para brincar com o widget e usa-lo em um pipeline!

###
A API de Inferência

Todos os modelos podem ser testados diretamente de seu navegador usando a API de InferênciaI, que está disponível no website da Hugging Face. Você pode brincar com o modelo diretamente pela página colocando textos customizados e observando como o modelo processa os dados inseridos.

A API de Inferência que alimenta o widget também está disponível como um produto pago, que serve como uma “mão na roda” se você precisa dela para seus workflows. Olhe a página de preços para mais detalhes.

##
Preenchimento de máscara ( Mask filling )

O próximo pipeline que você irá testar é o `fill-mask`. A ideia dessa tarefa é preencher os espaços em branco com um 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'}]

O argumento `top_k` controla quantas possibilidades você quer que sejam geradas. Note que aqui o modelo preenche com uma palavra `<máscara>` especial, que é frequentemente referida como mask token. Outros modelos de preenchimento de máscara podem ter diferentes mask tokens, então é sempre bom verificar uma palavra máscara apropriada quando explorar outros modelos. Um modo de checar isso é olhando para a palavra máscara usada no widget.

✏️ Experimente! Pesquise pelo modelo `bert-base-cased` no Hub e identifique suas palavras máscara no widget da API de inferência. O que esse modelo prediz para a sentença em nosso `pipeline` no exemplo acima?

##
Reconhecimento de entidades nomeadas

Reconhecimento de Entidades Nomeadas (NER) é uma tarefa onde o modelo tem de achar quais partes do texto correspondem a entidades como pessoas, locais, organizações. Vamos olhar em um exemplo:

    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}
    ]

Aqui o modelo corretamente identificou que Sylvain é uma pessoa (PER), Hugging Face é uma organização (ORG), e Brooklyn é um local (LOC).

Nós passamos a opção `grouped_entities=True` na criação da função do pipelina para dize-lo para reagrupar juntos as partes da sentença que correspondem à mesma entidade: aqui o modelo agrupou corretamente “Hugging” e “Face” como única organização, ainda que o mesmo nome consista em múltiplas palavras. Na verdade, como veremos no próximo capítulo, o pré-processamento até mesmo divide algumas palavras em partes menores. Por exemplo, `Sylvain` é dividido em 4 pedaços: `S`, `##yl`, `##va`, e `##in`. No passo de pós-processamento, o pipeline satisfatoriamente reagrupa esses pedaços.

✏️ Experimente! Procure no Model Hub por um modelo capaz de fazer o tageamento de partes do discurso (usualmente abreviado como POS) em inglês. O que o modelo prediz para a sentença no exemplo acima?

##
Responder perguntas

O pipeline `question-answering` responde perguntas usando informações dado um contexto:

    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'}

Note que o pipeline funciona através da extração da informação dado um contexto; não gera uma resposta.

##
Sumarização

Sumarização é uma tarefa de reduzir um texto em um texto menor enquanto pega toda (ou boa parte) dos aspectos importantes do texto referenciado. Aqui um exemplo:

    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 .'}]

Como a geração de texto, você pode especificar o tamanho máximo `max_length` ou mínimo `min_length` para o resultado.

##
Tradução

Para tradução, você pode usar o modelo default se você der um par de idiomas no nome da tarefa (tal como `"translation_en_to_fr"`, para traduzir inglês para francês), mas a maneira mais fácil é pegar o moddelo que você quiser e usa-lo no Model Hub. Aqui nós iremos tentar traduzir do Francês para o 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.'}]

Como a geração de texto e a sumarização, você pode especificar o tamanho máximo `max_length` e mínimo `min_length` para o resultado.

✏️ Experimente! Pesquise por modelos de tradução em outras línguas e experimente traduzir a sentença anterior em idiomas diferentes.

Os pipelines mostrados até agora são em sua maioria para propósitos demonstrativos. Eles foram programados para tarefas específicas e não podem performar variações delas. No próximo capítulo, você aprenderá o que está por dentro da função `pipeline()` e como customizar seu comportamento.