clip-box — onde está nesta imagem?
Esta é a porta de entrada "onde está X". A implementação vive em
decision-model: o mesmo cliente responde a bool, choice, score e box,
e clip-box é um ponto de entrada leve que mantém este vocabulário roteável e
pode apontar para um shim independente quando outro modelo ocupa o slot de decisão.
clip-box --image scene.png --target "o quadrado vermelho" # slot shim na :8083
clip-box --image scene.png --target "o quadrado vermelho" --port 8761 # shim independente
decision-model box --image scene.png --target "o quadrado vermelho" # mesma coisa
h2o-lightning é um modelo de decisão de 4B: ele responde a perguntas tipadas com
probabilidades e nunca gera prosa. Sua pergunta box retorna um retângulo
em vez de um rótulo, e três números que importam mais do que o retângulo:
| campo | significado |
|---|---|
box | left, top, right, bottom como frações da imagem, a partir do canto superior esquerdo |
confidence | P(IoU ≥ 0,5) — uma leitura de decisão na imagem com a caixa desenhada, não um número que o modelo narra |
present | P(o alvo está visível de alguma forma) — uma leitura separada na imagem intocada |
found | se alguma caixa foi produzida; uma falha retorna a imagem inteira com confiança 0 |
Use present como gate, não found. Perguntado por uma bicicleta azul em uma cena que
não tem nenhuma, o modelo retorna uma caixa de aparência confiante em torno de outra coisa com
found: true e present: 0,111. present é o que diz não.
Uso
# iniciar a API (perguntas box estão ativas; a porta frontal do slot é :8083)
h2o-serve --port 8083 # CPU, Q8_0
h2o-serve --backend vulkan # GPUs AMD: compila o backend Vulkan fixado uma vez
h2o-serve --status
h2o-serve --stop
# perguntar
clip-box --image scene.png --target "o quadrado vermelho"
# ACEITO box=(0,247, 0,247) -> (0,753, 0,753) confidence=0,651 present=0,885
clip-box --image scene.png --target "a bicicleta azul" # ausente -> sai com código 2
clip-box --image receipt.png --target "o valor total" # confidence=0,163 < 0,30 -> rejeitado
clip-box --image scene.png --target "o quadrado vermelho" --json --crop /tmp/square.png
--json retorna accepted, reason, box, pixels (calculados a partir do tamanho real
da imagem), confidence, present, found e o model que respondeu.
Código de saída 0 aceita, 2 rejeita, 1 é erro de requisição.
--min-present (padrão 0,5) e --min-confidence (padrão 0,30) definem os
limiares; ambos também são variáveis de ambiente (BOX_MIN_PRESENT,
BOX_MIN_CONFIDENCE). --crop escreve a caixa aceita; precisa do Pillow.
Capacidade, não suposição
box é um recurso shim, não um recurso de protocolo: o próprio llama.cpp
/v1/systemone aceita apenas choice, score e noul. O slot de decisão
rotaciona entre cinco candidatos, então:
de decision-model caps
# model /models/h2o-lightning-4b-Q4_K_M.gguf
# slot :8083 (box na :8083)
# primitives bool, choice, score, box
Se o ocupante não for h2o, caps não lista box e box recusa com o
nome do modelo servido — em vez de postar uma pergunta que o endpoint não pode responder.
Para o que realmente é bom
Medido nesta estação de trabalho (Q8_0, backend CPU), cenas sintéticas com verdade conhecida:
| alvo | IoU | confidence | present |
|---|---|---|---|
| quadrado vermelho, 512×512 centralizado | 0,976 | 0,651 | 0,885 |
| retângulo vermelho, 512×1024 alto | 0,877 | 0,669 | 0,897 |
| retângulo vermelho, 1024×512 largo | 0,848 | 0,722 | 0,895 |
| quadrado vermelho pequeno em cena poluída | 0,603 | 0,359 | 0,896 |
| "a bicicleta azul" (ausente) | — | 0,188 | 0,111 |
| "o valor total" em um recibo | erro (caixa abaixo do total) | 0,144 | 0,899 |
Objetos salientes, ícones, formas, imagens únicas: bom, proporção de aspecto tratada
corretamente. Texto pequeno denso em um recibo: ele erra, e sua baixa confiança assim o
diz. Para um valor em um recibo, recorte com a vizinhança do total ou use a
pergunta choice da API de decisão ("qual é o TOTAL? subtotal/total/tax"), que
pontuou corretamente na mesma imagem.
A armadilha que esta habilidade existe para absorver
Pillow. O shim desenha a caixa antes da leitura de precisão e retorna
None em ImportError, então um Python sem Pillow responde a cada caixa com
confidence: 0.0. h2o-serve constrói seu próprio venv e verifica a importação.
Arquivos
| caminho | função |
|---|---|
scripts/clip_box.py | ponto de entrada — lida com --port/--host, delega para decision-model box |
../hardware/decision-model/scripts/decision_model.py | o cliente: uma pergunta box, dois gates, recorte, códigos de saída |
../hardware/decision-model/scripts/h2o_serve.py | o lançador: bootstrap fixado por hash, venv seguro para Pillow, backend CPU/CUDA/Vulkan, --status, --stop |
O estado reside em ~/.cache/h2o_lightning_gguf (pesos + backend fixado) e
~/.local/share/h2o-lightning/venv. Nada fora desses dois caminhos é tocado.
Notas de protocolo
- O
box.modedo shim égenerateaqui: uma geração restrita na convençãobbox_2ddo Qwen (0–1000, x primeiro), analisada e limitada.edges/hybridprecisam de um modelo treinado em leituras de borda; mantenhageneratecom este lançamento. confidenceé uma probabilidade com sua própria temperatura,1.0até ser ajustada, então é conservadora: uma caixa quase perfeita em um quadrado grande lê 0,65, não 0,95.- Uma imagem por requisição por padrão; o shim aceita até 8 com
images:e o backend é iniciado com--image-max-tokens 1024. - O lado de decisão do mesmo servidor responde a
choice/noul/scoreem texto e imagens em/v1/systemone; para decisões calibradas em texto, prefirapplx-decider(Índice de Decisão 60.06 vs 51.38 aqui). Use este modelo para geometria, não para roteamento.