Recentemente eu precisei subir um Gradio no Windows para analisar um problema que envolvia o uso de uma nova feature, chamada Server Side Rendering (que apareceu na versão 5 do Gradio). Porém, me deparei com o erro ERR_UNSUPPORTED_ESM_URL_SCHEME, no Windows. Após analisar o erro, eu submeti um PR que foi aprovado e vai ser lançado no Gradio 5.7.0. Neste post, eu quero compartilhar um pouco de como foi o troubleshooting e aproveitar para deixar registrados detalhes da arquitetura do Gradio que descobri ao longo disso tudo!
Sobre o Gradio
O Gradio é uma biblioteca python para criar interface web. Ela é focada em elementos do mundo da IA e Machine Learning, sendo perfeita para criar demonstrações e até interfaces avançadas. Muito provavelmente você já deve ter interagido com uma ferramenta de “IA”, mas, que na verdade, era uma aplicação gradio!
No Hugging Face, você pode criar spaces que usam o gradio, por padrão, permitindo subir facilmente interfaces para testar os milhares de modelos que tem lá. Conheça mais em: Gradio
O problema
Tudo começou como um thread em que fui marcado no discord do Hugging Face (em breve posto sobre isso). Mas, basicamente, envolvia um erro em alguns spaces do Hugging Face. Após várias conversas, foi cogitado um relação com o Server Side Rendering.
O Server Side Rendering (SSR) é uma feature nova do Gradio 5. Antes da versão 5, o Gradio renderizava a maior parte da página dinamicamente no seu browser. Isto é, uma parte do código carregava no browser, e essa parte iria montando dinamicamente o conteúdo, comunicando com o servidor para trazer mais dados.
Com o SSR, o servidor faz um pouco mais de processamento do request e envia o HTML pronto, final, pro browser. Isso traz algumas vantagens, como carregamento inicial mais rápido, melhora indexação, etc. Obviamente que ainda sim, existe pequenos loads dinâmicos, mas, o principal é feito nessa primeira requisição.
Com o Gradio 5, os Spaces do Hugging Face passaram a usar essa feature por padrão. Isso gerou erros de HTTP 500 que foi relatado por alguns usuários. Eu irei fazer um post falando somente sobre esse erro. Mas eu caí nisso, pois tinha acabado de fazer um post sobre um erro no hugging face, e me marcaram para saber se sabia sobre algo.
Para ajudar a identificar o problema, eu resolvi olhar no código-fonte do Gradio e procurar por eventuais locais que poderiam causar o problema relatado. Mas quando eu tentei subir uma aplicação simples gradio no meu Windows, tive o seguinte erro:
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol ‘r:’
at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:227:11)
at defaultLoad (node:internal/modules/esm/load:109:3)
at ModuleLoader.load (node:internal/modules/esm/loader:666:12)
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:479:43)
at #createModuleJob (node:internal/modules/esm/loader:503:36)
at #getJobFromResolveResult (node:internal/modules/esm/loader:274:34)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:242:41)
at async onImport.tracePromise.proto (node:internal/modules/esm/loader:542:25) {
code: ‘ERR_UNSUPPORTED_ESM_URL_SCHEME’
}
E aqui encontrei uma grande surpresa: Um erro de NODE.JS bem no meio de uma biblioteca PYTHON. Sim, é isso mesmo. Ao me deparar com esse erro eu comecei a explorar o código e vi que essa feature do SSR é implementada usando Node.js, ao invés do python. Especialmente o framework sveltekit.
Após olhar o código fonte, entendi um pouco do funcionamento e aqui está um resumo (BEM RESUMO MESMO) do fluxo:
- O gradio inicia e configura as routes
- Se você passou a opção ssr_mode=True ou a variável de ambiente GRADIO_SSR_MODE=true, então ele ativa o Server Side Rendering (No hugging face, eles ativam por padrão através dessa variável).
- Uma vez que esta opção está ativa, o gradio inica um processo separador com o node.js.
Entre uma série de checks e validações, no fim das contas, o que ele faz é iniciar um processo com esse de comando:
node –import /caminho-absoluto/templates/register.mjs /caminho-absoluto/templates/node/build
Esse processo inicia um node.js, com alguns endpoints configurados usando sveltekit, escutando em uma porta TCP padrão (e que pode ser alterada via configuração). - Se o processo inicou com sucesso, então o Gradio segue sua vida.
- Toda requisição enviada ao gradio, vai ser redirecionada para o node. Você pode conferir isso nesse trecho e nessa função.
E é aqui onde mora o problema do Windows, especificamente no passo destacado acima. No Windows, o formato dos caminhos é LETRA:CAMINHO. Porém, no node, o parâmetro –import é tratado como uma URL, isto é, formato PROTOCOLO:ENDEREÇO.
Então, quando o caminho com a letra é informado, o node entende que tudo antes do dois pontos é um nome de protocolo. No caso da mensagem acima, note que ele reclama exatamente de um protocolo não existe:
E a razão é muito simples: No meu caso, a biblioteca do gradio estava no diretório R:\pyenv\gradio, e por isso ele informa o R: ali no código. Dependendo do seu ambiente, o erro pode vir com qualquer outra letra onde você instalou o gradio.
É assim que o gradio monta monta o path que vai passar nesse parâmetro:
Perceba que ele usa __file__, que resolve para o caminho absoluto, ou seja, em ambientes Windows, vai a letra junto.
A documentação é bem clara sobre o erro reportado:
Para resolver, eu apenas adicionei um ‘file://’ antes do nome do arquivo, quando o ambiente é Windows, e o gradio subiu normalmente usando SSR:
Contribuição
Após confirmar o problema e conseguir fazer a correção, eu vi que haviam algumas issues abertas mas nenhum PR relacionado a isso. Aqui fica uma dica importante: Antes de submeter PR em projetos open source, sempre verifique se já não há lago. Uma pesquisa na lista de issues e PR pode ajudar. Mesmo assim, pode ser que você deixe passar algo, mas já ajuda na maior parte dos casos.
Submeter essa correção foi relativamente simples: Fui direto no branch main, acessei o arquivo, e editei. Automaticamente o git gera um fork no meu perfil e me permite editar. Ao finalizar a edição, ele me deixa submeter o PR para o repositório original.
O time do Gradio é muito bacana e geralmente responde rápido. Já é a segunda vez que eu interajo com eles. A primeira foi uma issue para falar sobre o powershai, e agora esse PR. Após revisarem o meu código, eles aprovaram o PR, que iniciou uma série de processos automáticos e testes, que é típico desses projetos gigantes (e eu acho o máximo, pois é uma oportunidade de ver na prática o processo de mudança de um projeto gigante como o gradio).
Você pode conferir todo o histórico aqui: Fix Node.js start in Windows by rrg92 · Pull Request #10001 · gradio-app/gradio
Eu curto demais ter essas oportunidades de acesso ao código-fonte por isso: Olha quanto aprendizado apenas pela prática. Aprendi mais sobre a arquitetura do gradio, git e um monte de coisas. Eu acho muito legal poder participar disso.
Espero cada vez mais contribuir, não só com fixes, mas revisando docs, e, quem sabe, um dia, algo mais deep, no nível dos modelos de IA?! Mas até lá, seguimos aprendendo e fazendo o básico.
Se você estiver com esse erro, é só atualizar para a versão 5.7.0, ou superior (no momento em que eu escrevi esse post, ainda não lançada). Se você encontrou esse erro mesmo após atualizar, pode deixar um comentário no PR acima ou aqui no blog, e, se possível com o máximo de detalhes (sem informações sensíveis do seu ambiente), que assim que der, eu tento revisar e ajudar.
Muito obrigado pela leitura!
Apaixonado por tecnologia e veterano em bancos de dados SQL Server, este entusiasta agora se aventura no fascinante universo da Inteligência Artificial.
Atualmente é o Head de Inovação da Power Tuning, onde é o responsável por trazer novas ideias para produtos e serviços, que melhorem a produtividade do time ou a experiência do cliente! Com muita experiência em programação, hardware, sistemas operacionais, e mais, agora quer juntar tudo isso nesse novo mundo e trazer muitas ideias e conhecimento sobre Inteligência Artificial!
Neste blog, vai compartilhar sua jornada de aprendizado e uso da IA, focando em como transformar nossa maneira de resolver problemas e inovar.