Structured Query Language, ou SQL (muitas vezes pronunciado “sequel”), é uma linguagem de programação declarativa usada para armazenar, recuperar, gerenciar e manipular dados em um sistema de gerenciamento de banco de dados.
Ela foi desenvolvida pelos pesquisadores da IBM Raymond Boyce e Donald Chamberlain no início da década de 1970, mas só se tornou comercialmente disponível em 1979, quando a Relational Software, Inc. — hoje Oracle — lançou sua implementação.
Hoje, o SQL é amplamente aceito como o padrão de sistema de gerenciamento de banco de dados relacional (RDBMS), graças à sua simplicidade e à capacidade de gerenciar e analisar grandes volumes de dados com eficiência — algo indispensável no nosso mundo cada vez mais orientado por dados.
Mas esse mundo orientado por dados está evoluindo.
A inteligência artificial está ganhando espaço rapidamente, e os grandes modelos de linguagem surgiram como ferramentas extremamente poderosas para diversas tarefas. O único problema é que, às vezes, interagir com esses modelos parece conversar em outro idioma. É aí que o LMQL entra em cena.
Desenvolvido pelo SRI Lab da ETH Zürich, o LMQL funciona como um tradutor pessoal entre desenvolvedores e seus modelos de linguagem. Em resumo, o LMQL leva o poder do SQL para o universo dos modelos de linguagem, deixando as interações mais fluidas, eficientes e até divertidas.
No restante deste tutorial, vamos falar sobre:
O que é LMQL?
Por que usar LMQL?
Como configurar o LMQL
Aplicações práticas do LMQL
Limitações do LMQL
Boas práticas
O que é LMQL?
LMQL, sigla para Language Models Query Language, é uma linguagem de programação inovadora para Large Language Models (LLMs). Ela combina elementos declarativos inspirados em SQL com uma sintaxe imperativa de script para oferecer uma forma mais estruturada e intuitiva de extrair informações ou gerar respostas a partir de LLMs.
Além disso, o LMQL é um superconjunto de Python, o que significa que atua como uma extensão que introduz novos recursos e amplia as capacidades da linguagem. Isso permite criar prompts em linguagem natural que misturam texto e código, aumentando a flexibilidade e a expressividade das consultas.
De acordo com a documentação, “o LMQL oferece uma nova forma de entrelaçar programação tradicional com a capacidade de chamar LLMs no seu código. Ele vai além das linguagens de template tradicionais ao integrar a interação com LLMs de forma nativa no nível do seu código-fonte.”
Para contextualizar, grandes modelos de linguagem têm mostrado desempenho excepcional em várias tarefas, como responder perguntas e gerar código. Em essência, LLMs são muito bons em gerar sequências lógicas automaticamente com base em entradas fornecidas, usando probabilidades estatísticas.
Aproveitando essa capacidade, usuários conseguem orientar LLMs com instruções em linguagem natural ou exemplos para disparar a execução de diferentes tarefas. Técnicas avançadas de prompting permitem até interações entre usuários, o modelo e ferramentas externas como calculadoras.
O desafio está em atingir desempenho de ponta ou adaptar LLMs a tarefas específicas, o que geralmente exige programas complexos e sob medida — e que ainda podem depender de interações ad hoc.
O prompting de modelos de linguagem é uma disciplina emergente que vem ganhando tração para enfrentar esses problemas. O LMQL segue os princípios do LMP, oferecendo uma combinação intuitiva de texto e script para prompting e permitindo especificar restrições sobre a saída do modelo.
Por que LMQL?
A geração mais recente de modelos de linguagem pode ser orientada com exemplos ou instruções de forma relativamente simples, conceitualmente. No entanto, para extrair todo o seu potencial e acompanhar a evolução de novos modelos, é preciso entender a fundo seu funcionamento interno e as bibliotecas e implementações específicas de cada fornecedor.
Por exemplo, limitar o processo de decodificação a uma lista de palavras ou frases válidas pode ser complicado porque os modelos operam com tokens. E, independentemente de você usar LLMs localmente ou via API, o custo costuma ser alto, pois são redes massivas.
O LMQL pode reduzir o número de chamadas ao modelo de linguagem aproveitando comportamentos predefinidos e a busca restrita introduzida pelas constraints.
Outro motivo para usar LMQL é que muitas técnicas de prompting exigem um vai e vem entre o modelo e o usuário (como vemos em chatbots como o ChatGPT) ou interfaces altamente especializadas, como as usadas para cálculos aritméticos com lógica de controle externa.
Implementar esses prompts demanda muito trabalho manual e interação com os procedimentos de decodificação do modelo, o que limita a generalidade das soluções. Por fim, como um LM só consegue gerar um token (subpalavra) por vez, concluir uma resposta pode exigir várias chamadas.
Os LMs atuais não oferecem, por padrão, a funcionalidade de restringir a saída — algo essencial quando usados em produção. Imagine que você está construindo um app de análise de sentimento para marcar avaliações negativas. O programa esperaria que o LLM respondesse com “positivo”, “negativo” ou “neutro”.
No entanto, com frequência o LLM pode responder algo como “O sentimento da avaliação do cliente fornecida é positivo”, o que é difícil de processar via API. Por isso, constraints são extremamente valiosas.
Com o LMQL, você controla a saída com termos compreensíveis para humanos, e não apenas com os tokens usados pelos LMs.
Como configurar o LMQL
O LMQL pode ser instalado localmente ou usado online pelo Playground IDE no navegador. Observação: se você quiser usar modelos self-hosted via Transformers ou llama.cpp, é necessário instalar o LMQL localmente. Veja como:
Instalação e configuração do ambiente
Instalar o LMQL localmente é bem simples.
Basta executar o comando abaixo em um ambiente Python >= 3.10:
Esse comando abrirá o Playground IDE no navegador; se não abrir automaticamente, acesse http://localhost:3000.
Atenção: esse método requer a instalação do Node.js.
2. Interface de linha de comando Como alternativa ao playground, você pode usar a ferramenta de linha de comando para executar arquivos .lmql locais. Para isso, rode:
3. Integração com Python Como é um superconjunto, o LMQL pode ser executado diretamente dentro de um programa Python. Basta importar o pacote lmql. Todo o código de consulta deve ser executado via lmql.run ou com o decorador @lmql.query.
Ao usar modelos Transformer locais no Playground IDE ou pela linha de comando, você deve primeiro iniciar uma instância da LMQL Inference API para o modelo correspondente, executando o comando lmql serve-model.
Entendendo a sintaxe do LMQL
Um programa LMQL tem cinco partes fundamentais, cada uma com papel essencial no comportamento de uma consulta. São elas:
Query
Decoder
Model
Constraints
Distribution
Vamos aprofundar em cada uma.
Query
O bloco de query é o principal meio de comunicação entre o modelo de linguagem e o usuário.
Veja uma query básica em LMQL:
# Source: https://lmql.ai/docs/"Say 'this is a test':[RESPONSE]" where len(TOKENS(RESPONSE))<25
—-- Model Output—--"""
Say 'this is a test': RESPONSE This is a test
"""Tecnologia
O bloco de query trata toda string no nível superior como uma consulta direta ao modelo de linguagem. Assim como f-strings em Python, essas strings de consulta suportam dois subcampos especiais com escape.
Repare que o trecho que o modelo vai gerar é representado por [varname]. Isso também é chamado de “hole” (lacuna) — já chegamos à cláusula where.
Também é possível recuperar o valor de uma variável do escopo atual usando {varname}.
Por exemplo:
# Source: https://lmql.ai/docs/language/overview.html# review a ser analisada
review ="""We had a great stay. Hiking in the mountains was fabulous and the food is really good."""# use prompt statements para passar informações ao modelo"Review: {review}"Tecnologia
Decoder
O LMQL suporta vários algoritmos de decodificação usados para gerar texto a partir da distribuição de tokens de um modelo de linguagem. Isso permite especificar o algoritmo de decodificação no início de uma query.
Há duas formas de definir o algoritmo de decodificação:
1. Como parte da query — você especifica o algoritmo e seus parâmetros dentro da própria query. Segundo a documentação do LMQL, “isso pode ser particularmente útil se a escolha do decoder for relevante para o programa que você está escrevendo”. Veja como fica no código:
# Source: https://lmql.ai/docs/language/decoding.html# use beam search com largura 2# para o programa inteiro
beam(n=2)# usa beam search para gerar RESPONSE "This is a query with a specified decoder: [RESPONSE]"Tecnologia
2. Externamente — você define o algoritmo e os parâmetros de decodificação fora do programa em si, ou seja, separadamente. Observação: isso só é possível quando o LMQL é usado em um contexto Python
# Source: https://lmql.ai/docs/language/decoding.htmlimport lmql@lmql.query(model="openai/text-davinci-003", decoder="sample", temperature=1.8)deftell_a_joke():'''lmql
"""A list good dad joke. A indicates the punchline:
Q:[JOKE]
A:[PUNCHLINE]""" where STOPS_AT(JOKE, "?") and STOPS_AT(PUNCHLINE, "\n")
'''
tell_a_joke()# usa o decoder definido em @lmql.query(...)
tell_a_joke(decoder="beam", n=2)# usa beam search com n=2Tecnologia
Model
Os desenvolvedores definem o LMQL como uma “linguagem de alto nível e front-end para geração de texto”. Isso quer dizer que ele não é específico de um único modelo. Em vez disso, dá suporte a vários modelos de geração de texto no backend, como OpenAI model, llama.cppeHuggingFace Transformers.
Carregar modelos é bem direto. Você pode usar a função lmql.model(...), que produz um objeto lmql.LMM.
Exemplo:
# Source: https://lmql.ai/docs/models/
lmql.model("openai/gpt-3.5-turbo-instruct")# modelo da OpenAI API
lmql.model("random", seed=123)# modelo de amostragem aleatória
lmql.model("llama.cpp:<YOUR_WEIGHTS>.gguf")# modelo via llama.cpp
lmql.model("local:gpt2")# carrega um modelo `transformers` no processo
lmql.model("local:gpt2", cuda=True, load_in_4bit=True)# carrega um `transformers` no processo com argumentos extras
lmql.model("gpt2")# acessa um modelo `transformers` hospedado via `lmql serve-model`Tecnologia
Depois que o objeto lmql.LLM é criado, você pode passá-lo ao programa de query de duas maneiras:
1. Especificando o modelo externamente
# Source: https://lmql.ai/docs/models/import lmql
# usa 'chatgpt' por padrão@lmql.query(model="chatgpt")deftell_a_joke():'''lmql
"""A great good dad joke. A indicates the punchline
Q:[JOKE]
A:[PUNCHLINE]""" where STOPS_AT(JOKE, "?") and \
STOPS_AT(PUNCHLINE, "\n")
'''
tell_a_joke()# usa chatgpt
tell_a_joke(model=lmql.model("openai/text-davinci-003"))# usa text-davinci-003Tecnologia
2. Usando uma query com cláusula from
# Source: https://lmql.ai/docs/models/
argmax
"This is a query with a specified 'from'-clause: [RESPONSE]"from"openai/text-ada-001"Tecnologia
Constraints
Um dos grandes atrativos do LMQL é o componente de constraints (restrições). Com elas, você pode impor condições sobre a saída do modelo de linguagem. Isso ajuda no prompting roteirizado, garantindo que a saída termine no ponto certo e dando controle sobre o modelo durante a decodificação.
As constraints suportadas incluem:
Stopping phrases
Number type constraints
Choice from set
Character length
Token length
Regex constraints preview
Combining constraints
Custom
Confira a página de Constraints na documentação do LMQL para saber mais.
Distribution
A instrução de distribuição é um componente-chave no LMQL. Ela controla o formato e a estrutura da saída, definindo como os resultados gerados são distribuídos e apresentados.
Veja um exemplo na prática:
# Source: https://lmql.ai/docs/language/overview.html
argmax
# review a ser analisada
review ="""We had a great stay. Hiking in the mountains was fabulous and the food is really good."""# use prompt statements para passar informações ao modelo"Review: {review}""Q: What is the underlying sentiment of this review and why?"# variáveis de template como [ANALYSIS] são usadas para gerar texto"A:[ANALYSIS]" where not"\n"in ANALYSIS
# use variável com restrição para produzir uma classificação"Based on this, the overall sentiment of the message can be considered to be[CLS]"
distribution
CLS in[" positive"," neutral"," negative"]----- Model Output ------
Review: We had a great stay. Hiking in the mountains was fabulous and the food is really good.
Q: What is the underlying sentiment of this review and why?
A: ANALYSIS The underlying sentiment of this review is positive because the reviewer had a great stay, enjoyed the hiking and found the food to be good.
Based on this, the overall sentiment of the message can be considered to be CLSTecnologia
Limitações do LMQL e suporte da comunidade
Como toda tecnologia, o LMQL tem algumas limitações. Por exemplo:
A biblioteca do LMQL é relativamente nova e ainda não é muito popular. Consequentemente, a comunidade é pequena e há poucos recursos externos para ajudar quando você ficar travado.
A documentação da biblioteca poderia ser mais detalhada.
Limitações da API da OpenAI significam que não é possível aproveitar totalmente o LMQL com o ChatGPT, já que os modelos mais populares e com melhor desempenho não estão acessíveis.
Embora esses pontos possam ser impeditivos para quem está considerando usar o LMQL, é importante lembrar que a biblioteca ainda é nova e está em desenvolvimento — essas limitações podem ser resolvidas em versões futuras.
Conclusão
O LMQL é uma linguagem de programação ao estilo SQL e também um superconjunto de Python. Ele simplifica a extração de informações e a geração de respostas de LLMs ao combinar elementos declarativos com uma sintaxe imperativa de script. Desenvolvedores podem usar o LMQL para controlar a geração de texto com eficiência, tornando-o uma ferramenta valiosa para diversas aplicações no setor de tecnologia.
Mergulhe em um passo a passo abrangente sobre a compreensão do preconceito nos LLMs, o impacto que ele causa e como atenuá-lo para garantir a confiança e a justiça.
Saiba como avaliar modelos de linguagem grandes (LLMs) usando métricas importantes, metodologias e práticas recomendadas para tomar decisões informadas.
O ajuste fino dos grandes modelos de linguagem (LLMs, Large Language Models) revolucionou o processamento de linguagem natural (PLN), oferecendo recursos sem precedentes em tarefas como tradução de idiomas, análise de sentimentos e geração de textos. Essa abordagem transformadora aproveita modelos pré-treinados como o GPT-2, aprimorando seu desempenho em domínios específicos pelo processo de ajuste fino.
Explore o potencial inexplorado dos modelos de linguagem grandes com o LangChain, uma estrutura Python de código aberto para criar aplicativos avançados de IA.
Descubra os fundamentos da IA, aprenda a usar a IA de forma eficaz no trabalho e mergulhe em modelos como o chatGPT para navegar pelo cenário dinâmico da IA.
Structured Query Language, ou SQL (muitas vezes pronunciado “sequel”), é uma linguagem de programação declarativa usada para armazenar, recuperar, gerenciar e manipular dados em um sistema de gerenciamento de banco de dados.
Ela foi desenvolvida pelos pesquisadores da IBM Raymond Boyce e Donald Chamberlain no início da década de 1970, mas só se tornou comercialmente disponível em 1979, quando a Relational Software, Inc. — hoje Oracle — lançou sua implementação.
Hoje, o SQL é amplamente aceito como o padrão de sistema de gerenciamento de banco de dados relacional (RDBMS), graças à sua simplicidade e à capacidade de gerenciar e analisar grandes volumes de dados com eficiência — algo indispensável no nosso mundo cada vez mais orientado por dados.
Mas esse mundo orientado por dados está evoluindo.
A inteligência artificial está ganhando espaço rapidamente, e os grandes modelos de linguagem surgiram como ferramentas extremamente poderosas para diversas tarefas. O único problema é que, às vezes, interagir com esses modelos parece conversar em outro idioma. É aí que o LMQL entra em cena.
Desenvolvido pelo SRI Lab da ETH Zürich, o LMQL funciona como um tradutor pessoal entre desenvolvedores e seus modelos de linguagem. Em resumo, o LMQL leva o poder do SQL para o universo dos modelos de linguagem, deixando as interações mais fluidas, eficientes e até divertidas.
No restante deste tutorial, vamos falar sobre:
O que é LMQL?
LMQL, sigla para Language Models Query Language, é uma linguagem de programação inovadora para Large Language Models (LLMs). Ela combina elementos declarativos inspirados em SQL com uma sintaxe imperativa de script para oferecer uma forma mais estruturada e intuitiva de extrair informações ou gerar respostas a partir de LLMs.
Além disso, o LMQL é um superconjunto de Python, o que significa que atua como uma extensão que introduz novos recursos e amplia as capacidades da linguagem. Isso permite criar prompts em linguagem natural que misturam texto e código, aumentando a flexibilidade e a expressividade das consultas.
De acordo com a documentação, “o LMQL oferece uma nova forma de entrelaçar programação tradicional com a capacidade de chamar LLMs no seu código. Ele vai além das linguagens de template tradicionais ao integrar a interação com LLMs de forma nativa no nível do seu código-fonte.”
A linguagem foi apresentada por seus criadores em um artigo de pesquisa intitulado Prompting is Programming: A Query Lnague for Large Language Models como uma solução para viabilizar um fenômeno que eles chamaram de “LMP”, de Language Model Prompting.
Para contextualizar, grandes modelos de linguagem têm mostrado desempenho excepcional em várias tarefas, como responder perguntas e gerar código. Em essência, LLMs são muito bons em gerar sequências lógicas automaticamente com base em entradas fornecidas, usando probabilidades estatísticas.
Aproveitando essa capacidade, usuários conseguem orientar LLMs com instruções em linguagem natural ou exemplos para disparar a execução de diferentes tarefas. Técnicas avançadas de prompting permitem até interações entre usuários, o modelo e ferramentas externas como calculadoras.
O desafio está em atingir desempenho de ponta ou adaptar LLMs a tarefas específicas, o que geralmente exige programas complexos e sob medida — e que ainda podem depender de interações ad hoc.
O prompting de modelos de linguagem é uma disciplina emergente que vem ganhando tração para enfrentar esses problemas. O LMQL segue os princípios do LMP, oferecendo uma combinação intuitiva de texto e script para prompting e permitindo especificar restrições sobre a saída do modelo.
Por que LMQL?
A geração mais recente de modelos de linguagem pode ser orientada com exemplos ou instruções de forma relativamente simples, conceitualmente. No entanto, para extrair todo o seu potencial e acompanhar a evolução de novos modelos, é preciso entender a fundo seu funcionamento interno e as bibliotecas e implementações específicas de cada fornecedor.
Por exemplo, limitar o processo de decodificação a uma lista de palavras ou frases válidas pode ser complicado porque os modelos operam com tokens. E, independentemente de você usar LLMs localmente ou via API, o custo costuma ser alto, pois são redes massivas.
O LMQL pode reduzir o número de chamadas ao modelo de linguagem aproveitando comportamentos predefinidos e a busca restrita introduzida pelas constraints.
Outro motivo para usar LMQL é que muitas técnicas de prompting exigem um vai e vem entre o modelo e o usuário (como vemos em chatbots como o ChatGPT) ou interfaces altamente especializadas, como as usadas para cálculos aritméticos com lógica de controle externa.
Implementar esses prompts demanda muito trabalho manual e interação com os procedimentos de decodificação do modelo, o que limita a generalidade das soluções. Por fim, como um LM só consegue gerar um token (subpalavra) por vez, concluir uma resposta pode exigir várias chamadas.
Os LMs atuais não oferecem, por padrão, a funcionalidade de restringir a saída — algo essencial quando usados em produção. Imagine que você está construindo um app de análise de sentimento para marcar avaliações negativas. O programa esperaria que o LLM respondesse com “positivo”, “negativo” ou “neutro”.
No entanto, com frequência o LLM pode responder algo como “O sentimento da avaliação do cliente fornecida é positivo”, o que é difícil de processar via API. Por isso, constraints são extremamente valiosas.
Com o LMQL, você controla a saída com termos compreensíveis para humanos, e não apenas com os tokens usados pelos LMs.
Como configurar o LMQL
O LMQL pode ser instalado localmente ou usado online pelo Playground IDE no navegador. Observação: se você quiser usar modelos self-hosted via Transformers ou llama.cpp, é necessário instalar o LMQL localmente. Veja como:
Instalação e configuração do ambiente
Instalar o LMQL localmente é bem simples.
Basta executar o comando abaixo em um ambiente Python >= 3.10:
Se você pretende rodar modelos em uma GPU local, instale o LMQL em um ambiente com PyTorch >= 1.11 com suporte a GPU.
Para instalar o LMQL com dependências de GPU via pip, use:
Observação: é recomendável instalar dependências em um ambiente virtual.
Após a instalação, você tem três opções para executar programas LMQL:
1. Playground
Você pode iniciar uma instância local do Playground IDE
Esse comando abrirá o Playground IDE no navegador; se não abrir automaticamente, acesse http://localhost:3000.
Atenção: esse método requer a instalação do Node.js.
2. Interface de linha de comando
Como alternativa ao playground, você pode usar a ferramenta de linha de comando para executar arquivos .lmql locais. Para isso, rode:
3. Integração com Python
Como é um superconjunto, o LMQL pode ser executado diretamente dentro de um programa Python. Basta importar o pacote lmql. Todo o código de consulta deve ser executado via lmql.run ou com o decorador
@lmql.query.Ao usar modelos Transformer locais no Playground IDE ou pela linha de comando, você deve primeiro iniciar uma instância da LMQL Inference API para o modelo correspondente, executando o comando
lmql serve-model.Entendendo a sintaxe do LMQL
Um programa LMQL tem cinco partes fundamentais, cada uma com papel essencial no comportamento de uma consulta. São elas:
Vamos aprofundar em cada uma.
Query
O bloco de query é o principal meio de comunicação entre o modelo de linguagem e o usuário.
Veja uma query básica em LMQL:
O bloco de query trata toda string no nível superior como uma consulta direta ao modelo de linguagem. Assim como f-strings em Python, essas strings de consulta suportam dois subcampos especiais com escape.
Repare que o trecho que o modelo vai gerar é representado por
[varname]. Isso também é chamado de “hole” (lacuna) — já chegamos à cláusula where.Também é possível recuperar o valor de uma variável do escopo atual usando
{varname}.Por exemplo:
Decoder
O LMQL suporta vários algoritmos de decodificação usados para gerar texto a partir da distribuição de tokens de um modelo de linguagem. Isso permite especificar o algoritmo de decodificação no início de uma query.
Há duas formas de definir o algoritmo de decodificação:
1. Como parte da query — você especifica o algoritmo e seus parâmetros dentro da própria query. Segundo a documentação do LMQL, “isso pode ser particularmente útil se a escolha do decoder for relevante para o programa que você está escrevendo”. Veja como fica no código:
2. Externamente — você define o algoritmo e os parâmetros de decodificação fora do programa em si, ou seja, separadamente. Observação: isso só é possível quando o LMQL é usado em um contexto Python
Model
Os desenvolvedores definem o LMQL como uma “linguagem de alto nível e front-end para geração de texto”. Isso quer dizer que ele não é específico de um único modelo. Em vez disso, dá suporte a vários modelos de geração de texto no backend, como
OpenAI model,llama.cppeHuggingFace Transformers.Carregar modelos é bem direto. Você pode usar a função
lmql.model(...), que produz um objeto lmql.LMM.Exemplo:
Depois que o objeto
lmql.LLMé criado, você pode passá-lo ao programa de query de duas maneiras:1. Especificando o modelo externamente
2. Usando uma query com cláusula
fromConstraints
Um dos grandes atrativos do LMQL é o componente de constraints (restrições). Com elas, você pode impor condições sobre a saída do modelo de linguagem. Isso ajuda no prompting roteirizado, garantindo que a saída termine no ponto certo e dando controle sobre o modelo durante a decodificação.
As constraints suportadas incluem:
Confira a página de Constraints na documentação do LMQL para saber mais.
Distribution
A instrução de distribuição é um componente-chave no LMQL. Ela controla o formato e a estrutura da saída, definindo como os resultados gerados são distribuídos e apresentados.
Veja um exemplo na prática:
Limitações do LMQL e suporte da comunidade
Como toda tecnologia, o LMQL tem algumas limitações. Por exemplo:
Embora esses pontos possam ser impeditivos para quem está considerando usar o LMQL, é importante lembrar que a biblioteca ainda é nova e está em desenvolvimento — essas limitações podem ser resolvidas em versões futuras.
Conclusão
O LMQL é uma linguagem de programação ao estilo SQL e também um superconjunto de Python. Ele simplifica a extração de informações e a geração de respostas de LLMs ao combinar elementos declarativos com uma sintaxe imperativa de script. Desenvolvedores podem usar o LMQL para controlar a geração de texto com eficiência, tornando-o uma ferramenta valiosa para diversas aplicações no setor de tecnologia.
Para continuar aprendendo, veja também: