Jetson AI Lab: configuração da página do catálogo de modelos
Verificação da realidade
- Jetson AI Lab é um site Astro estático. Ele não hospeda APIs de inferência. Os usuários copiam comandos do site e os executam em um Jetson (ou outra máquina).
- As páginas de modelo são arquivos Markdown na coleção de conteúdo Astro
models:src/content/models/<slug>.md. - O
slugdo arquivo (nome do arquivo sem.md) torna-se o segmento da URL: rota publicada/models/<slug>(vejasrc/pages/models/[slug].astro). - Quase todo elemento visível em uma página de modelo é controlado pelo frontmatter YAML naquele arquivo (Hero, barra lateral de Detalhes do Modelo, abas Executar no Jetson, trechos de Chamada, abas one-shot, gráfico de Benchmark). O Markdown do corpo preenche apenas a seção de texto Detalhes do Modelo na parte inferior.
Não invente uma URL base para "a API de inferência do Jetson AI Lab" — ela não existe.
Anatomia da página (de cima para baixo)
| Seção | Controlada por | Componente / arquivo |
|---|---|---|
| Hero (título, badges, chips "Comando para Executar no Jetson" / "Benchmark" / "Detalhes do Modelo") | title, is_new, type, short_description, presença de engines e benchmark_key | src/pages/models/[slug].astro |
| Barra lateral de Especificações (Parâmetros, Modalidades, Comprimento de Contexto, Licença, pills de Precisão) | parameters (ou model_size), modalities (ou vision_capable), context_length, license, precision (por token) | src/pages/models/[slug].astro L137–193 |
| Executar no Jetson → Matriz de Servir | serving.entries (preferido) ou supported_inference_engines, mais matrix_modules_disabled | ModelServeSection.astro |
| Chamar o modelo | client_call.{shell,python,intro} (ou construído automaticamente a partir de engines + hf_checkpoint) | ModelCallSection.astro |
| Inferência one-shot (abas por módulo) | one_shot_inference.* | ModelOneShotSection.astro + src/lib/evalRunModal.ts |
| Gráfico de Benchmark | benchmark_key (+ opcional benchmark_series) → junta src/data/benchmarks.json | ModelBenchmarkSection.astro |
Texto de Detalhes do Modelo + links externos (Try on build.nvidia.com, View on HuggingFace) | Corpo Markdown + build_nvidia_url, huggingface_url (ou hf_checkpoint) | src/pages/models/[slug].astro L242–289 |
Referência do frontmatter
Cada página de modelo é controlada pelo seu frontmatter YAML. A validação está em src/content/config.ts (modelsSchema).
Tags sempre incluídas
Ou são exigidas pelo esquema (a build falha sem elas) ou usadas por todos os modelos no repositório. Inclua todas ao adicionar um novo modelo.
| Tag | Esquema | O que faz |
|---|---|---|
title | obrigatório | Nome de exibição na página do modelo e nos cartões do catálogo. |
short_description | obrigatório | Resumo de uma linha na grade do catálogo e subtítulo do Hero. |
precision | obrigatório | Tokens de quantização separados por barra ou vírgula (ex.: "NVFP4 / FP8 / Q4_K_M GGUF"). Cada token renderiza como uma pill colorida na barra lateral (precisionPill em [slug].astro). |
family | opcional, mas onipresente | Agrupa modelos no catálogo. O valor especial "Google Gemma4" aciona o banner de tutorial Gemma 4 acima do texto. |
model_id, icon, is_new, order, type, hf_checkpoint, huggingface_url, minimum_jetson | opcional, mas onipresente | Cartão do catálogo / herói / links externos. huggingface_url usa fallback para https://huggingface.co/${hf_checkpoint} quando omitido. |
Tags da barra lateral de Detalhes do Modelo (controlam o cartão escuro de especificações à direita do Hero)
Pular estas tags faz com que a linha desapareça da barra lateral (nenhum erro, apenas menos polimento).
| Tag | Linha da barra lateral | Notas |
|---|---|---|
parameters (ou fallback para model_size) | "Parâmetros" | Texto livre, ex.: "~9B" ou "30B total / 3B ativos". |
modalities: [...] | "Modalidades" | Array de "Text" | "Image" | "Audio" | "Video" — cada um renderiza com um ícone. Se omitido, usa fallback para vision_capable (Sim → "Texto, Imagem", Não → "Texto"). |
vision_capable (booleano) | (fallback para Modalidades) | Defina explicitamente mesmo quando modalities estiver presente — usado em outros lugares para filtros do catálogo. |
context_length | "Comprimento de Contexto" | Texto livre, ex.: "128K", "262K". |
license | "Licença" | Texto livre, ex.: "Apache 2.0", "Licença de Modelo Aberto NVIDIA". |
model_size | (fallback para Parâmetros) | ex.: "12GB". |
memory_requirements | não mostrado na barra lateral, mas usado por outra UI | ex.: "16GB RAM". |
Tags situacionais
Adicione estas apenas quando o modelo precisar delas.
| Tag | Quando usar | Uso no repositório |
|---|---|---|
build_nvidia_url | O modelo tem uma página NVIDIA Build → adiciona o botão Try on build.nvidia.com. | ~67% dos modelos |
matrix_modules_disabled | Algumas abas de módulo da matriz devem ser esmaecidas / não clicáveis para todos os engines deste modelo. | ~10% dos modelos |
hide_run_button | Oculta toda a interface Executar no Jetson (Servir + Chamar + one-shot) mesmo quando os dados do engine estão presentes. | ~5% dos modelos |
benchmark_key | O modelo tem desempenho medido em src/data/benchmarks.json. O valor deve ser igual ao campo name da entrada de benchmarks. | ~30% dos modelos |
benchmark_series: [...] | Mostra barras de comparação lado a lado extras (ex.: comparar com a geração anterior da mesma família). Cada valor é outro name de benchmarks.json. | Alguns |
Blocos de inferência (pelo menos um obrigatório, a menos que hide_run_button: true)
| Bloco | Propósito |
|---|---|
serving.entries | Lista de engines no novo estilo — preferido para novos modelos. Substitui supported_inference_engines na interface quando não vazio. |
supported_inference_engines | Array de engines legado. Ainda funciona e é a forma mais comum hoje. |
one_shot_inference | Comandos de execução one-shot (variantes shell/python/por módulo). Renderiza uma seção separada de abas "Inferência one-shot" abaixo de Chamar. |
client_call.{shell,python,intro} | Substituição opcional para o trecho Chamar o modelo. Se omitido, a página constrói automaticamente um exemplo curl a partir dos comandos do engine e hf_checkpoint. |
Executar no Jetson: as três alavancas de "bloqueio" (quando OOM vs ocultar vs esmaecer)
Estas são em camadas. A matriz de Servir as avalia nesta ordem:
-
hide_run_button: true(frontmatter, nível superior)- Oculta toda a seção Executar no Jetson (Servir + Chamar + one-shot).
- Use quando o modelo existe no catálogo, mas ainda não pode ser iniciado a partir do site (ex.: requer download NGC, checkpoint com acesso restrito, validação pendente).
- Exemplo:
src/content/models/cosmos-reason2-8b.md— mantém os dados do engine para documentação, mas a interface de execução permanece oculta.
-
matrix_modules_disabled: [moduleId, ...](frontmatter, nível superior)- Esmaece as abas de módulo listadas em todos os engines para este modelo. A aba é mostrada, mas não é clicável.
- Use quando um módulo Jetson é teoricamente possível, mas ainda não foi validado para este modelo.
-
engines[].modules_supported: [moduleId, ...](por engine, dentro deserving.entries[]ousupported_inference_engines[])- Lista de permissões: apenas os ids de módulo listados são habilitados para aquele engine. As células fora da lista aparecem esmaecidas para aquela linha do engine.
- Omita o campo completamente → o engine suporta todos os módulos da matriz. Um array vazio significa que o engine não suporta nada (raro).
- Use quando o modelo funciona em todos os lugares, mas um engine específico só funciona em um subconjunto (ex.: vLLM apenas Thor, Ollama Orin+Thor).
OOM é um conceito diferente e vive em src/data/benchmarks.json — veja Benchmarks abaixo.
| O que você quer expressar… | Use… |
|---|---|
| "Este modelo não está pronto para ser executado a partir do site" | hide_run_button: true |
| "Este modelo não pode ser executado no Orin Nano (qualquer engine)" | matrix_modules_disabled: [orin_nano_8] |
| "vLLM só funciona no Thor para este modelo; llama.cpp funciona em todos os lugares" | Entrada vLLM: modules_supported: [thor_t5000, thor_t4000]; omita em llama.cpp |
| "Fizemos benchmark e ficou sem memória no T4000" | Adicione "oom": ["t4000"] àquela quantização em benchmarks.json (não pertence ao frontmatter do modelo) |
| "Fizemos benchmark e o modelo simplesmente não executa no Orin Nano" | Adicione "dnr": ["orin_nano_8gb"] àquela quantização em benchmarks.json |
| "Ainda não medimos esta combinação" | Defina o valor como null em benchmarks.json. Nenhum marcador é desenhado; a barra simplesmente está ausente. |
Dados de inferência: matriz de Servir (engines)
A lista de engines é construída por getSupportedInferenceEngines em src/lib/modelFrontmatterAdapter.ts:
- Se
serving.entriesestiver presente e não vazio → essas entradas são usadas (preferido para novos trabalhos). - Caso contrário,
supported_inference_engines(array legado) é usado.
Cada linha de engine mapeia para SupportedEngineEntry em src/lib/inferenceCommands.ts. Prefira:
serve_command_orin/serve_command_thorpara comandos de execução de longa duração (vLLM, Ollama, etc.).- Os legados
run_command_orin/run_command_thorestão obsoletos, mas ainda são aceitos como fallbacks.
Campos opcionais:
modules_supported— veja alavanca de bloqueio #3 acima.run_commands_by_module: mapa de substituição por célula{ moduleId: command }para células da matriz Executar.install_command/install_command_orin/install_command_thor: prefixados como um bloco# Instalaçãoacima do comando de servir.
A ordem de exibição dos engines é fixa por sortEnginesForUi em modelFrontmatterAdapter.ts: vLLM → SGLang → llama.cpp → Ollama → Edge-LLM → todo o resto (alfabético). Não tente controlar a ordem a partir do frontmatter.
Ids canônicos de módulos Jetson
Definidos em JETSON_MATRIX_MODULES em src/lib/inferenceCommands.ts. Use estes ids exatos em modules_supported / matrix_modules_disabled / one_shot_inference.modules_supported.
| Id do módulo | Aba da matriz? | Plataforma |
|---|---|---|
thor_t5000 | Sim | thor |
thor_t4000 | Sim | thor |
orin_agx_64 | Sim | orin |
orin_nx_16 | Sim | orin |
orin_nano_8 | Sim | orin |
orin_agx_32 | apenas dados (sem aba) | orin |
orin_nx_8 | apenas dados (sem aba) | orin |
orin_nano_4 | apenas dados (sem aba) | orin |
Ids "apenas dados" (showInMatrixUi: false) são frontmatter válido e resolvem comandos por platformKey, mas nenhuma aba da matriz Servir/Executar é mostrada. Não invente novos ids — estender a lista requer uma alteração de código em JETSON_MATRIX_MODULES.
Exemplos no repositório:
serving.entries(novo estilo):src/content/models/ministral3-8b-reasoning.mdsupported_inference_engineslegado commodules_supportedrico por engine:src/content/models/nemotron-3-nano-omni.mdhide_run_button: true:src/content/models/cosmos-reason2-8b.md
Inferência one-shot
Bloco de frontmatter opcional one_shot_inference (esquema em src/content/config.ts). Campos:
run_command_orin,run_command_thor— comando único de execução por plataforma.shell,python— trechos não específicos de plataforma.shell_by_module,python_by_module— mapas de substituição por módulo, com chaves pelo id canônico do módulo.modules_supported— restringe quais abas de módulo aparecem.intro— introdução Markdown opcional mostrada acima das abas.
Visibilidade: ModelOneShotSection.astro mostra a seção quando pelo menos um dos campos de comando acima não está vazio (verificação hasContent).
A resolução de trechos/módulos vive em src/lib/evalRunModal.ts (veja evalSnippetByModule, evalMatrixModuleSpecs).
Chamar o modelo (client_call)
Bloco de frontmatter opcional — substitui o exemplo curl gerado automaticamente mostrado em Chamar o modelo.
client_call:
intro: "Quando o servidor estiver funcionando:"
shell: |-
curl -s http://${JETSON_HOST}:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{ "model": "my_model", "messages": [{"role":"user","content":"oi"}] }'
python: |-
import openai
...
Omita client_call completamente para deixar ModelCallSection.astro sintetizar um exemplo a partir de hf_checkpoint e do comando de servir do primeiro engine.
Dados de benchmark
Os números de benchmark não residem no frontmatter do modelo. Eles residem em src/data/benchmarks.json sob models[]. A página do modelo os junta através do campo de frontmatter benchmark_key, que deve corresponder exatamente a models[].name.
Adicionando dados de benchmark
- Adicione uma entrada a
models[]emsrc/data/benchmarks.json:
{
"family": "Nome da Família",
"name": "Nome Exato (esta é a chave de junção)",
"releaseDate": "YYYY-MM-DD",
"capabilities": { "language": true, "vision": false, "audio": false, "vla": false },
"isl": 2048,
"osl": 128,
"engines": {
"vLLM": {
"NVFP4": {
"concurrency1": { "t5000": 63.3, "t4000": 51.8, "agx_orin_64gb": null, "orin_nx_16gb": null, "orin_nano_8gb": null, "dgx_spark": 59.6 },
"concurrency8": { "t5000": 181.2, "t4000": 147.4, "agx_orin_64gb": null, "orin_nx_16gb": null, "orin_nano_8gb": null, "dgx_spark": 191.2 }
},
"FP8": {
"concurrency1": { "t5000": 54.7, "t4000": null, "agx_orin_64gb": null, "orin_nx_16gb": null, "orin_nano_8gb": null, "dgx_spark": 52.3 },
"concurrency8": { "t5000": 129.8, "t4000": null, "agx_orin_64gb": null, "orin_nx_16gb": null, "orin_nano_8gb": null, "dgx_spark": 138.6 },
"oom": ["t4000"]
}
},
"Ollama": {
"Q4_K_M": {
"concurrency1": { "t5000": 27, "t4000": null, "agx_orin_64gb": 17, "orin_nx_16gb": null, "orin_nano_8gb": null, "dgx_spark": null },
"concurrency8": { "t5000": 28, "t4000": null, "agx_orin_64gb": 17, "orin_nx_16gb": null, "orin_nano_8gb": null, "dgx_spark": null },
"oom": ["orin_nx_16gb", "orin_nano_8gb"]
}
}
}
}
- No frontmatter do modelo, adicione:
benchmark_key: "Nome Exato (esta é a chave de junção)"
benchmark_series:
- "Nome da Família Predecessora" # opcional — sobrepõe barras de comparação
Ids de produtos de benchmark ≠ ids de módulos da matriz (pegadinha crítica)
O eixo de benchmark usa ids diferentes dos da matriz Executar/Servir:
| Hardware | Id do módulo da matriz (frontmatter) | Id do produto de benchmark (benchmarks.json) |
|---|---|---|
| Jetson Thor T5000 | thor_t5000 | t5000 |
| Jetson Thor T4000 | thor_t4000 | t4000 |
| Jetson AGX Orin 64GB | orin_agx_64 | agx_orin_64gb |
| Jetson Orin NX 16GB | orin_nx_16 | orin_nx_16gb |
| Jetson Orin Nano 8GB | orin_nano_8 | orin_nano_8gb |
| Jetson Orin AGX 32GB | orin_agx_32 | agx_orin_32gb |
| Jetson Orin NX 8GB | orin_nx_8 | orin_nx_8gb |
| Jetson Orin Nano 4GB | orin_nano_4 | orin_nano_4gb |
| DGX Spark | dgx_spark | dgx_spark |
Importante: o benchmark id agx_orin_64gb usa sublinhado (agx_orin_64gb), enquanto o id do módulo usa underline (orin_agx_64). Não confunda t5000 (benchmark) com thor_t5000 (módulo). O campo oom / dnr dentro de uma quantização específica também usa os ids do produto de benchmark, não os ids do módulo da matriz.
Consulta: fetchBenchmarks em src/data/benchmarks.ts.
Dicas de solução de problemas
| Sintoma | Causa provável |
|---|---|
| A página não é construída / erro no esquema | Tag obrigatória ausente (title, short_description, precision). Verifique src/content/config.ts. |
| A barra lateral de Especificações está ausente ou incompleta | Pule uma tag específica (ex.: sem parameters → a linha "Parâmetros" desaparece silenciosamente). |
| A seção "Executar no Jetson" não aparece | Possibilidades: hide_run_button: true está definido; serving.entries e supported_inference_engines estão ambos vazios; serving.entries não está configurado e supported_inference_engines está vazio. |
| "Chamar o modelo" parece vazio ou quebrado | client_call está ausente, hf_checkpoint está faltando e nenhum engine está presente → nada para sintetizar. |
| O gráfico de Benchmark não mostra dados | benchmark_key não corresponde a models[].name em benchmarks.json (verifique maiúsculas/minúsculas e espaços). |
| A aba de um módulo está esmaecida, mas deveria estar ativa | Verifique matrix_modules_disabled e, em seguida, verifique se o engine tem um campo modules_supported que não inclui este módulo. |
| O benchmark mostra "OOM" inesperadamente | Olhe em benchmarks.json dentro da quantização -> "oom": ["id_do_produto"]. Isso não está no frontmatter do modelo. |
| "DNR" aparece no gráfico | O mesmo que OOM, mas o campo é "dnr". |