Programa
A Microsoft lançou três modelos prontos para produção sob a sigla MAI (Microsoft AI): MAI-Transcribe-1 para speech-to-text, MAI-Voice-1 para text-to-speech e MAI-Image-2 para geração de imagens a partir de texto. Os três estão disponíveis no Microsoft Foundry, com acesso real de API.
Neste tutorial, vamos fazer duas coisas: primeiro, ver como provisionar e conectar cada modelo via Azure. Depois, vamos criar um app em Streamlit que testa os três modelos com prompts reais e chamadas de API.
Ao final, você será capaz de:
- Provisionar MAI-Transcribe-1, MAI-Voice-1 e MAI-Image-2 no Azure
- Entender os principais benchmarks e o que eles realmente significam
- Chamar os três modelos a partir de Python via uma interface em Streamlit
- Conhecer os principais recursos e limitações de cada modelo antes de decidir construir em cima deles
O código completo está disponível no repositório no GitHub.
O que são os modelos Microsoft MAI?
A família de modelos MAI da Microsoft é desenvolvida pelo time Microsoft AI Superintelligence. São modelos totalmente internos, treinados na própria infraestrutura da Microsoft, otimizados para a pilha de serving da empresa e disponibilizados diretamente pelo Azure. MAI-Transcribe-1 e MAI-Voice-1 rodam na mesma infraestrutura do Azure Speech que já atende clientes corporativos em escala, enquanto o MAI-Image-2 usa uma arquitetura de difusão com flow-matching e o mesmo objetivo de treinamento do Stable Diffusion 3, com entre 10 e 50 bilhões de parâmetros (excluindo embeddings).
Aqui vai um resumo rápido dos três:
|
Modelo |
Tarefa |
Número-chave |
Preço |
|
MAI-Transcribe-1 |
Fala para texto |
WER médio de 3,88% no FLEURS |
US$0,36/h |
|
MAI-Voice-1 |
Texto para fala |
60s de áudio em 1s |
US$22/1M de caracteres |
|
MAI-Image-2 |
Texto para imagem |
Elo 1190 geral |
US$5/1M tokens de texto + US$33/1M tokens de imagem |
Vamos nos aprofundar em cada um antes de construir.
MAI-Transcribe-1
O MAI-Transcribe-1 é um modelo de speech-to-text com suporte a 25 idiomas. Seu destaque é a taxa média de erro por palavra (WER) de 3,88% no benchmark FLEURS — quanto menor, melhor. Esse resultado o coloca à frente de GPT-Transcribe (4,17%), Scribe v2 (4,32%), Gemini 3.1 Flash-Lite (4,89%) e Whisper-large-v3 (7,60%).
O modelo foi feito para áudios do mundo real, com ruído, sotaques mistos e fala natural. A Microsoft também afirma que o MAI-Transcribe-1 entrega boa acurácia com cerca de 50% menos custo de GPU do que alternativas líderes — uma vantagem relevante para empresas que rodam transcrição em escala.
Ainda assim, faltam transcrição em tempo real, diarização de falantes e viés de contexto, todos listados como "em breve".
MAI-Voice-1
O MAI-Voice-1 é o modelo TTS de alta fidelidade da Microsoft. Seu recurso-chave é o voice prompting: você envia um áudio de 10 segundos e o modelo clona essa voz sem fine-tuning. No entanto, a clonagem de voz exige aprovação controlada pela Microsoft; já a biblioteca de vozes curadas (nomes como en-us-Jasper:MAI-Voice-1, en-us-June:MAI-Voice-1) está disponível imediatamente.
O modelo gera 60 segundos de áudio em 1 segundo usando uma única GPU, suporta controle de emoção por turno via SSML e foi pensado para conteúdo de longa duração como audiolivros e podcasts. Ele já alimenta os recursos de Audio Expressions e podcasts do Copilot nos produtos da Microsoft.
Um ponto negativo é que ele é "apenas em inglês", com suporte a 10+ idiomas chegando em breve.
MAI-Image-2
O MAI-Image-2 usa uma arquitetura de difusão com flow-matching e 10–50 bilhões de parâmetros. Ele está entre os três primeiros no ranking de imagens do Arena.ai e é 2x mais rápido que o MAI-Image-1 em produção. O modelo foi desenvolvido em parceria com fotógrafos, designers e criadores visuais, e já está presente no Copilot, Bing Image Creator e PowerPoint. Foi especialmente projetado para fotorrealismo, tons de pele precisos e texto legível dentro da imagem.
Seus escores Elo por categoria incluem fotorrealismo (1201) e retratos (1201), onde ele se destaca; já a renderização de texto (1186) melhorou, mas ainda é a categoria mais fraca.
Configurando o Azure para todos os modelos
Os três modelos MAI estão disponíveis no Microsoft Azure. MAI-Transcribe-1 e MAI-Voice-1 compartilham o mesmo recurso Azure Speech, enquanto o MAI-Image-2 roda via Microsoft Foundry. Vamos configurar os dois, passo a passo.
Pré-requisitos
- Crie sua conta ou faça login no Azure para ganhar US$200 de crédito gratuito
- Python 3.9+
Passo 1: crie um recurso Azure Speech
Tanto o MAI-Transcribe-1 quanto o MAI-Voice-1 são acessados pelo serviço Azure AI Speech, então um único recurso atende aos dois.
-
Acesse o portal.azure.com
-
No campo de busca, digite Speech e selecione Speech services
-
Clique em + Create
-
Preencha o formulário:
-
Resource group: crie um novo grupo de recursos e nomeie como
mai-demo-rg -
Region: selecione
East USporque os modelos MAI, por enquanto, só têm suporte em East US e West US -
Name:
mai-speech-demo -
Pricing tier:
Standard S0 -
Observação: o plano Free F0 tem limites de taxa que podem interromper a demo
-
Por fim, clique em Review and create, e depois em Create.
Quando a implantação terminar, vá em Keys and Endpoint na barra lateral esquerda e copie a Key 1 e anote o valor de Region (eastus).

Passo 2: crie um recurso Foundry e faça o deploy do MAI-Image-2
O MAI-Image-2 é acessado via Microsoft Foundry, separado do portal padrão do Azure.

-
Na home do portal Azure, clique em Foundry na barra superior de serviços
-
Clique em Create a resource
-
Depois, preencha os dados a seguir:
-
Resource group: selecione o mesmo
mai-demo-rgdo Passo 1 -
Region: East US
-
Name:
mai-image-demo -
Default project name:
proj-default -
Em seguida, clique em Review and create, e depois em Create
-
Quando o recurso estiver ativo, clique em Go to Foundry portal.
-
No Foundry, clique em Model catalog na barra lateral

- Busque por
MAIe você verá os quatro modelos MAI listados

-
Selecione MAI-Image-2 e clique em Use this model
-
No diálogo de deploy, defina:
-
Deployment name:
MAI-Image-2 -
Deployment type:
Global Standard -
Por fim, clique em deploy

Após o deploy, você verá a página de detalhes. Copie o Target URI (algo como https://mai-image-demo.services.ai.azure.com/models) e a Key.
Passo 3: configure o arquivo .env
Crie um arquivo .env no diretório local do projeto e adicione os dados obtidos nos dois passos anteriores:
AZURE_SPEECH_KEY=your_speech_key_1_here
AZURE_SPEECH_REGION=eastus
AZURE_IMAGE_ENDPOINT=https://your-resource-name.services.ai.azure.com/models
AZURE_IMAGE_KEY=your_foundry_key_here
AZURE_IMAGE_DEPLOYMENT=MAI-Image-2
Observação importante: AZURE_IMAGE_DEPLOYMENT diferencia maiúsculas de minúsculas. Use exatamente MAI-Image-2, como aparece no Foundry; mai-image-2 em minúsculas retornará erro unknown_model.
Demo com os modelos MAI: crie um app de fala, voz e imagem com Streamlit
Nesta seção, vamos criar um app em Streamlit com três abas que chama os três modelos MAI via chamadas de API do Azure em tempo real. Em alto nível, o app faz:
- Aba 1: aceita um arquivo de áudio WAV, MP3 ou outro e envia ao MAI-Transcribe-1 via Azure Speech REST API, retornando a transcrição completa com métricas de latência e custo
- Aba 2: recebe um texto com escolha de voz e emoção, monta uma requisição SSML e chama o MAI-Voice-1 para retornar um MP3 reproduzível
- Aba 3: recebe um prompt de texto e a resolução, chama o MAI-Image-2 pelo endpoint do Azure Foundry e exibe a imagem gerada com opção de download
- O app também mostra estimativas de custo em tempo real para cada modelo conforme você configura as entradas
Estrutura de arquivos:
mai_demo/
├── app.py # UI em Streamlit
├── mai_clients.py # Wrappers de API do Azure
├── requirements.txt
└── .env
O app é dividido em dois arquivos: mai_clients.py, que realiza todas as chamadas à API do Azure e retorna dicts estruturados, e app.py, que cuida da interface em Streamlit. Vamos construir passo a passo.
Passo 1: instale as dependências
Diferente de um setup local de modelo, este app se conecta a APIs na nuvem do Azure, então as dependências incluem o Azure Speech SDK e bibliotecas de HTTP e imagem.
pip install -r requirements.txt
O arquivo requirements.txt contém:
.txt
streamlit>=1.35.0
azure-cognitiveservices-speech>=1.38.0
requests>=2.31.0
pillow>=10.0.0
python-dotenv>=1.0.0
openai>=1.30.0
Neste projeto, vamos usar:
-
streamlitpara a UI com três abas, upload de arquivos, players de áudio e renderização inline de imagens -
azure-cognitiveservices-speechcomo SDK do Azure Speech, para se comunicar com MAI-Transcribe-1 e MAI-Voice-1 -
requestspara fazer chamadas REST diretas aos três endpoints do Azure -
pillowpara decodificar e exibir os bytes de imagem retornados pelo MAI-Image-2 -
python-dotenvpara carregar as chaves do Azure e URLs de endpoint do arquivo.envem tempo de execução -
openaipara o SDK compatível com Azure OpenAI, que dá suporte aos endpoints de geração de imagem do Foundry
Depois de instalar, garanta que o arquivo .env esteja no mesmo diretório de app.py antes de rodar o app. O carregamento de credenciais acontece automaticamente na inicialização via python-dotenv.
Passo 2: construindo a camada cliente de API (mai_clients.py)
Todas as chamadas à API do Azure ficam em mai_clients.py, e cada função retorna um dicionário simples no formato {"success": bool, ...} para que a camada de UI não quebre em caso de erro.
MAI-Transcribe-1: fala para texto
O MAI-Transcribe-1 é acessado pelo endpoint LLM Speech da Azure Speech REST API. O ponto-chave é que ele recebe uma requisição multipart form com um arquivo de áudio e um objeto JSON de definição.
def transcribe_audio(audio_bytes: bytes, filename: str = "audio.wav") -> dict:
url = (
f"https://{speech_region}.api.cognitive.microsoft.com"
f"/speechtotext/transcriptions:transcribe?api-version=2024-11-15"
)
headers = {"Ocp-Apim-Subscription-Key": speech_key}
definition = '{"locales":["en-US"],"profanityFilterMode":"None"}'
files = {
"audio": (filename, audio_bytes, _mime_type(filename)),
"definition": (None, definition, "application/json"),
}
resp = requests.post(url, headers=headers, files=files, timeout=60)
data = resp.json()
combined = " ".join(
p.get("text", "") for p in data.get("combinedPhrases", [])
).strip()
return {"success": True, "transcript": combined, "raw": data, ...}
A resposta volta como um objeto JSON com combinedPhrases, um array de segmentos de texto. Nós unimos tudo em uma única string de transcrição. Os formatos de áudio suportados incluem WAV, MP3 e FLAC. A API, por ora, está restrita às regiões East US e West US.
MAI-Voice-1: texto para fala
O MAI-Voice-1 usa o TTS padrão do Azure Speech via SSML. O segredo é montar o bloco <mstts:express-as> para controle de emoção e referenciar o formato correto do nome da voz (en-us-Jasper:MAI-Voice-1).
def _build_ssml(text: str, emotion: str, voice_name: str) -> str:
style_map = {
"neutral": None,
"joy": "joy",
"excitement": "excitement",
"empathy": "empathy",
}
style = style_map.get(emotion)
text_block = (
text if style is None
else f"<mstts:express-as style='{style}'>{text}</mstts:express-as>"
)
return f"""<speak version='1.0' xml:lang='en-US'
xmlns='http://www.w3.org/2001/10/synthesis'
xmlns:mstts='http://www.w3.org/2001/mstts'>
<voice name='{voice_name}'>
{text_block}
</voice>
</speak>"""
Os nomes de voz disponíveis para MAI-Voice-1 seguem o padrão en-us-{Name}:MAI-Voice-1. A lista atual inclui Jasper, June, Grant, Iris, Reed e Joy.
MAI-Image-2: texto para imagem
O MAI-Image-2 usa um endpoint específico do Foundry, diferente do caminho padrão do Azure OpenAI /openai/deployments/. O formato correto é:
url = f"{base_endpoint}/mai/v1/images/generations"
Aqui, base_endpoint é a raiz do URL do recurso Foundry (por exemplo, https://your-resource.services.ai.azure.com), removendo qualquer /models no final antes de construir a requisição. O corpo da requisição tem dois requisitos: primeiro, passar explicitamente o campo model com o nome do seu deployment — diferente dos endpoints OpenAI padrão, onde o modelo é inferido pelo caminho da URL:
payload = { "model": deployment, # "MAI-Image-2" "prompt": prompt, "width": width, "height": height, }
Segundo, as dimensões da imagem têm restrições rígidas: width e height devem ter no mínimo 768 pixels, e o produto não pode ultrapassar 1.048.576 — o que dá no máximo 1024×1024 para imagens quadradas. Enviar 512×512 ou omitir dimensões retorna 400 Bad Request.
A resposta segue o formato padrão de geração de imagens do OpenAI. Cada item em data traz um url para uma imagem hospedada ou um b64_json com os bytes em base64. O cliente trata ambos os casos:
image_url = row.get("url")
b64 = row.get("b64_json")
if b64:
img_bytes = base64.b64decode(b64)
elif image_url:
img_resp = requests.get(image_url, timeout=30)
img_bytes = img_resp.content
Atenção: respostas com url têm tempo limitado, então precisamos buscar e armazenar os bytes imediatamente, em vez de guardar a URL para uso posterior.
Passo 3: construindo a UI no Streamlit (app.py)
O app é organizado em três abas, uma por modelo. Estrutura:
import streamlit as st
from mai_clients import transcribe_audio, synthesize_speech, generate_image
tab1, tab2, tab3 = st.tabs([
"🎙 MAI-Transcribe-1",
"🔊 MAI-Voice-1",
"🖼 MAI-Image-2",
])
Cada aba segue o mesmo padrão: entradas → botão → spinner → exibição do resultado → métricas de custo.
Aba 1: MAI-Transcribe-1
A primeira aba faz upload e transcrição do áudio. Ela aceita arquivos WAV, MP3 e FLAC, reproduz o áudio inline para você validar o teste e envia os bytes direto para transcribe_audio() ao clicar no botão.
with tab1:
audio_file = st.file_uploader("Upload audio file", type=["wav", "mp3", "flac"])
if audio_file:
st.audio(audio_file)
if st.button("Transcribe", type="primary"):
with st.spinner("Calling MAI-Transcribe-1..."):
result = transcribe_audio(audio_file.read(), audio_file.name)
if result["success"]:
st.text_area("Transcript", value=result["transcript"], height=140)
m1, m2, m3 = st.columns(3)
m1.metric("Latency", f"{result['latency_s']}s")
m2.metric("Audio duration", f"{result['duration_ms']/1000:.1f}s")
m3.metric("Est. cost", f"${result['duration_ms']/3_600_000 * 0.36:.5f}")
Com sucesso, a transcrição aparece em um campo de texto editável seguida de três métricas: latência da API em segundos, duração do áudio (a partir de durationMilliseconds) e o custo estimado calculado como duration_in_hours × US$0,36.
Um clipe de 7 segundos custa cerca de US$0,0000007, então dá para rodar dezenas de testes sem mexer de verdade no seu crédito do Azure.
Aba 2: MAI-Voice-1
A segunda aba faz a síntese de texto em fala. Ela expõe os três controles que mais importam para testar o MAI-Voice-1: o texto, o estilo de emoção e a voz — todos passados diretamente para a função synthesize_speech().
with tab2:
text_input = st.text_area("Text to synthesize", value="The quarterly results exceeded...")
emotion = st.selectbox("Emotion / style", ["neutral", "joy", "excitement", "empathy"])
voice_name = st.selectbox("Voice", ["en-us-Jasper:MAI-Voice-1", "en-us-June:MAI-Voice-1", ...])
if st.button("Synthesize", type="primary"):
with st.spinner("Calling MAI-Voice-1..."):
result = synthesize_speech(text_input, emotion=emotion, voice_name=voice_name)
if result["success"]:
st.audio(result["audio_bytes"], format="audio/mp3")
O seletor de emoção mapeia para os estilos SSML <mstts:express-as>; neutral omite a tag para um baseline limpo, enquanto joy, excitement e empathy geram perfis de ritmo e tom perceptivelmente diferentes. O dropdown cobre as seis vozes disponíveis: Jasper, June, Grant, Iris, Reed e Joy.
Com sucesso, os bytes MP3 retornados são enviados direto ao st.audio() para reprodução inline. Com 113 caracteres, o custo estimado é de US$0,000002 — dá para fazer vários testes sem gastar muitos créditos.
Aba 3: MAI-Image-2
A terceira aba lida com texto para imagem. A API atual do MAI-Image-2 expõe dois parâmetros de entrada: prompt e resolução. Não há níveis de qualidade ou controles de estilo — o modelo define isso internamente.
with tab3:
prompt = st.text_area("Image prompt", value="A worn paperback book on a café table...")
size = st.selectbox("Resolution", ["1024x1024", "1365x768", "768x1365"])
if st.button("Generate", type="primary"):
with st.spinner("Calling MAI-Image-2..."):
result = generate_image(prompt, size=size)
if result["success"]:
img = Image.open(io.BytesIO(result["image_bytes"]))
st.image(img, use_container_width=True)
As três opções de resolução cobrem os principais formatos: quadrado (1024×1024), paisagem (1365×768) e retrato (768×1365). A string de tamanho é convertida em inteiros de largura e altura antes de enviar para a API, já que o endpoint do Foundry recebe campos separados.
Com sucesso, os bytes brutos são embrulhados em um buffer BytesIO, abertos com Pillow e renderizados em largura total do container. A geração costuma levar de 2 a 4 segundos, visivelmente mais rápida que o MAI-Image-1 no mesmo ambiente.
Passo 4: rodando o app
Com o .env configurado e as dependências instaladas, você já pode executar o app.
streamlit run app.py
O Streamlit iniciará um servidor local e abrirá o app no navegador em http://localhost:8501. Você verá a interface com três abas, com o MAI-Transcribe-1 ativo por padrão.

Testando os modelos
Veja o que os modelos geraram nos nossos testes.
Teste 1: transcrição de áudio com ruído
Testei o MAI-Transcribe-1 com um clipe de 7 segundos gravado em um ambiente propositalmente ruidoso, com sotaque indiano. O modelo retornou uma transcrição limpa e precisa em menos de 2 segundos.
Insight: O resultado se manteve bom com fala sotaqueada, onde o Whisper-large-v3 costuma sofrer mais. Dito isso, números por idioma contam outra história: árabe fica em 10,1% e dinamarquês em 13,2% — bem acima do número de destaque. Se seu caso de uso envolve um idioma específico ou distribuição regional de sotaques, teste com seu áudio real antes de levar para produção.
Teste 2: controle de emoção
Eu sintetizei uma frase de 113 caracteres no estilo excitement usando a voz en-us-Jasper:MAI-Voice-1, e o modelo retornou um MP3 de 6 segundos em menos de 1 segundo. A emoção ficou clara no resultado, com ritmo mais energético e maior variação de pitch.

Insight: Um clipe de 6 segundos gerado em menos de 1 segundo é impressionante. O controle de emoção via SSML funciona, mas está limitado a quatro estilos: neutral, joy, excitement e empathy. Não espere a gama completa de expressões que você encontra na biblioteca de estilos da ElevenLabs.
Teste 3: fotorrealismo e renderização de texto
Este é o teste mais interessante porque escolhi um prompt que combina duas coisas: composição de cena fotorrealista e texto dentro da imagem. A maioria dos modelos de difusão falha em pelo menos um desses pontos.
Prompt: "A worn paperback book on a café table, natural window light, steam rising from an espresso cup beside it. The book cover reads: INFERENCE AT SCALE — text clearly legible, not warped."

Insight: O fotorrealismo é realmente forte — luz natural de janela, vapor convincente e textura crível no livro e na xícara. O texto "INFERENCE AT SCALE" também saiu corretamente e legível.
No entanto, a renderização de texto é inconsistente entre execuções. Em várias gerações com prompts semelhantes, o modelo ocasionalmente gerou palavras com erros ou embaralhadas. Esse é um modo de falha conhecido nos modelos de difusão atuais; o MAI-Image-2 é melhor que a maioria, mas não é imune. Além disso, a resolução máxima atual é 1024×1024 pixels — suficiente para web e conteúdo, mas insuficiente para impressão ou formatos grandes sem um passo de upscaling. Se você gera imagens em que a precisão do texto é crítica, inclua sempre uma revisão humana.
Conclusão
A família de modelos MAI da Microsoft é realmente impressionante. Os números do MAI-Transcribe-1 no FLEURS são os mais fáceis de verificar e sustentam um WER médio de 3,88%, referência de mercado até o momento desta publicação.
O MAI-Voice-1 impressiona em velocidade e qualidade de voz, mas é limitado ao inglês e tem paleta de emoções restrita. O MAI-Image-2 gera imagens fotorrealistas muito boas, com a ressalva de que alucinações de texto ainda acontecem e exigem revisão humana em produção.
O código completo deste tutorial está no GitHub.
Sou Especialista Google Developers em ML (Gen AI), tricampeã no Kaggle e Embaixadora Women Techmakers, com mais de três anos de experiência na área de tecnologia. Cofundei uma startup de saúde em 2020 e atualmente faço um mestrado em ciência da computação na Georgia Tech, com foco em aprendizado de máquina.
FAQs
Preciso de uma conta paga do Azure para usar os modelos MAI?
Novas contas do Azure vêm com US$200 em crédito gratuito, e contas Azure for Students incluem US$100. Como uma sessão completa de demo com os três modelos custa bem menos de US$0,01, esse crédito é mais do que suficiente para começar. Você precisará migrar para uma conta paga se planeja usar os modelos em produção e em escala.
Posso usar o MAI-Transcribe-1 para transcrição em tempo real em um agente de voz?
Ainda não. O MAI-Transcribe-1 funciona apenas em modo batch: você envia um arquivo de áudio completo e recebe a transcrição de volta. Se tempo real for um requisito rígido, mantenha o Whisper ou a oferta de tempo real já existente do Azure Speech como alternativa enquanto aguarda.
Por que o MAI-Image-2 às vezes erra a ortografia em textos gerados nas imagens?
Essa é uma limitação conhecida dos modelos de geração de imagem baseados em difusão, não específica do MAI-Image-2. O modelo gera imagens transformando ruído em pixels, então não possui entendimento explícito de ortografia ou sequências de caracteres como um modelo de linguagem tem. O MAI-Image-2 lida com texto significativamente melhor que seu antecessor (Elo 1186 vs 1069), mas inconsistências ainda ocorrem, especialmente com palavras longas ou fontes estilizadas. Ter uma revisão humana do texto gerado é uma boa prática antes de usar essas imagens em produção.
Posso clonar qualquer voz com o MAI-Voice-1?
A clonagem de voz pelo recurso Personal Voice exige uma amostra de 10 segundos da voz do talento e consentimento gravado explícito dessa pessoa. O acesso é controlado, então você precisa enviar uma solicitação de aprovação pelo processo de Limited Access Review da Microsoft.



