Downloads · 30 days
87
38% of all-time downloads
sulfierry/manaca-1b-instruct-GGUF
manaca-1b-instruct-GGUF is a text generation model from sulfierry. Use it when you need the model to write or continue text. It is set up for llama.cpp. The card lists the license as cc-by-nc-4.0.
Conversão para GGUF do menezesbruno/manaca-1b-instruct, para uso com llama.cpp.
Downloads · 30 days
87
38% of all-time downloads
All-time downloads
231
Public
Repo size
3.4 GB
Likes
4
Public
Click a slice to open those files.
.gguf3.4 GB · 100%
From the Hugging Face model README
Conversão para GGUF do menezesbruno/manaca-1b-instruct,
para uso com llama.cpp.
Os pesos são do autor original; aqui não há re-treino, fine-tuning nem quantização com perda — o
arquivo é F16, conversão direta do safetensors bf16.
⚠️ Leia a seção "A adaptação obrigatória" antes de converter você mesmo. A conversão padrão do
convert_hf_to_gguf.pyproduz um GGUF que parece funcionar mas alucina em qualquer pergunta. Este arquivo já vem corrigido.
Conversão feita no contexto do Carcará (LNCC / Santos Dumont), onde o modelo é servido em produção.
O config.json do modelo declara LlamaForCausalLM. Por causa disso, o
convert_hf_to_gguf.py roteia a conversão para LlamaModel.set_vocab() →
_set_vocab_sentencepiece(), que grava tokenizer.ggml.model = "llama". Em tempo de execução isso
seleciona o tokenizador SPM do llama.cpp, cujo algoritmo é merge guloso por score — o
algoritmo correto para SentencePiece BPE.
Mas o tokenizador do Manacá é SentencePiece Unigram, cujo algoritmo correto é Viterbi. O resultado da conversão padrão:
referência (sp.encode) : ['▁explique', '▁o', '▁que', '▁é', '▁fotossíntese', '▁em', '▁uma', '▁frase', '.'] → 9 tokens
GGUF padrão (SPM) : [' ex','pli','que',' o',' que',' é',' fotos','sí','nte','se',' em',' uma',...] → 14 tokens
O modelo passa a receber sequências de tokens que nunca viu no treino. O efeito é silencioso e fácil de confundir com limitação do modelo:
| pergunta | GGUF padrão (SPM) | este GGUF (UGM) |
|---|---|---|
| "Qual é a capital do Brasil?" | "rio de janeiro." | "brasília." |
| "Explique o que é fotossíntese" | "as células se reproduzem, convertendo energia química em energia luminosa" | "as plantas usam a energia da luz solar para converter dióxido de carbono e água em oxigênio e glicose" |
A correção é usar o caminho de vocabulário UGM (tokenizer.ggml.model = "t5"), que o
conversor já implementa para modelos T5 e que embute o precompiled_charsmap do
tokenizer.model — a normalização nmt_nfkc_cf (NMT + NFKC + case folding) do autor.
Metadados deste arquivo:
tokenizer.ggml.model 't5' # implementação UGM = Unigram/Viterbi
tokenizer.ggml.precompiled_charsmap 244410 bytes # nmt_nfkc_cf do tokenizer.model oficial
tokenizer.ggml.add_bos_token 1
llama.context_length 4096
general.architecture 'llama'
IDs comparados token a token contra sp.encode() (a SentencePieceProcessor carregada com o
tokenizer.model oficial), no servidor de produção:
| entrada | sp.encode() | este GGUF | IDs idênticos |
|---|---|---|---|
Qual é a capital do Brasil? | 7 | 7 | ✅ |
ATENÇÃO: Coordenação de Aperfeiçoamento (CAPES) — 2026! | 15 | 15 | ✅ |
O LNCC fica em Petrópolis, no Rio de Janeiro. | 13 | 13 | ✅ |
| prompt Alpaca completo (single-turn) | 40 | 40 | ✅ |
| prompt Alpaca completo (multi-turn) | 54 | 54 | ✅ |
⚠️ Leia com atenção o que esta paridade significa — e o que ela não significa.
A comparação acima é contra sp.encode(), ou seja, contra o tokenizer.model. Contra ele a
paridade é exata. Mas o repositório traz dois tokenizadores que não são equivalentes, e a
implementação de referência (AutoTokenizer, usada por transformers e vLLM) usa o outro:
\n vira | usado por | |
|---|---|---|
tokenizer.json | <0x0A> (byte-fallback) | transformers, vLLM — e, ao que tudo indica, o treino |
tokenizer.model | espaço (normalizador nmt_nfkc_cf) | este GGUF |
Como o template Alpaca é feito de quebras de linha, o prompt que este GGUF entrega ao modelo
não tem \n nenhum — vira …ao pedido. ### Instrução: … ### Resposta: em linha única. Na maioria
das perguntas o resultado é o mesmo; em algumas, não. Medido (greedy, mesma configuração):
| pergunta | referência (transformers) | este GGUF |
|---|---|---|
| "Qual a capital da Argentina?" | buenos aires. — para sozinho | buenos aires. #argentina #buenosaires #buenosaires… até o teto |
Por que não dá para simplesmente usar o tokenizer.json aqui: o tokenizador UGM do llama.cpp
(o único que segmenta Unigram corretamente) não implementa byte-fallback — \n viraria <unk>.
Em llama.cpp é um ou outro: segmentação Unigram correta sem quebras de linha (este GGUF), ou
quebras de linha com segmentação errada (o caminho SPM, que é muito pior — ver acima).
Quem precisa de fidelidade máxima ao comportamento de referência deve usar os safetensors
originais com transformers ou vLLM, que carregam o tokenizer.json nativamente. Este GGUF existe
para quem precisa de llama.cpp — com a ressalva acima.
Outras divergências menores: x², · e emoji diferem em 1–3 tokens (compatibilidade Unicode e
plano suplementar).
O modelo não tem chat_template no tokenizer_config.json — foi treinado no formato Alpaca-PT.
Salve o template abaixo como manaca_alpaca.jinja:
{{- 'Abaixo está uma instrução que descreve uma tarefa. Escreva uma resposta que atenda adequadamente ao pedido.' -}}
{%- for m in messages -%}
{%- if m['role'] == 'user' -%}{{- '\n\n### Instrução:\n' + m['content'] -}}
{%- elif m['role'] == 'assistant' -%}{{- '\n\n### Resposta:\n' + m['content'] + '</s>' -}}
{%- endif -%}
{%- endfor -%}
{%- if add_generation_prompt -%}{{- '\n\n### Resposta:\n' -}}{%- endif -%}
Este é o template do autor (2026-09-04) — note o </s> fechando cada resposta do assistente.
E suba o servidor:
llama-server \
--model manaca-1b-instruct-F16-UGM.gguf \
--chat-template-file manaca_alpaca.jinja --jinja \
--ctx-size 4096 \
--temp 0 --top-p 1 --top-k 0 --min-p 0 --repeat-penalty 1.0 --seed 0 \
--n-predict 512
Amostragem determinística, especificada pelo autor (2026-09-04): temperature 0, top_p 1.0, top_k 0, min_p 0.0, repeat_penalty 1.0, frequency_penalty 0.0, presence_penalty 0.0, seed 0 — ou
seja, greedy puro com todos os amostradores nos seus valores neutros.
Limite a geração (--n-predict 512). O modelo não emite EOS de forma confiável em modo
sampling: sem teto ele divaga por ~2000 tokens, e como o contexto é de 4096 uma única
resposta consome metade da janela — a segunda pergunta já sai degradada e a terceira estoura.
Use stop sequences. Por ser um modelo Alpaca, depois de responder ele começa o próximo
turno sozinho. O autor especifica
["\n### Instrução:", "\n### Resposta:", "</s>"] — correto para a pilha dele
(transformers/vLLM). Neste GGUF é preciso acrescentar "###", pelo motivo da seção
seguinte. Lista recomendada aqui:
"stop": ["###", "\n### Instrução:", "\n### Resposta:", "</s>"]
O llama-server não tem flag de CLI para stop no endpoint OpenAI — mande no corpo da requisição.
"###" no stopConsequência direta da diferença entre os dois tokenizadores do repositório original:
\n vira | quem usa | |
|---|---|---|
tokenizer.json | <0x0A> (byte-fallback) | transformers, vLLM |
tokenizer.model | espaço (normalizador nmt_nfkc_cf) | este GGUF |
Como o GGUF é convertido do .model (é ele que traz o precompiled_charsmap), o modelo não
consegue emitir \n — ele emite espaço. Saída crua medida, sem stop algum:
' machado de assis. ###' stop_type: eos
Ele escreve o marcador do próximo turno como ### (com espaços) e só então emite EOS. As stop
sequences ancoradas em \n nunca casam, o ### vaza para a resposta e ainda polui o histórico dos
turnos seguintes. O "###" resolve.
Verificamos cada uma destas com três implementações — este GGUF, transformers (a referência do
autor) e vLLM com o tokenizador nativo. As três abaixo aparecem igual nas três pilhas, ou seja,
não são efeito da conversão (a cauda de hashtags da seção anterior, essa sim, é):
# 1. baixar os pesos (inclusive o tokenizer.model OFICIAL — indispensável)
huggingface-cli download menezesbruno/manaca-1b-instruct --local-dir manaca-hf
# 2. aplicar o patch que força o vocabulário UGM no conversor
python3 manaca_patch_converter_ugm.py llama.cpp/conversion/llama.py
# 3. converter
python3 llama.cpp/convert_hf_to_gguf.py manaca-hf \
--outtype f16 --outfile manaca-1b-instruct-F16-UGM.gguf
O patch do conversor (manaca_patch_converter_ugm.py) está publicado junto deste modelo — é
idempotente e aborta sem alterar nada se os anchors do upstream mudarem. O chat template
(manaca_alpaca.jinja) também está aqui, pronto para usar.
Sem o passo 2 o GGUF sai quebrado — e o sintoma parece ser do modelo, não da conversão.
sha256 538713e550299089e3029c431026834b67288dab015853800366d6963daf1074
tamanho 3.448.096.640 bytes (3,3 GiB)
menezesbruno/manaca-1b-instruct
— todo o crédito pelo treino é do autor.Se encontrar divergência entre este GGUF e a implementação de referência, abra uma discussion — os testes de paridade de tokenização são reprodutíveis e estão descritos acima.