初始化项目,由ModelHub XC社区提供模型
Model: chartreuse-verte/orb-human-typeahead-1b-v2.2 Source: Original Platform
This commit is contained in:
37
.gitattributes
vendored
Normal file
37
.gitattributes
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.arrow filter=lfs diff=lfs merge=lfs -text
|
||||
*.bin filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
||||
*.ftz filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.h5 filter=lfs diff=lfs merge=lfs -text
|
||||
*.joblib filter=lfs diff=lfs merge=lfs -text
|
||||
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
||||
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
||||
*.model filter=lfs diff=lfs merge=lfs -text
|
||||
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
||||
*.npy filter=lfs diff=lfs merge=lfs -text
|
||||
*.npz filter=lfs diff=lfs merge=lfs -text
|
||||
*.onnx filter=lfs diff=lfs merge=lfs -text
|
||||
*.ot filter=lfs diff=lfs merge=lfs -text
|
||||
*.parquet filter=lfs diff=lfs merge=lfs -text
|
||||
*.pb filter=lfs diff=lfs merge=lfs -text
|
||||
*.pickle filter=lfs diff=lfs merge=lfs -text
|
||||
*.pkl filter=lfs diff=lfs merge=lfs -text
|
||||
*.pt filter=lfs diff=lfs merge=lfs -text
|
||||
*.pth filter=lfs diff=lfs merge=lfs -text
|
||||
*.rar filter=lfs diff=lfs merge=lfs -text
|
||||
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
||||
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
||||
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
||||
*.tar filter=lfs diff=lfs merge=lfs -text
|
||||
*.tflite filter=lfs diff=lfs merge=lfs -text
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.wasm filter=lfs diff=lfs merge=lfs -text
|
||||
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.zst filter=lfs diff=lfs merge=lfs -text
|
||||
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
||||
GGUF/orb-human-typeahead-1b-v2.2-Q4_0.gguf filter=lfs diff=lfs merge=lfs -text
|
||||
GGUF/orb-human-typeahead-1b-v2.2-Q8_0.gguf filter=lfs diff=lfs merge=lfs -text
|
||||
3
GGUF/orb-human-typeahead-1b-v2.2-Q4_0.gguf
Normal file
3
GGUF/orb-human-typeahead-1b-v2.2-Q4_0.gguf
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5d8e226bd9116decf776ba24c561010b461911038af2b50d14327fcb9725f162
|
||||
size 974978976
|
||||
3
GGUF/orb-human-typeahead-1b-v2.2-Q8_0.gguf
Normal file
3
GGUF/orb-human-typeahead-1b-v2.2-Q8_0.gguf
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5fd2260927f81a8a383ee6c9a167b81a2514cf2592f3547da217939de965ef03
|
||||
size 1737785248
|
||||
140
README.md
Normal file
140
README.md
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
license: apache-2.0
|
||||
base_model: ibm-granite/granite-4.0-1b-base
|
||||
pipeline_tag: text-generation
|
||||
language:
|
||||
- en
|
||||
tags:
|
||||
- typeahead
|
||||
- autocomplete
|
||||
- roleplay
|
||||
- granite
|
||||
- gguf
|
||||
library_name: transformers
|
||||
---
|
||||
|
||||
# orb-human-typeahead-1b-v2.2
|
||||
|
||||
A 1.6B typeahead model that predicts **the human's next few words** in a
|
||||
roleplay chat — inline "ghost text" for the person typing, not a reply
|
||||
generator for the character. Full fine-tune of
|
||||
[ibm-granite/granite-4.0-1b-base](https://huggingface.co/ibm-granite/granite-4.0-1b-base).
|
||||
|
||||
Most small LMs asked to continue a user's half-typed roleplay message produce
|
||||
fluent but irrelevant text. This model is trained specifically on
|
||||
(conversation context + partial user message → the words the user actually
|
||||
typed next), so its suggestions stay on-scene and in-voice.
|
||||
|
||||
## Variants
|
||||
|
||||
| Path | Format | Use with |
|
||||
|---|---|---|
|
||||
| `/` | safetensors bf16, plain `granite` arch | transformers |
|
||||
| `GGUF/orb-human-typeahead-1b-v2.2-Q4_0.gguf` | GGUF Q4_0 (default) | llama.cpp / llama-cpp-python |
|
||||
| `GGUF/orb-human-typeahead-1b-v2.2-Q8_0.gguf` | GGUF Q8_0 | llama.cpp / llama-cpp-python |
|
||||
|
||||
The original fine-tune used the `granitemoehybrid` architecture; since this
|
||||
variant is attention-only and dense, the weights are republished here as the
|
||||
equivalent plain `granite` architecture (logit-identical, verified), which
|
||||
loads everywhere without extras.
|
||||
|
||||
## Prompt format
|
||||
|
||||
Plain text, no chat template. Optional character summary, a marker line,
|
||||
name-prefixed turns, and finally the user's draft — the model continues the
|
||||
draft. Cut the suggestion at the first newline.
|
||||
|
||||
```
|
||||
<character summary, optional>
|
||||
***Roleplay chat below***
|
||||
Sylvara: *She looks down from the watchtower and sees you.*
|
||||
Traveler: *I approach the encampment.*
|
||||
Sylvara: *She lowers her bow as you approach the gate.* "State your business, traveler."
|
||||
Traveler: *I raise both hands slowly and
|
||||
```
|
||||
|
||||
A completion looks like ` step into the torchlight, keeping my voice low.*`
|
||||
|
||||
Notes:
|
||||
- Trained to trigger at **word boundaries** only (draft ends on a whole word,
|
||||
or on a trailing space). Mid-word completion is out of scope.
|
||||
- Trained context: up to ~4 recent turns, summaries ≤400 chars, turns ≤500 chars.
|
||||
|
||||
## Serving recipe
|
||||
|
||||
Greedy, short budget, stop at newline — mirrors how it was trained and evaluated:
|
||||
|
||||
```python
|
||||
from llama_cpp import Llama
|
||||
|
||||
llm = Llama("GGUF/orb-human-typeahead-1b-v2.2-Q4_0.gguf", n_ctx=1024)
|
||||
out = llm.create_completion(prompt, max_tokens=12, stop=["\n"], temperature=0.0)
|
||||
print(out["choices"][0]["text"])
|
||||
```
|
||||
|
||||
Or with transformers:
|
||||
|
||||
```python
|
||||
from transformers import AutoModelForCausalLM, AutoTokenizer
|
||||
|
||||
tok = AutoTokenizer.from_pretrained("chartreuse-verte/orb-human-typeahead-1b-v2.2")
|
||||
model = AutoModelForCausalLM.from_pretrained("chartreuse-verte/orb-human-typeahead-1b-v2.2")
|
||||
ids = tok(prompt, return_tensors="pt").input_ids
|
||||
out = model.generate(ids, max_new_tokens=12, do_sample=False)
|
||||
print(tok.decode(out[0, ids.shape[1]:], skip_special_tokens=True).split("\n")[0])
|
||||
```
|
||||
|
||||
## Evaluation
|
||||
|
||||
Scored on a held-out validation set of roleplay conversations (120
|
||||
prompts, conversation-disjoint from training; greedy, 12-token budget,
|
||||
suggestions cut at newline). word-EM@k = fraction of prompts where the first
|
||||
k words of the suggestion exactly match what the user really typed next;
|
||||
prefix-chars = mean length of the exactly-matching leading characters.
|
||||
|
||||
| Metric | orb-human-typeahead-1b-v2.1 | this model |
|
||||
|---|---|---|
|
||||
| word-EM@1 | 0.483 | **0.500** |
|
||||
| word-EM@2 | **0.367** | 0.358 |
|
||||
| word-EM@3 | **0.275** | 0.267 |
|
||||
| accept-rate | **0.267** | 0.133 |
|
||||
| prefix-chars | **10.89** | 9.44 |
|
||||
| completion perplexity | 3.56 | 3.56 |
|
||||
|
||||
**Regression detected?? Not bug, is feature — That is the expected
|
||||
result of the change.** Turns out autocompletion isn't immune to overused slop.
|
||||
v2.2 is a data-only refresh whose entire purpose was to flatten the completion distribution —
|
||||
to stop the model defaulting to a small set of high-frequency phrasings.
|
||||
The eval set itself is synthetic and has a diversity problem, it rewards both coherency AND overused slop (which are unfortunately akin in ML).
|
||||
A model that spreads its probability mass across more plausible continuations agrees with
|
||||
such targets less often, which is what the multi-word columns show: word-EM@1 and completion perplexity
|
||||
are flat, while longer exact-agreement metrics give back a few points.
|
||||
|
||||
**Read the table as how much text is saved while typing, not as an absolute
|
||||
quality ranking**. Exact agreement with one recorded continuation cannot score suggestion
|
||||
variety, and creative roleplay is high-entropy enough that many suggestions the metric
|
||||
counts as misses are perfectly good ones.
|
||||
|
||||
You will find v2.2 much more pleasant and much less janky despite the benchmark numbers.
|
||||
|
||||
## Training
|
||||
|
||||
Two-stage full fine-tune of granite-4.0-1b-base: stage 1 on a large, mostly-synthetic
|
||||
roleplay corpus (self-chat generated to cover the on-scene, in-voice register real
|
||||
users type in), then stage 2 on a smaller private in-domain set in the serve-time
|
||||
prompt format (with stage-1 replay to limit forgetting). Over v2.1, stage 1 grew and its
|
||||
completion distribution was flattened further: a 3-gram repetition cap retires canned
|
||||
mid-phrase filler that the earlier first-word cap could not see, post-dialogue beats got
|
||||
real supervision instead of being capped into starvation, and generator punctuation tells
|
||||
(em-dashes, curly quotes) plus non-English leakage are normalized out rather than dropped.
|
||||
Examples are user turns split at word boundaries; loss is on the continuation.
|
||||
Suggestions are single-line by construction (completions end at newline).
|
||||
|
||||
## Limitations
|
||||
|
||||
- English-centric, roleplay register (asterisk actions, quoted dialogue).
|
||||
Out of domain for assistant chat, code, or formal prose.
|
||||
- Roleplay corpora include mature themes; suggestions can reflect that.
|
||||
Intended as a typing aid for consenting adult users of RP chat apps.
|
||||
- Not an instruction follower — it only continues drafts in the format above.
|
||||
- Suggests at word boundaries; won't complete a half-typed word.
|
||||
7
chat_template.jinja
Normal file
7
chat_template.jinja
Normal file
@@ -0,0 +1,7 @@
|
||||
{{- bos_token -}}{%- set system_prompt = "" -%}{%- set ns = namespace(system_prompt="") -%}{%- if messages[0]["role"] == "system" -%} {%- set ns.system_prompt = messages[0]["content"] -%} {%- set messages = messages[1:] -%}{%- endif -%}{%- if tools -%} {%- set ns.system_prompt = ns.system_prompt + ("
|
||||
" if ns.system_prompt else "") + "List of tools: <|tool_list_start|>[" -%} {%- for tool in tools -%} {%- if tool is not string -%} {%- set tool = tool | tojson -%} {%- endif -%} {%- set ns.system_prompt = ns.system_prompt + tool -%} {%- if not loop.last -%} {%- set ns.system_prompt = ns.system_prompt + ", " -%} {%- endif -%} {%- endfor -%} {%- set ns.system_prompt = ns.system_prompt + "]<|tool_list_end|>" -%}{%- endif -%}{%- if ns.system_prompt -%} {{- "<|im_start|>system
|
||||
" + ns.system_prompt + "<|im_end|>
|
||||
" -}}{%- endif -%}{%- for message in messages -%} {{- "<|im_start|>" + message["role"] + "
|
||||
" -}} {%- set content = message["content"] -%} {%- if content is not string -%} {%- set content = content | tojson -%} {%- endif -%} {%- if message["role"] == "tool" -%} {%- set content = "<|tool_response_start|>" + content + "<|tool_response_end|>" -%} {%- endif -%} {{- content + "<|im_end|>
|
||||
" -}}{%- endfor -%}{%- if add_generation_prompt -%} {{- "<|im_start|>assistant
|
||||
" -}}{%- endif -%}
|
||||
34
config.json
Normal file
34
config.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"architectures": [
|
||||
"GraniteForCausalLM"
|
||||
],
|
||||
"attention_bias": false,
|
||||
"attention_dropout": 0.0,
|
||||
"attention_multiplier": 0.0078125,
|
||||
"bos_token_id": 100257,
|
||||
"dtype": "bfloat16",
|
||||
"embedding_multiplier": 12,
|
||||
"eos_token_id": 100257,
|
||||
"hidden_act": "silu",
|
||||
"hidden_size": 2048,
|
||||
"initializer_range": 0.02,
|
||||
"intermediate_size": 4096,
|
||||
"logits_scaling": 8,
|
||||
"max_position_embeddings": 131072,
|
||||
"mlp_bias": false,
|
||||
"model_type": "granite",
|
||||
"num_attention_heads": 16,
|
||||
"num_hidden_layers": 40,
|
||||
"num_key_value_heads": 4,
|
||||
"pad_token_id": 100256,
|
||||
"residual_multiplier": 0.22,
|
||||
"rms_norm_eps": 1e-05,
|
||||
"rope_parameters": {
|
||||
"rope_theta": 10000000,
|
||||
"rope_type": "default"
|
||||
},
|
||||
"tie_word_embeddings": true,
|
||||
"transformers_version": "5.13.0",
|
||||
"use_cache": true,
|
||||
"vocab_size": 100352
|
||||
}
|
||||
10
generation_config.json
Normal file
10
generation_config.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"_from_model_config": true,
|
||||
"bos_token_id": 100257,
|
||||
"eos_token_id": 100257,
|
||||
"output_attentions": false,
|
||||
"output_hidden_states": false,
|
||||
"pad_token_id": 100256,
|
||||
"transformers_version": "5.13.0",
|
||||
"use_cache": true
|
||||
}
|
||||
3
model.safetensors
Normal file
3
model.safetensors
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4ed4b792117083d2a51f5016adc667849b7749dff110d1c19db23b1747bad8a4
|
||||
size 3263542120
|
||||
501289
tokenizer.json
Normal file
501289
tokenizer.json
Normal file
File diff suppressed because it is too large
Load Diff
14
tokenizer_config.json
Normal file
14
tokenizer_config.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"add_prefix_space": false,
|
||||
"backend": "tokenizers",
|
||||
"bos_token": "<|end_of_text|>",
|
||||
"clean_up_tokenization_spaces": false,
|
||||
"eos_token": "<|end_of_text|>",
|
||||
"is_local": true,
|
||||
"local_files_only": false,
|
||||
"model_max_length": 1000000000000000019884624838656,
|
||||
"pad_token": "<|pad|>",
|
||||
"padding_side": "left",
|
||||
"tokenizer_class": "TokenizersBackend",
|
||||
"unk_token": "<|unk|>"
|
||||
}
|
||||
Reference in New Issue
Block a user