curso
Criando interfaces de usuário para aplicativos de IA com Gradio em Python
A utilidade dos modelos de IA atuais é muito reduzida sem interfaces de usuário acessíveis. Usando o Gradio, uma biblioteca de interface do usuário da Web Python de código aberto, você pode preencher essa lacuna entre os LLMs e os usuários finais não técnicos. Ele permite que você crie protótipos rápidos para seus projetos de IA e simplifique a implantação deles para um público mais amplo.
Este tutorial é voltado para engenheiros de machine learning que normalmente não têm experiência em desenvolvimento web. Ele aborda os conceitos básicos e fundamentais do Gradio, a criação de interface para vários tipos de modelos de IA, recursos avançados para UX e interatividade, além de práticas recomendadas de implantação e compartilhamento.
Vamos começar.
Primeiros passos com o Gradio
Instalação
Para começar, criaremos um ambiente virtual (de preferência Conda):
$ conda create -n gradio_tutorial python=3.9 -y
$ conda activate gradio_tutorial
Em seguida, você pode usar o PIP para instalar o Gradio e suas dependências:
$ pip install gradio ipykernel
Também instalamos o pacoteipykernel para que você possa exibir as interfaces do Gradio diretamente nos notebooks Jupyter. Esse processo exige que você adicione o ambiente virtual que criou como um kernel ao Jupyter Lab. Aqui está o comando para você fazer isso:
$ ipython kernel install --user --name=gradio_tutorial
$ jupyter lab # Start the lab
Isso deve permitir que você crie um notebook com um kernel que tenha o Gradio instalado. Para verificar, importe-o com seu alias padrão e imprima sua versão:
import gradio as gr
print(gr.__version__)
4.37.1
Conceitos básicos e terminologia
Vamos nos aprofundar no Gradio, aprendendo seus principais conceitos e terminologia por meio de um exemplo "Hello World":
def greet(name):
return f"Hello, {name}!"
demo = gr.Interface(
fn=greet,
inputs=['text'],
outputs="text",
)
demo.launch()
Quando você executar o código acima em uma célula, o resultado será uma pequena interface interativa que retorna uma mensagem de saudação personalizada:
O Gradio gira em torno de alguns conceitos-chave:
- InterfaceInterface: a classe principal para a criação de interfaces de usuário.
- Componentes: Elementos de entrada e saída, como caixas de texto, imagens e áudio. No momento, há mais de 30 componentes integrados.
- Funções: Funções Python que processam as informações dos componentes de entrada e retornam os resultados para que você os exiba nos componentes de saída.
- Lançamento: O método para iniciar o aplicativo Gradio.
Acima, criamos uma funçãogreet que recebe e retorna uma entrada de texto. Por esse motivo, os componentes de entrada e saída são especificados como text dentro da classeInterface.
No final, estamos chamando o métodolaunch, que inicia um servidor local. Para tornar a interface do usuário disponível para qualquer pessoa, você pode definir o parâmetro share como True. Isso iniciará um túnel SSH e implantará o aplicativo Gradio em uma página da Web compartilhável publicamente:
demo.launch(share=True)
Running on public URL: https://d638ed5f2ce0044296.gradio.live
This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run gradio deploy from Terminal to deploy to Spaces (https://huggingface.co/spaces)
Componentes do Gradio
Você passará a maior parte do tempo mexendo em diferentes componentes e como colocá-los na página durante a criação de aplicativos Gradio. Então, vamos dar uma olhada mais de perto no que você tem à sua disposição.
Componentes de entrada e saída
O Gradio oferece uma ampla gama de componentes para a criação de interfaces interativas. Esses componentes geralmente são divididos em duas categorias: entrada e saída.
Os componentes de entrada permitem que os usuários forneçam dados ao processador subjacente (pode ser qualquer função Python). Algumas entradas comuns são:
- Caixa de texto
- Imagem
- Áudio
- Controle deslizante
- Menu suspenso
Aqui está uma interface fictícia que usa alguns dos componentes acima:
def process_inputs(text, image, audio, number, option):
# Process inputs and return results
return f"Processed: {text}, {number}, {option}"
demo = gr.Interface(
fn=process_inputs,
inputs=[
gr.Textbox(label="Enter text"),
gr.Image(label="Upload image"),
gr.Audio(label="Upload audio"), # Uncomment this line to add audio input
gr.Slider(0, 100, label="Choose a number"),
gr.Dropdown(["Streamlit", "Taipy", "Gradio"], label="Select a UI library"),
],
outputs="text",
)
demo.launch()
Neste exemplo, a funçãoprocess_inputs requer cinco parâmetros. Portanto, precisamos criar cinco componentes de entrada e passá-los para inputs. Embora o número de componentes de entrada deva corresponder ao número de parâmetros de função necessários, essa não é uma regra rígida. Para evitar erros e avisos, defina valores padrão para parâmetros que não exijam entrada do usuário na interface do usuário.
Observe como estamos usando uma classe Textbox para especificar o componente de entrada em vez de um texto de string simples como no primeiro exemplo. É sempre recomendável usar classes dedicadas para especificar os componentes de entrada e saída para torná-los personalizáveis. Por exemplo, todas as classes de componentes têm um atributo útil derótulo , enquanto Slider e Dropdown têm argumentos para especificar o intervalo e as opções disponíveis.
Muitos componentes de entrada também podem ser usados para exibir a saída. Aqui estão alguns cenários comuns:
- Etiqueta: Para exibir texto ou resultados de classificação
- Imagem: Para exibir imagens processadas ou geradas
- Áudio: Para reproduzir áudio processado ou gerado
- Plot: Para exibir gráficos ou tabelas
Assim como as entradas, o número de componentes de saída deve corresponder ao número de valores retornados da função de processamento.
Personalização da aparência do componente
O Gradio permite que você personalize a aparência dos seus componentes para atender às suas necessidades. Aqui está um exemplo que usa caixas de texto personalizadas:
demo = gr.Interface(
fn=lambda x: int(x) ** 7,
inputs=gr.Textbox(
lines=5,
placeholder="Enter any number...",
label="Custom textbox",
info="This is a customized textbox component to raise any number to the power of 7.",
),
outputs=gr.Textbox(label="And the number is...", show_copy_button=True),
)
demo.launch()
Neste exemplo, personalizamos os componentes do Textbox especificando o número de linhas, adicionando um espaço reservado e um texto informativo e incluindo um botão de cópia para a saída.
Faça experiências com diferentes componentes e suas propriedades para criar interfaces que melhor atendam aos requisitos do seu aplicativo de IA. Para saber que tipo de propriedades você pode alterar no seu componente, visite a documentação dele ou, melhor ainda, use o operando ? no Jupyter Lab após o nome da classe:
Criando interfaces para LLMs
Vamos juntar tudo o que aprendemos criando duas interfaces baseadas em texto e imagem do mundo real que são alimentadas por LLMs.
Primeiro, criaremos um tradutor de idiomas do inglês para o turco, espanhol ou chinês:
import openai # pip install openai
def translate_text(api_key, text, target_language):
openai.api_key = api_key # Set openai API key
language_map = {
"Turkish": "Turkish",
"Spanish": "Spanish",
"Chinese": "Chinese (Simplified)",
}
prompt = f"Translate the following English text to {language_map[target_language]}:\n\nEnglish: {text}\n\n{target_language} translation:"
try:
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a professional translator."},
{"role": "user", "content": prompt},
],
)
translation = response.choices[0].message.content.strip()
return translation
except Exception as e:
return f"Error: {str(e)}"
Inicialmente, definimos uma funçãotranslate_text. Em seu corpo, definimos a chave da API da OpenAI e criamos um mapa de idiomas. Em seguida, criamos o prompt para tradução. Em seguida, dentro de um bloco try-except , enviamos uma solicitação ao ponto de extremidadeChatCompletion com um prompt do sistema. No final, retornamos a primeira opção.
Agora, podemos criar a interface:
iface = gr.Interface(
fn=translate_text,
inputs=[
gr.Textbox(
placeholder="Enter your OpenAI API key",
type="password",
label="OpenAI API Key",
),
gr.Textbox(
lines=4,
placeholder="Enter English text to translate...",
label="English Text",
),
gr.Dropdown(choices=["Turkish", "Spanish", "Chinese"], label="Target Language"),
],
outputs=gr.Textbox(label="Translation", show_copy_button=True),
title="English to Turkish/Spanish/Chinese Translator",
description="Translate English text to Turkish, Spanish, or Chinese using OpenAI's GPT-4 model. Enter your OpenAI API key, the text you want to translate, and select the target language.",
)
iface.launch(share=True)
O código é simples, como os das interfaces anteriores, mas estamos introduzindo algumas propriedades novas:
- type de caixas de texto altera o campo de entrada de texto simples para entrada de senha, ocultando o texto.
- título e descrição argumentos de classe Interface adiciona um título H1 e um subtítulo na parte superior central da página.
Aqui está o resultado:
Você pode se perguntar por que estamos solicitando a chave de API do usuário como parte do aplicativo em vez de fornecê-la nós mesmos. O motivo tem a ver com a forma como o Gradio implementa as UIs.
Se fornecêssemos nossa própria chave de API como uma variável de ambiente (que é a prática padrão), a versão do aplicativo compartilhável publicamente não funcionaria, pois não teria acesso às nossas variáveis de ambiente. Na seção de implantação, veremos como corrigir isso implantando nossos aplicativos nos espaços do HuggingFace.
Vamos criar outra interface do usuário para gerar imagens:
def generate_surrealist_art(api_key, prompt):
surrealist_prompt = f"Create a surrealist artwork based on the following concept: {prompt}. The artwork should be dreamlike, with unexpected juxtapositions and a sense of the uncanny."
client = OpenAI(api_key=api_key)
response = client.images.generate(
model="dall-e-3",
prompt=surrealist_prompt,
size="1024x1024",
)
image_url = response.data[0].url
return image_url
Criamos uma função chamada generate_surrealist_art que envia uma solicitação para dall-e-3 e retorna o URL da imagem gerada usando um prompt surrealista. Em seguida, alimentaremos essa função em uma classede interface novamente:
iface = gr.Interface(
fn=generate_surrealist_art,
inputs=[
gr.Textbox(
placeholder="Enter your OpenAI API key",
type="password",
label="OpenAI API Key",
),
gr.Textbox(
lines=2,
placeholder="Describe your surrealist concept...",
label="Concept Description",
),
],
outputs=gr.Image(value="str"),
title="Surrealist Artwork Generator",
description="Generate surrealist artwork based on your prompts using DALL-E. Enter your OpenAI API key and describe your concept.",
)
iface.launch(share=True)
Especificamos duas entradas para a chave da API e o conceito que queremos capturar em uma imagem surrealista. Em seguida, criamos um componente de saída para a imagem gerada com a classe Image. Se você definir o argumento value como str, o componente poderá fazer download e exibir imagens de URLs, que é exatamente o que precisamos.
E aqui está o resultado:
Criando interfaces para modelos clássicos de ML
Agora, vamos criar uma interface para um modelo de regressão tabular clássico. Usaremos o conjunto de dados Diamonds, que está disponível no Seaborn.
Comece criando um novo diretório de trabalho e um novo script chamado app.py dentro dele. Em seguida, cole o código de este gist do GitHub que carrega os dados, processa-os usando um pipeline do Scikit-learn e treina um modeloRandomForestRegression.
A próxima etapa é criar uma função de processamento que aceite o mesmo número de entradas que o número de recursos no conjunto de dados Diamonds:
# Create the Gradio interface
def predict_price(carat, cut, color, clarity, depth, table, x, y, z):
input_data = pd.DataFrame(
{
"carat": [carat],
"cut": [cut],
"color": [color],
"clarity": [clarity],
"depth": [depth],
"table": [table],
"x": [x],
"y": [y],
"z": [z],
}
)
prediction = model.predict(input_data)[0]
return f"Predicted Price: ${prediction:.2f}"
A função converte essas entradas em um DataFrame e o passa para o método.predict() do pipeline do modelo treinado. No final, ele retorna uma string com o preço previsto.
Agora, a Interface deve corresponder à assinatura dessa função: nove componentes de entrada para processar os recursos e uma saída para exibir o preço previsto:
iface = gr.Interface(
fn=predict_price,
inputs=[
gr.Slider(
minimum=diamonds["carat"].min(),
maximum=diamonds["carat"].max(),
label="Carat",
),
gr.Dropdown(["Fair", "Good", "Very Good", "Premium", "Ideal"], label="Cut"),
gr.Dropdown(["D", "E", "F", "G", "H", "I", "J"], label="Color"),
gr.Dropdown(
["I1", "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"], label="Clarity"
),
gr.Slider(
minimum=diamonds["depth"].min(),
maximum=diamonds["depth"].max(),
label="Depth",
),
gr.Slider(
minimum=diamonds["table"].min(),
maximum=diamonds["table"].max(),
label="Table",
),
gr.Slider(minimum=diamonds["x"].min(), maximum=diamonds["x"].max(), label="X"),
gr.Slider(minimum=diamonds["y"].min(), maximum=diamonds["y"].max(), label="Y"),
gr.Slider(minimum=diamonds["z"].min(), maximum=diamonds["z"].max(), label="Z"),
],
outputs="text",
title="Diamond Price Predictor",
description="Enter the characteristics of a diamond to predict its price.",
)
iface.launch(share=True)
Dentro da classe, criamos três menus suspensos para os recursos categóricos. As opções são preenchidas com as categorias exclusivas de cada recurso. Também criamos seis componentes de controle deslizante para aceitar recursos numéricos. Os intervalos dos controles deslizantes são determinados pelos valores mínimo e máximo de cada recurso.
Tudo o que precisamos fazer agora é executar o script para executar e implantar o aplicativo:
$ python app.py
Aqui está o resultado:
Para obter dicas de práticas recomendadas e otimização, vá para a seção Práticas recomendadas abaixo.
Implantação de aplicativos Gradio
Já vimos como é fácil implantar aplicativos Gradio habilitando um único argumento. Obviamente, a desvantagem desse método é que as demonstrações expiram em 72 horas. Portanto, o método recomendado de implementação do Gradio é por meio do HuggingFace Spaces. A HuggingFace adquiriu a Gradio em 2021, tornando a integração entre as duas plataformas perfeita.
Portanto, para este tutorial ou para qualquer aplicativo futuro que você criar com o Gradio, inscreva-se para obter uma conta gratuita em huggingface.co e navegue até Configurações > Tokens para você gerar um token de acesso:
O token é exibido apenas uma vez, portanto, certifique-se de armazená-lo em um local seguro.
Com esse token, você pode implantar quantos aplicativos Gradio quiser com hospedagem permanente no Spaces. Como exemplo, implantaremos o modelo de previsão de preços de diamantes da seção anterior, e você verá que é surpreendentemente fácil.
Tudo o que você precisa fazer é navegar até o diretório com o script da interface do usuário e chamar gradio deploy no terminal:
O terminal orienta você na conversão do seu script em um HuggingFace Space funcional. Ele solicita detalhes como:
- O token de acesso que você gerou
- Título do espaço: isso fará parte da URL do espaço após a implantação
- O nome do script que contém o código da interface do usuário do Gradio (app.py padrão)
- Hardware do espaço; deixe em branco para usar apenas CPUs (livre)
- Quaisquer variáveis de ambiente que o script use (é aqui que você armazena chaves de API e segredos de usuário com segurança)
- Dependências - insira uma a uma pressionando ENTER
E o terminal apresenta a você um link implantado do Space. Aqui está o que você vê:
Outra coisa excelente sobre esse método de implantação é que o Gradio converte automaticamente a demonstração em uma API REST funcional. As instruções para acessá-lo e consultá-lo estão sempre localizadas na parte inferior:
Assim, de uma só vez, você tem a hospedagem permanente da interface do usuário do seu aplicativo para usuários não técnicos e uma API REST para seus colegas e amigos desenvolvedores.
Para obter mais opções de implantação e compartilhamento, como incorporação de demonstrações em páginas da Web, adição de autenticação do Google a aplicativos, etc., visite a página "Compartilhando seu aplicativo" da documentação do Gradio.
Práticas recomendadas e dicas do Gradio
Ao desenvolver interfaces de usuário com o Gradio, seguir as práticas recomendadas pode melhorar significativamente a experiência do usuário e a capacidade de manutenção do seu aplicativo. Aqui estão algumas recomendações importantes:
1. Use scripts para organização e manutenção
Organize os aplicativos Gradio em scripts Python para melhor controle de versão, colaboração e implantação.
2. Otimizar a alocação de espaço para os componentes
Use ferramentas de dimensionamento e layout adequadas (por exemplo, gr.Column(), gr.Row()) para garantir uma interface equilibrada e responsiva.
3. Fornecer informações abrangentes
Utilize os atributos "info" e "label" para fornecer instruções e contexto claros para cada componente.
4. Lidar com grandes conjuntos de recursos de forma eficiente
Para modelos com muitos recursos, use entradas de arquivo (CSV, JSON) para permitir previsões em lote e simplificar a interface.
5. Gerenciar adequadamente as variáveis de ambiente
Use o python-dotenv para desenvolvimento local e defina variáveis no Hugging Face Spaces para implantação.
6. Implementar tratamento e validação de erros
Valide as entradas, forneça mensagens de erro claras e use blocos try-except para o tratamento de erros.
7. Otimizar o desempenho
Implemente o armazenamento em cache, o carregamento preguiçoso para modelos grandes e use gr.LoadingStatus() para tarefas de longa duração.
8. Design para acessibilidade
Garanta alto contraste, forneça texto alternativo para as imagens e habilite a navegação pelo teclado para todos os elementos interativos.
9. Implementar a divulgação progressiva
Use acordeões ou guias para organizar interfaces complexas, revelando opções avançadas conforme necessário.
10. Atualizar e manter regularmente
Mantenha as dependências atualizadas, monitore a existência de bugs e melhore continuamente com base no feedback do usuário.
11. Aproveite os recursos do HuggingFace
Utilize as ferramentas e os recursos do HuggingFace para uma integração perfeita com o Gradio, incluindo repositórios de modelos e conjuntos de dados.
12. Hospede modelos grandes no HuggingFace Hub
Para modelos tabulares grandes, faça upload para o HuggingFace Hub e carregue diretamente em seu script Gradio para melhorar o desempenho e reduzir os requisitos de armazenamento local.
13. Utilize os conjuntos de dados do HuggingFace
Para grandes conjuntos de dados, faça o upload para o HuggingFace Hub e acesse-os diretamente no seu aplicativo Gradio para simplificar o gerenciamento de dados e melhorar os tempos de carregamento.
Conclusão e recursos adicionais
Neste artigo, aprendemos os conceitos básicos da criação de interfaces de usuário para aplicativos de IA usando o Gradio. Você acabou de mergulhar na superfície, pois o Gradio oferece muitos outros recursos para a criação de interfaces complexas. Por exemplo, estado da interface permite que seu aplicativo se lembre das saídas de uma chamada de função para outra. Interfaces reativas alteram dinamicamente a interface do usuário assim que a entrada do usuário é alterada. Com Blocosvocê pode criar aplicativos com layouts e designs personalizados.
Da mesma forma, confira estes recursos relacionados para obter mais conteúdo:
Principais cursos da DataCamp
programa
Developing Large Language Models
curso
Developing LLM Applications with LangChain
blog
Python no setor de saúde: Aplicativos de IA em hospitais
Armstrong Asenavi
18 min
tutorial
Criando um transformador com o PyTorch
tutorial
Como criar aplicativos LLM com o tutorial LangChain
tutorial
Guia de torchchat do PyTorch: Configuração local com Python
François Aubry
tutorial
Criando agentes LangChain para automatizar tarefas em Python
tutorial