Tratamento de erros¶
llama-crab reporta cada falha recuperável através do enum
[LlamaError]. Esta página explica as variantes, quando cada uma
é levantada, e os padrões que a API segura usa para expô-las.
O enum LlamaError¶
pub enum LlamaError {
/// Erro de I/O (arquivo de modelo não encontrado, falha de leitura, etc.).
Io(std::io::Error),
/// Erro de parse GGUF (arquivo presente, mas inválido).
Gguf(String),
/// O arquivo de modelo não pôde ser aberto ou carregado.
ModelLoad(String),
/// O contexto não pôde ser criado (sem memória, n_ctx muito grande).
ContextCreate(String),
/// Falha de tokenização.
Tokenize(String),
/// Falha de detokenização.
Detokenize(String),
/// Falha de criação ou amostragem do sampler.
Sampling(String),
/// Falha do stack multimodal.
Multimodal(String),
/// O backend não está inicializado (raro; usualmente pego no startup).
BackendNotInitialised,
/// Um erro customizado ou desconhecido retornado por uma função C++.
Other(String),
}
O enum implementa std::error::Error + Send + Sync, então compõe
com anyhow::Error e thiserror sem cerimônia. Os métodos de alto
nível em Llama retornam Result<T, LlamaError>.
Variantes comuns em detalhe¶
LlamaError::Io¶
Levantada quando o arquivo de modelo não pode ser aberto, quando
um arquivo de tokenizador está faltando, ou quando o cache em disco
encontra um erro de I/O. O std::io::Error interno carrega os
detalhes a nível de SO:
match Llama::load(LlamaParams::new("ausente.gguf")) {
Ok(llama) => { /* … */ }
Err(LlamaError::Io(e)) => eprintln!("arquivo não encontrado: {e}"),
Err(e) => eprintln!("outro erro: {e}"),
}
Mitigações:
- Certifique-se de que o caminho está correto.
- Baixe o modelo novamente com
scripts/download_models.sh <alvo>. - Para caminhos relativos, verifique o diretório de trabalho do
binário em tempo de execução (pode diferir do
pwddo seu shell).
LlamaError::ModelLoad¶
Levantada quando o arquivo está aberto mas o modelo não pode ser
carregado — tipicamente por causa de uma arquitetura não suportada,
um arquivo GGUF corrompido, ou uma incompatibilidade de versão com
o llama.cpp empacotado.
Mitigações:
- Baixe o GGUF novamente.
- Confirme que o arquivo não está truncado (
ls -lhvs tamanho esperado). - Abra uma issue com a mensagem de erro exata e o identificador do modelo.
LlamaError::ContextCreate¶
Levantada quando não há memória suficiente para alocar o cache KV.
As duas alavancas que você tem são n_ctx (tamanho do cache KV) e
n_gpu_layers (offload de GPU).
Mitigações, em ordem de impacto:
- Diminua
n_ctx(ex.4096 → 1024). - Diminua
n_gpu_layerspara manter mais camadas na CPU (menos VRAM, mais RAM). - Troque para um quant mais agressivo (
Q4_K_M → Q3_K_M → Q2_K). - Troque de backend (Metal → CPU quando VRAM é o gargalo).
LlamaError::Tokenize e LlamaError::Detokenize¶
Levantadas quando o texto de entrada contém bytes que não podem ser tokenizados, ou quando o id do token está fora do range. Muito raro na prática.
LlamaError::Multimodal¶
Levantada pela feature mtmd. Causas típicas:
- O arquivo
mmprojnão corresponde ao modelo de texto. - A imagem é grande demais para caber no contexto.
- A feature
mtmdnão está habilitada no build (o tipo nem existe nesse caso).
LlamaError::BackendNotInitialised¶
Levantada apenas quando a API de baixo nível é usada sem um guard
LlamaBackend ativo. A API de alto nível Llama::load sempre
inicializa o backend, então usuários da API de alto nível nunca
verão esta variante.
Padrões para expor erros¶
Mapear para mensagens voltadas ao usuário¶
Um padrão comum é converter o erro da biblioteca em uma string plana para exibição:
fn run() -> Result<String, String> {
let mut llama = Llama::load(LlamaParams::new("modelo.gguf"))
.map_err(|e| format!("não foi possível carregar o modelo: {e}"))?;
let resp = llama.create_completion("Hello", 32)
.map_err(|e| format!("completion falhou: {e}"))?;
Ok(resp.text)
}
Usar anyhow para código de aplicação¶
use anyhow::{Context, Result};
fn main() -> Result<()> {
let mut llama = Llama::load(LlamaParams::new("modelo.gguf"))
.context("carregando o modelo")?;
let resp = llama.create_completion("Hello", 32)
.context("executando a completion")?;
println!("{}", resp.text);
Ok(())
}
Usar thiserror para código de biblioteca¶
use thiserror::Error;
#[derive(Debug, Error)]
pub enum AppError {
#[error(transparent)]
Llama(#[from] llama_crab::LlamaError),
#[error("configuração inválida: {0}")]
Config(String),
}
Recuperável vs não recuperável¶
A maioria das variantes de LlamaError são recuperáveis no
sentido de que o processo pode continuar rodando e responder à
próxima requisição. As duas exceções são:
ModelLoad(o arquivo de modelo está inutilizável; geralmente uma configuração errada que você só corrige no startup).ContextCreate(pressão de memória; geralmente uma falha transitória que retries não ajudam).
Para um servidor, trate essas duas como fatais e saia do processo para que um supervisor possa reiniciá-lo.
Por onde ir a partir daqui¶
- Solução de problemas — receitas concretas para as mensagens de erro mais comuns.
- Ciclo de vida — o que acontece com requisições em andamento quando um worker atinge um erro irrecuperável.
- Servidor — como o servidor HTTP
empacotado converte
LlamaErrorem códigos de status HTTP no estilo OpenAI.