Eu gosto de projetos que parecem improváveis no começo. Este foi um deles. A ideia era portar o modelo de inpainting de imagens Moebius 0.2B para rodar direto no navegador, sem depender do ambiente original em PyTorch com NVIDIA CUDA. Em vez de ficar preso ao desktop ou a uma GPU específica, o alvo passou a ser WebGPU, com execução em navegadores como Chrome, Firefox e Safari.
Inpainting é o processo de selecionar uma área da imagem e pedir ao modelo que complete aquele espaço com conteúdo coerente.
Na prática, isso significa remover um objeto, preencher um fundo ausente ou reconstruir uma parte da cena. Eu já tinha visto muitos fluxos assim rodando localmente, mas queria observar até onde dava para chegar num modo mais próximo do que a Replitfy chama de AI-Building: pegar uma ideia, estruturar um plano e transformar isso em produto funcional com apoio forte de IA.
O ponto de partida foi simples. Antes de escrever qualquer coisa, eu pedi ao Claude.ai uma análise de viabilidade. Minha pergunta era objetiva: existe um caminho realista para fazer esse modelo sair de PyTorch e CUDA e chegar ao navegador com WebGPU? A resposta veio com uma rota plausível. A proposta era clonar o repositório original no GitHub, entender como o modelo era carregado e testar a conversão para ONNX, para depois rodar tudo com ONNX Runtime Web sobre WebGPU.
O primeiro ganho veio antes do código: confirmar que havia uma trilha técnica viável.
Começando pelo que era possível
Eu iniciei o trabalho num diretório temporário em /tmp. Fiz isso porque queria um espaço limpo para experimentar sem carregar resíduos de testes anteriores. Depois, inicializei o git e pedi ao Claude Code que começasse lendo o material de referência do repositório e organizasse o trabalho em dois arquivos simples: plan.md e notes.md.
Essa decisão ajudou bastante. O plan.md serviu para listar etapas, hipóteses e travas técnicas. O notes.md virou o diário do projeto, com descobertas, erros, suposições e mudanças de direção. Ao longo do processo, esses dois arquivos foram atualizados várias vezes. Eu gostei disso porque criou uma trilha clara do raciocínio, algo que combina muito com a formação prática proposta pela Replitfy.
No começo, minhas instruções para o Claude como agente de programação eram curtas:
Fazer commits frequentes;
Registrar descobertas relevantes em notes.md;
Não sair alterando tudo sem antes validar a hipótese;
Priorizar um demo funcional antes de qualquer acabamento.
Eu acho que esse tipo de direção simples funciona bem. Em vez de microgerenciar cada arquivo, eu preferi manter o foco no comportamento esperado. Isso deixou o processo perto do que muita gente hoje chama de vibe coding. Eu não entrei fundo em cada detalhe de WebGPU, ONNX ou do próprio Moebius. Meu papel foi mais de definir o rumo, testar, apontar erros e pedir ajustes.
Primeiro, provar que roda.
Da dependência de CUDA para o navegador
O obstáculo inicial era claro. O modelo original estava pensado para PyTorch e aceleração com CUDA. Isso limita o público e dificulta o uso client-side. Para quebrar essa barreira, a melhor alternativa encontrada foi a exportação para ONNX.
ONNX funciona como um formato portável para representar redes neurais, com grafo computacional e pesos aprendidos no mesmo pacote lógico.
Eu pedi ao Claude para localizar no repositório pontos de exportação e também verificar se o projeto já trazia algum script próximo disso. O resultado foi animador. Havia base suficiente para montar um fluxo de exportação, inclusive com referência ao script export_onnx.py. Isso importou bastante, porque mostrou que PyTorch não estava sendo abandonado. Ele continuava sendo a origem do modelo, mas deixava de ser o ambiente obrigatório para inferência final no navegador.
Em termos simples, o caminho ficou assim:
Clonar o repositório do modelo original;
Estudar entradas, saídas e pré-processamento;
Exportar o modelo de PyTorch para ONNX;
Adaptar a interface web para carregar o arquivo ONNX;
Executar a inferência com WebGPU no navegador.
Esse desenho parece linear quando eu conto agora. Na hora, não foi. Houve idas e vindas. Às vezes a exportação funcionava, mas a inferência no navegador falhava por incompatibilidade de forma, tipo de tensor ou caminho de arquivo. Em outros momentos, a interface abria, mas não encontrava os pesos corretos.

Claude Code como agente de programação
Eu não editei diretamente o código do modelo. Isso é um detalhe que muda bastante a leitura do projeto. Meu contato foi por testes funcionais, pedidos de ajuste e exemplos de comportamento esperado. Quando algo quebrava no navegador, eu tirava um print, mandava de volta e descrevia o que eu esperava ver.
Boa parte do avanço veio de pequenas iterações, não de grandes reescritas manuais.
Um exemplo simples foi a interface do demo. Num certo ponto, o download dos arquivos era grande e não havia feedback visual suficiente. Eu pedi uma barra de progresso para deixar claro que o sistema estava baixando pesos, e não travado. Parece um detalhe menor. Não é. Quando o arquivo passa de 1 GB, a percepção do usuário muda por completo.
Também fui pedindo correções de UX ao longo do caminho:
Mensagens mais claras quando o navegador não suportava a execução esperada;
Estado visível durante carregamento do modelo;
Indicação melhor da máscara aplicada sobre a imagem;
Tratamento de erro quando a URL do peso estava errada.
Foi um ciclo bem direto. O Claude implementava, eu testava, voltava com feedback e o notes.md recebia o registro do que tinha sido descoberto. Para quem trabalha com formação técnica aplicada, isso tem muito valor. Inclusive, vejo relação clara com os conteúdos da Replitfy sobre AI-Building, porque o processo inteiro mostra como uma IA pode virar agente de entrega quando a direção está bem definida.
Publicação dos pesos e da interface
Quando o modelo convertido para ONNX ficou estável, surgiu a etapa de publicação. Os pesos resultaram num arquivo de 1,24 GB. Na prática, arredondando na experiência do usuário, o download aparecia como algo perto de 1,3 GB. Eu publiquei esses pesos no Hugging Face, enquanto a interface da aplicação foi hospedada no GitHub Pages.
Esse arranjo funcionou bem, mas exigiu atenção. Não bastava subir os arquivos. Era preciso garantir que, ao abrir o site hospedado, a interface apontasse para a URL correta do modelo e conseguisse carregar tudo sem quebra por caminho relativo mal resolvido.
Em demos web com modelos grandes, o erro mais banal pode ser só uma URL incorreta.
Eu precisei validar isso algumas vezes. Em ambiente local, um caminho podia funcionar. Em produção estática, não. Ajustar essas referências foi parte do processo. E aqui eu senti de novo um padrão útil do trabalho com IA: muita coisa não depende de escrever lógica nova, mas de fechar as lacunas entre ambiente de teste e ambiente publicado.
Quem acompanha a evolução de ferramentas e fluxos práticos pode achar útil também a seção de novidades do Replit, porque esse tipo de orquestração em nuvem conversa muito com o jeito moderno de construir demos técnicos com rapidez.
O problema do recarregamento de 1,3 GB
A pior parte da experiência apareceu depois. Cada recarga da página podia disparar de novo o download inteiro do modelo. Eu sinceramente travei quando vi isso acontecendo. Não adiantava ter uma inferência web interessante se o navegador insistisse em puxar 1,3 GB toda vez.
Sem cache, o demo perde fôlego.
A saída veio com a API CacheStorage. A implementação passou a trabalhar com caches.open("transformers-cache"), guardando os arquivos grandes do modelo de forma mais estável no navegador. A inspiração veio de um demo conhecido de transcrição web, mas a adaptação foi feita para o nosso caso de inpainting.
CacheStorage pode reduzir downloads repetidos e mudar totalmente a experiência de uso de modelos pesados no navegador.
Depois desse ajuste, a aplicação ficou muito mais aceitável. O primeiro carregamento continuava grande, e isso não tem como esconder. Só que os acessos seguintes deixavam de ser um castigo. Para uma aplicação client-side, esse tipo de melhoria faz toda a diferença.

O que eu aprendi sem mexer fundo no motor
Talvez a parte mais curiosa desta história seja esta: eu cheguei até aqui sem entrar a fundo na implementação interna de WebGPU, sem reescrever ONNX Runtime e sem alterar o núcleo do Moebius na mão. Isso me mostrou uma coisa bem prática.
Hoje já dá para portar certos modelos com apoio forte de IA, mesmo quando a pessoa está operando mais por direção e validação do que por baixo nível.
Claro, há limites. Nem todo modelo vai sair de PyTorch para navegador com esse grau de tranquilidade. Ainda existem problemas de operadores, memória, compatibilidade e tamanho. Mas, no caso do Moebius 0.2B, o Claude Opus 4.8 se mostrou capaz de conduzir várias etapas relevantes: converter o modelo para ONNX, publicar os pesos, montar a interface web e fazer tudo rodar localmente no navegador.
Na prática, isso abre espaço para incluir inpainting em aplicações web client-side. A ressalva é direta: o usuário precisa aceitar um download inicial pesado. Se 1,3 GB for viável para o contexto do produto, a abordagem faz sentido. Se não for, talvez seja melhor pensar em outra estratégia de entrega.
Para equipes que gostam de aprender construindo, esse tipo de projeto também combina com formatos de trabalho em grupo. Eu vejo conexão com o que a Replitfy discute em mentorias em grupo para times de tecnologia, porque a troca curta de feedback e o registro das descobertas aceleram muito quando o problema ainda está mal definido.
Entendendo melhor o papel do ONNX
Depois que o demo estava de pé, eu quis compreender melhor o fundamento técnico. Pedi então ao Claude.ai uma explicação detalhada sobre ONNX. O resultado foi um arquivo understanding.md, com definição do formato, glossário e até um diagrama ASCII mostrando o fluxo do modelo.
O texto explicava ONNX como um formato neutro e portável para redes neurais. Em vez de pensar só em pesos, eu passei a olhar para dois blocos juntos:
O grafo computacional, que descreve operadores, entradas, saídas e tensores;
Os pesos aprendidos, que carregam os parâmetros do modelo treinado.
Essa separação mental ajuda bastante. O ONNX não é só um “arquivo exportado”. Ele é uma forma estruturada de representar a execução da rede para outro ambiente de inferência.
Quando um modelo PyTorch vira ONNX, a meta é transportar a lógica da rede para um runtime diferente sem depender do ambiente original.
Eu gostei de fechar o projeto com esse passo mais conceitual. Primeiro, fazer funcionar. Depois, entender melhor o porquê. Isso também conversa com a proposta de formação da Replitfy, que não se limita a “fazer dar certo”, mas busca formar gente capaz de conceber, arquitetar e implantar sistemas com apoio de IA.
Se o leitor quiser ampliar a visão sobre projetos práticos com esse espírito, eu recomendo o texto sobre como aplicar AI-Building em projetos reais usando Replit. Ele ajuda a enxergar como esse tipo de experiência pode sair do experimento e virar método.

Conclusão
Ao final, eu saí com uma visão bem concreta: portar um modelo PyTorch de inpainting para WebGPU já é algo possível em casos reais, mesmo quando o processo acontece num estilo de coordenação leve, muito próximo de vibe coding. O projeto com o Moebius 0.2B mostrou isso de forma clara. Comecei com um modelo preso a PyTorch e CUDA. Terminei com um demo no navegador, rodando com WebGPU, interface publicada em GitHub Pages, pesos ONNX hospedados no Hugging Face, cache ajustado no navegador e documentação gerada ao longo do caminho em plan.md, notes.md e understanding.md.
Eu não diria que foi um caminho sem atrito. Houve erro de carregamento, falha de URL, problema de peso grande e necessidade de tornar a interface menos opaca para quem estava esperando o modelo baixar. Mas foi justamente aí que o projeto ficou interessante. Ele mostrou que a IA já consegue atuar como parceira de construção, não só como explicadora de conceitos. Se você quer acompanhar mais experimentos e métodos ligados a esse jeito de construir software com IA, vale conhecer melhor a Replitfy e buscar outros conteúdos em nossa busca de artigos.
Perguntas frequentes
O que é WebGPU e para que serve?
WebGPU é uma API moderna do navegador para acessar a GPU com mais controle e melhor capacidade de computação gráfica e numérica. Eu vejo o WebGPU como uma ponte entre aplicações web e tarefas pesadas, como inferência de modelos, renderização avançada e processamento paralelo. Para IA no navegador, o WebGPU serve para acelerar cálculos que seriam lentos demais apenas com CPU.
Como portar modelos PyTorch para WebGPU?
Na minha experiência, o caminho mais prático passa por exportar o modelo de PyTorch para ONNX e depois rodar esse arquivo com um runtime web compatível com WebGPU. Foi assim que consegui levar o Moebius 0.2B ao navegador. O fluxo inclui entender entradas e saídas do modelo, validar a exportação, adaptar o pré e pós-processamento e montar uma interface que carregue os pesos corretamente. Portar para WebGPU quase nunca significa rodar PyTorch direto no navegador, mas sim passar por uma etapa intermediária como ONNX.
Quais modelos de inpainting funcionam melhor?
Os melhores modelos para esse tipo de porte costumam ser os que têm arquitetura bem definida, exportação previsível e consumo de memória controlado. Eu prefiro modelos que já tenham pipeline claro de entrada, máscara e saída, porque isso reduz atrito na hora de levar para ONNX e WebGPU. No caso deste artigo, o Moebius 0.2B se mostrou um bom candidato por ser viável dentro desse fluxo, embora ainda traga o custo alto do download inicial.
É difícil rodar PyTorch com WebGPU?
Se a ideia for rodar PyTorch puro no navegador, eu diria que a tarefa tende a ser difícil e pouco direta. O que funcionou para mim foi mudar a estratégia: sair de PyTorch como ambiente de inferência e usar PyTorch apenas como origem do modelo, exportando para ONNX. A dificuldade real fica na compatibilidade dos operadores, no tamanho dos arquivos e no ajuste do carregamento web. O maior desafio não é só o WebGPU, mas o caminho de adaptação entre o modelo treinado e o runtime do navegador.
Onde encontrar exemplos de código prontos?
Neste caso, os materiais do projeto ficaram publicados no GitHub e os pesos no Hugging Face, junto com o demo funcionando no navegador. Além disso, eu costumo procurar referências em repositórios do próprio projeto, scripts de exportação como export_onnx.py e anotações geradas durante o processo, como plan.md, notes.md e understanding.md. Isso ajuda mais do que copiar um trecho isolado, porque mostra também as decisões tomadas no caminho.
