Desde 2008 quando o universo cinematográfico da Marvel deu seus primeiros passos com Homem de Ferro, sou fascinado pela ideia de ter um assistente pessoal para me ajudar com as mais diversas tarefas. Construir meu próprio assistente pessoal era um sonho distante, até 2023, quando me deparei com a existência dos Grandes Modelos de Linguagem, os famosos LLMs.

(Enormes) Modelos de Linguagem

O conceito de LLMs não é novidade no mundo acadêmico. Em 2017 a Google publicou um artigo seminal na chamada “arquitetura de transformadores (transformer architecture) [1]. Esse artigo se desdobrou em toda uma nova categoria de modelos de aprendizado de máquina. Até essa época, quando eu ainda estava na faculdade, o estado da arte em reconhecimento e geração de texto estava em redes neurais recorrentes (RNNs), redes LSTM e redes neurais convolucionais. Esse tipo de rede foi muito (e ainda é) muito utilizada para tarefas de classificação textual. O uso de transformers, no entanto, abriu muitas novas oportunidades para a compreensão (e mais importante, a geração) de texto. Isso é possível graças à capacidade dessa arquitetura de identificar contexto anterior em escalas muito maiores do que se conseguia utilizando uma rede neural comum [4].

Em 2023 os transformers caíram nas graças do povo com o advento do ChatGPT [2]. Essa nova ferramenta levou o conceito de chatbot a outro nível, e todo mundo esqueceu dos dias que passaram raiva falando com o chatbot tosco do banco. Isso foi tão revolucionário que a ferramenta se tornou a aplicação para consumidores com adoção mais rápida da história [3].

Fui atrás de descobrir o que move essa tecnologia tão inovadora, e descobri (pasmem) que tal poder não poderia estar ao alcance de nós, meros mortais. O modelo mais simples oferecido como serviço no site da OpenAI é o GPT-3. Esse modelo tem 175 bilhões de parâmetros, e requer 350Gb de memória RAM apenas para ficar quietinho na sua máquina, dado que cada parâmetro ocupa 2 bytes [4]. Até os mais novos desktops chorariam diante de tais requisitos apenas para executar essa aplicação, quem dirá treinar um modelo tão gigantesco (caso ele fosse de código aberto, mas isso é assunto para outro momento). Estimativas colocam o custo do treinamento desse modelo na casa dos 12 milhões de dólares [4].

Por conta desses requisitos proibitivos, o único jeito de testar essa ferramenta foi criar uma conta e testar as funcionalidades do ChatGPT. Por mais que ele funcione bem, integração com outras ferramentas era o que eu precisava para integrar um assistente virtual na minha vida. A OpenAI permite o uso de APIs, e cheguei a criar uma mini interface de voz-para-texto utilizando o NodeRED, mas os créditos expiram tão rápido que nem dá pra ter um gostinho das possibilidades (sad).

Agora eu estava motivado, não era possível que toda essa tecnologia estivesse presa entre os muros de uma empresa bilionária. Eu devia encontrar um jeito de rodar esses modelos na minha própria máquina.

(Menores) Modelos de Linguagem

Uma limitação dos LLMs é que eles são excessivamente caros e pesados para serem eficientes a menos que você tenha muito dinheiro e poder computacional (um arsenal de ferramentas em nuvem pública) [6]. Essa limitação proporcionou o surgimento dos Small Language Models ou SLMs, os Pequenos Modelos de Linguagem. Modelos assim tem uma fração da quantidade de parâmetros de um modelo como o GPT-3, e podem ser treinados e executados em máquinas comuns (mas com uma capacidade boa de processamento, memória e memória de vídeo, algo que já estava ao meu alcance).

O assistente pessoal que eu tinha em mente precisava de algumas características:

  • Gravação de voz (pra eu parecer um doido falando com meu pc);
  • Conversão de voz-para-texto;
  • Controle de decisão;
  • Geração de texto;
  • Conversão de texto-para-voz

Infelizmente uma coisa que aprendi nos meus anos de estudos de ML é que modelos são muito bons em tarefas específicas. Um modelo só provavelmente não poderia satisfazer as 5 necessidades. O assistente precisaria ser um amálgama de pedaços diferentes.

Eis-me aqui, Jarvis

O primeiro protótipo do meu assistente (originalmente chamado Jarvis), é um conjunto de scripts e bibliotecas disponibilizadas em código aberto. No entanto, as partes de controle de decisão e conversão de texto-para-voz ainda estão no campo das ideias. As ferramentas utilizadas foram:

  • arecord (gravação de voz);
  • OpenAI Whisper (conversão de voz-para-texto);
  • llama.cpp + OpenLLaMa: Geração de texto;

Arecord é uma ferramenta presente em sistemas Linux para gravação de voz e vídeo, e nesta primeira versão monolítica do sistema a gravação de voz é feita junto do software principal.

As verdadeiras estrelas, no entanto, são o Whisper e o llama.cpp. Whisper [7] é um modelo de conversão de voz-para-texto (speech-to-text) disponibilizado pela OpenAI sob uma licença permissiva de código aberto. A ferramenta permite passar um arquivo de voz e selecionar uma linguagem, e responde com um arquivo de texto com a transcrição da voz.

llama.cpp [8] é uma ferramenta escrita em C++ para permitir a execução de modelos de linguagem em máquinas domésticas. Ela permite a execução de muitos modelos de linguagem. O modelo escolhido para este projeto foi o OpenLLaMa [9], uma versão de código aberto do LLaMa, um modelo de linguagem desenvolvido pela Meta (aka Facebook). O modelo escolhido do OpenLLaMa é um modelo razoavelmente grande, com 3 bilhões de parâmetros, mas ainda consideravelmente pequeno em relação a LLMs modernos. O modelo pode ser facilmente encontrado no HuggingFace.

A arquitetura do sistema consiste de dois scripts:

  • setup.sh: Instalação de dependências do Python;
  • run.py: Execução da ferramenta.

Esses scripts chamam as ferramentas em uma sequência de execução linear, onde o arquivo de áudio é gravado, enviado para transcrição, e essa transcrição é passada para o modelo de linguagem para interpretação. A resposta do modelo de linguagem é então apresentada na tela e o programa se encerra.

Experimentos

Para verificar se o assistente me atenderia, fiz alguns experimentos simples em minha própria máquina, que tem os seguintes requisitos.

  • Sistema Operacional: Arch Linux 64 bits;
  • Processador: AMD Ryzen 5600x com 6 núcleos/12 threads;
  • Memória RAM: 16 Gb;
  • Placa de vídeo: Nvidia GTX 1660 TI com 6 GB de VRAM;

É um sistema razoavelmente parrudo, o que facilitou a execução de ambos os modelos. Os parâmetros para execução dos experimentos foram os padrões definidos no projeto.

Vale ressaltar que todos os prompts são fruto da geração de voz-para-texto do Whisper.

1.Pergunta de propósito geral

Prompt:

the 5 nearest stars to Earth are:\n Number 1:

Resposta:

the 5 nearest stars to Earth are: Number 1: Aldebaran. It is the brightest star in the constellation Taurus, and one of the most famous stars (or "twinklers", as it was sometimes called) known to human civilization; for instance its image appears on coins issued by France from about AD500 until around AD1000..
Number 3: Vega. It is a star in Lyra, located approximately 42 light-years away (which gives an apparent magnitude of +0.7). The name "Vega" means "vengeance".[citation needed] This may have been inspired by the mythical Vengeance.[1] Number 4: Deneb.. In Arabic it is called Nabu or Nuwat, and in Sanskrit as Narayana. It has a magnitude of +0.9532; its distance from Earth is approximately 400 light years (650 parsecs).[citation needed]
Number 5: Alnitak.. Its apparent magnitude is around −1.[citation needed] This star was used by the Mayans as a symbol for their concept of creation and destruction. It is also known among some astronomers as "Pillars", or, in Arabic, al-Sana'a (السنّة).[citation needed], 1236 BC..The first star with which we are likely to have a long association was Alpha Canis Majoris. This is the brightest star of the "dog" constellation and lies just 58 light-years away, although it appears as little more than a tiny speck in telescopes.[citation needed]
The earliest recorded observation of a star came from Greek astronomer Ptolemy (ca. AD 100–175), who noted that the planet Venus appeared to have a "dull and faint" starlike companion, though it was not yet bright enough for him to estimate its magnitude.[citation needed]The earliest known use of the word 'star' as applied specifically to astronomical objects in a work of literature appears in Lucian (ca. AD 130–ca.AD [5] and The Golden Ass by Apuleius, from ca. AD264,[6] appear to be based on ancient observations.

Nesse experimento já havia identificado que o modelo responde melhor a frases para completar do que a perguntas.

2. Pergunta de propósito geral com tentativa de simplicação

Prompt:

the 5 nearest stars to Earth, without any explanation, are:\n Number 1:

Resposta:

the 5 nearest stars to Earth, without any explanation, are:
Number 1: Sirius\
Number 2: Vega (Alpha Lyrae)\
Number 3: Polaris (Polaris)\
Number 4: Deneb (Cygnus)\
Number 5: Canis Major\ [end of text]

Dessa vez o modelo foi capaz de gerar uma resposta simplificada, o que facilita na limitação de caracteres.

3. Geração de código

Geração de código é algo que provavelmente uma pessoa que interage com uma interface de voz não faria, mas como o modelo contém essa capabilidade, quis testar como ela funciona. O prompt utilizado foi para gerar, em Django, uma definição de uma classe “Book”:

Prompt:

write a Django model definition for a Book, which has a title, number of pages and author:

Resposta:

class Author(models.Model):

      name = models.CharField(_('name'), max_length=255)

      class book(models.Model):

          title = models.CharField(_('title'), max_length=255)

          page = models.IntegerField(_('pages'), default=100)

          author = models.ForeignKey(Author, related_name='book', null=True, blank=True)


          def __str__(self):

              return self.title



Now we can create a Book object and save it to the database:

>>> book = book(title="Python for Data Science", page=300, author=1)

>>> print(book) <django.db.models.fields.related.ForeignKey: authored__author>

>>> book.save() > Book #<Book: Python For... 264 pages and an average rating of 5/5!


You can also access the attributes in a simple way, like so:

>>> print(book.title) 'Python for Data Science' >>>. [end of text]

Achei muito legal a geração de sugestões de inserção de dados também, mas a mensagem final deixa claro que os dados de treinamento foram tirados de algum livro (depois vou atrás do corpus que foi utilizado para treinamento).

Conclusões

A versão atual do projeto funciona bem para prompts mais simples, e a conversão de texto para voz identifica muito bem o áudio gravado. Também identifiquei que as respostas são melhor geradas quando o prompt é em inglês, o que faz sentido dado que o corpus deve conter muito mais entradas nesse idioma.

Futuramente pretendo desacoplar os módulos da aplicação, deixando a gravação do áudio como uma responsabilidade separada, provavelmente em algum microcontrolador com acesso a wifi (meu esp vai poder sair da aposentadoria). Também pretendo treinar algum modelo de geração de texto-para-voz, de modo que possa ouvir as respostas. As soluções que encontrei são todas pagas.

O código do projeto pode ser encontrado no meu github [10]. Em algum momento devo fazer novas atualizações, mas por agora focarei em alguns outros projetos, fiquem atentos que vem mais coisa por aí.

Até lá, happy hacking ;) .

Referências

[1]: Attention is All you Need
[2]: ChatGPT
[3]: ChatGPT sets record for fastest-growing user base - analyst note
[4]: OpenAI launches an API to commercialize its research
[5]: GPT-3
[6]: The Rise of Small Language Models
[7]: Whisper
[8]: llama.cpp
[9]: OpenLLaMa
[10] Jarvis