TypeScript commited on
Commit
f84a65d
·
verified ·
1 Parent(s): a409e51

Add native 4-bit/8-bit mixed-precision loading in joint_schema_model.py and GGUF documentation

Browse files
Files changed (2) hide show
  1. README.md +58 -9
  2. joint_schema_model.py +33 -4
README.md CHANGED
@@ -5,6 +5,8 @@ license: apache-2.0
5
  pipeline_tag: text-generation
6
  tags:
7
  - fastbrain
 
 
8
  - systemone
9
  - decision-index
10
  - tool-calling
@@ -82,19 +84,25 @@ Evaluated on the official **Cloudflare Decision Index (v0.2.1)** across **10 ben
82
 
83
  ## Quickstart
84
 
85
- `TypeScript/FastBrain-9B` is a drop-in replacement for `Cloudflare/clef-flash` using the standard `joint_schema_model` runtime:
 
 
86
 
87
  ```python
88
  from huggingface_hub import snapshot_download
89
  import sys
90
  import torch
91
 
92
- model_dir = snapshot_download("TypeScript/FastBrain-9B")
93
  sys.path.insert(0, model_dir)
94
  import joint_schema_model as clef
95
 
 
96
  model, processor = clef.load_release_model(model_dir, device="cuda", dtype=torch.bfloat16)
97
 
 
 
 
98
  response = clef.systemone(model, processor, {
99
  "model": "TypeScript/FastBrain-9B",
100
  "state": {
@@ -116,14 +124,55 @@ response = clef.systemone(model, processor, {
116
  print(response)
117
  ```
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  ---
120
 
121
  ## Repository Structure
122
 
123
- | File | Description |
124
- | :--- | :--- |
125
- | `model-00001-of-00004.safetensors` .. `00004` | Full `9B` backbone weights (`bfloat16`, in-place merged, no LoRA required) |
126
- | `joint_head.safetensors` & `joint_head_config.json` | `116M`-parameter `JointSchemaHead` weights (`122` tensors) and configuration |
127
- | `joint_schema_model.py` | `ClefModel`, `JointSchemaHead`, `load_release_model()`, and `systemone()` runtime |
128
- | `config.json`, `tokenizer.json`, `processor_config.json` | Standard Hugging Face model, tokenizer, and processor configurations |
129
- | `assets/*.png` | High-resolution technical benchmark and calibration charts |
 
 
 
 
 
5
  pipeline_tag: text-generation
6
  tags:
7
  - fastbrain
8
+ - clef
9
+ - gguf
10
  - systemone
11
  - decision-index
12
  - tool-calling
 
84
 
85
  ## Quickstart
86
 
87
+ ### 1. PyTorch / Transformers (`bfloat16` or `4-bit` / `8-bit` Quantized on Colab T4)
88
+
89
+ `TypeScript/FastBrain-9B` is a drop-in replacement for `Cloudflare/clef-flash` using the standard `joint_schema_model` runtime. It supports both full-precision `bfloat16` (`18.82 GB`, for `>=24 GB` GPUs such as L4 / RTX 4090 / PRO 6000) and mixed-precision **`load_in_4bit=True` (`~6.8 GB` VRAM, runs on a free Google Colab T4 16GB GPU)** or **`load_in_8bit=True` (`~11.2 GB` VRAM)** while keeping the `116M` `JointSchemaHead` in native `bfloat16`/`float16`:
90
 
91
  ```python
92
  from huggingface_hub import snapshot_download
93
  import sys
94
  import torch
95
 
96
+ model_dir = snapshot_download("TypeScript/FastBrain-9B", ignore_patterns=["*.gguf"])
97
  sys.path.insert(0, model_dir)
98
  import joint_schema_model as clef
99
 
100
+ # Full precision (24GB+ GPU: L4, A100, RTX 3090/4090, RTX PRO 6000):
101
  model, processor = clef.load_release_model(model_dir, device="cuda", dtype=torch.bfloat16)
102
 
103
+ # Or 4-bit NF4 mixed-precision (8GB–16GB GPU, e.g., free Google Colab T4):
104
+ # model, processor = clef.load_release_model(model_dir, device="cuda", dtype=torch.float16, load_in_4bit=True)
105
+
106
  response = clef.systemone(model, processor, {
107
  "model": "TypeScript/FastBrain-9B",
108
  "state": {
 
124
  print(response)
125
  ```
126
 
127
+ ### 2. `llama.cpp` GGUF (`Q4_K_M` / `Q8_0` / `BF16`) via `/v1/systemone`
128
+
129
+ This repository includes official `llama.cpp` (`b11430`+ / `ClefModel`) GGUF quantizations that pack both the `Qwen3.5-9B` hybrid backbone and the `116M` `JointSchemaHead` (`dec.*` tensors preserved at `Q8_0` precision):
130
+
131
+ ```bash
132
+ # Start llama-server on the /v1/systemone decision endpoint (6.04 GB Q4_K_M quant)
133
+ llama-server -hf TypeScript/FastBrain-9B:Q4_K_M --port 8080
134
+
135
+ # Query the single-forward-pass /v1/systemone endpoint
136
+ curl http://127.0.0.1:8080/v1/systemone \
137
+ -H "Content-Type: application/json" \
138
+ -d '{
139
+ "model": "FastBrain-9B",
140
+ "state": "Customer message: I was charged twice for my order last week and nobody has replied.",
141
+ "questions": {
142
+ "route": {
143
+ "type": "choice",
144
+ "instructions": "Which team should handle this?",
145
+ "criteria": {"billing": "Payments or invoices", "technical": "Bugs or outages"}
146
+ },
147
+ "urgent": {"type": "noul", "instructions": "Is the customer requesting urgent resolution?"}
148
+ }
149
+ }'
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Hardware Footprint, Quantization Tiers & Inference Speed
155
+
156
+ | Format / Precision Tier | Weight Footprint | Peak VRAM | Minimum Hardware | Typical Latency (`500–1k tok`) |
157
+ | :--- | :---: | :---: | :--- | :---: |
158
+ | **`FastBrain-9B-Q4_K_M.gguf`** *(4-bit + `Q8_0` Head)* | `6.04 GB` | `~7.2 GB` | **8GB GPU / Colab Free T4 (16GB) / Mac M1–M4** | `~90–220 ms` |
159
+ | **PyTorch `load_in_4bit=True`** *(NF4 + `fp16` Head)* | `~5.5 GB` | `~6.8 GB` | **Colab Free T4 (16GB) / RTX 3060–4060 (8GB+)** | `~180–280 ms` |
160
+ | **`FastBrain-9B-Q8_0.gguf`** *(Full 8-bit GGUF)* | `9.68 GB` | `~11.0 GB` | **12GB–16GB GPU / Colab T4 / Mac 16GB+** | `~80–180 ms` |
161
+ | **PyTorch `load_in_8bit=True`** *(INT8 + `bf16` Head)* | `~9.6 GB` | `~11.2 GB` | **Colab T4 (16GB) / RTX 4070 Ti (12GB+)** | `~130–210 ms` |
162
+ | **Native `bfloat16` (`safetensors` / `BF16.gguf`)** | `18.82 GB` (`18.16 GB`) | `20.3–24.7 GB` | **Colab L4 (24GB) / RTX 3090–4090 / PRO 6000 (96GB)** | **`38.8 ms` (`B=1`) · `61.7 ms` (`B=16` on G4 6000)** |
163
+
164
  ---
165
 
166
  ## Repository Structure
167
 
168
+ | File | Size | Description |
169
+ | :--- | :---: | :--- |
170
+ | `model-00001-of-00004.safetensors` .. `00004` | `18.59 GB` | Full `9B` backbone weights (`bfloat16`, in-place merged, no LoRA required) |
171
+ | `joint_head.safetensors` & `joint_head_config.json` | `232 MB` | `116M`-parameter `JointSchemaHead` weights (`122` tensors) and configuration |
172
+ | `FastBrain-9B-Q4_K_M.gguf` | `6.04 GB` | Recommended 4-bit GGUF (`dec.*` decision head, `ssm_`, and `attn_` preserved at `Q8_0`) |
173
+ | `FastBrain-9B-Q8_0.gguf` | `9.68 GB` | High-precision 8-bit GGUF (`ClefModel` architecture for `llama-server`) |
174
+ | `FastBrain-9B-BF16.gguf` | `18.16 GB` | Full-precision `bfloat16` GGUF (`ClefModel` architecture for `llama-server`) |
175
+ | `mmproj-FastBrain-9B-Q8_0.gguf` & `BF16.gguf` | `624 MB` / `922 MB` | Multimodal vision projector GGUF files for image/screenshot states |
176
+ | `joint_schema_model.py` | `25 KB` | `ClefModel`, `JointSchemaHead`, `load_release_model(load_in_4bit/8bit)`, and `systemone()` runtime |
177
+ | `config.json`, `tokenizer.json`, `processor_config.json` | `11 MB` | Standard Hugging Face model, tokenizer, and processor configurations |
178
+ | `assets/*.png` | `1.2 MB` | High-resolution technical benchmark and calibration charts |
joint_schema_model.py CHANGED
@@ -482,12 +482,16 @@ class ClefModel(torch.nn.Module):
482
  return_dict=True,
483
  **media,
484
  )
 
 
 
 
485
  return self.head(
486
- outputs.last_hidden_state,
487
  batch["input_ids"],
488
  batch["attention_mask"],
489
  batch["records"],
490
- base_model.get_output_embeddings().weight,
491
  )
492
 
493
 
@@ -495,9 +499,17 @@ def load_release_model(
495
  model_path: str | Path,
496
  device: str | torch.device = "cuda",
497
  dtype: torch.dtype = torch.bfloat16,
 
 
498
  **from_pretrained_kwargs: Any,
499
  ) -> tuple[ClefModel, Any]:
500
- """Load a Clef release (merged backbone, joint schema head, and processor)."""
 
 
 
 
 
 
501
  from huggingface_hub import snapshot_download
502
  from safetensors.torch import load_file
503
  from transformers import AutoProcessor, Qwen3_5ForConditionalGeneration
@@ -505,6 +517,23 @@ def load_release_model(
505
  path = Path(model_path)
506
  if not path.is_dir():
507
  path = Path(snapshot_download(str(model_path)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  backbone = Qwen3_5ForConditionalGeneration.from_pretrained(
509
  path,
510
  dtype=dtype,
@@ -560,7 +589,7 @@ def systemone(model: ClefModel, processor: Any, request: dict[str, Any], max_len
560
  if question["type"] != "noul" and not question.get("criteria"):
561
  raise ValueError(f"{question_id}: criteria must not be empty")
562
  encoded = encode_record(processor.tokenizer, request, max_length=max_length, processor=processor)
563
- device = next(model.parameters()).device
564
  logits = model(collate_records([encoded], processor.tokenizer.pad_token_id, device))[0]
565
  answers = {
566
  question.question_id: systemone_answer(
 
482
  return_dict=True,
483
  **media,
484
  )
485
+ head_dtype = next(self.head.parameters()).dtype
486
+ out_emb = base_model.get_output_embeddings().weight
487
+ if hasattr(out_emb, "dequantize"):
488
+ out_emb = out_emb.dequantize()
489
  return self.head(
490
+ outputs.last_hidden_state.to(dtype=head_dtype),
491
  batch["input_ids"],
492
  batch["attention_mask"],
493
  batch["records"],
494
+ out_emb.to(dtype=head_dtype),
495
  )
496
 
497
 
 
499
  model_path: str | Path,
500
  device: str | torch.device = "cuda",
501
  dtype: torch.dtype = torch.bfloat16,
502
+ load_in_4bit: bool = False,
503
+ load_in_8bit: bool = False,
504
  **from_pretrained_kwargs: Any,
505
  ) -> tuple[ClefModel, Any]:
506
+ """Load a FastBrain / Clef release (merged backbone, joint schema head, and processor).
507
+
508
+ Supports full-precision ``bfloat16``/``float16`` as well as mixed-precision
509
+ 4-bit NF4 (``load_in_4bit=True``, ~6.8 GB VRAM on Colab T4) and 8-bit
510
+ (``load_in_8bit=True``, ~11.2 GB VRAM) quantization via ``bitsandbytes`` while
511
+ preserving the 116M ``JointSchemaHead`` in native ``dtype`` precision.
512
+ """
513
  from huggingface_hub import snapshot_download
514
  from safetensors.torch import load_file
515
  from transformers import AutoProcessor, Qwen3_5ForConditionalGeneration
 
517
  path = Path(model_path)
518
  if not path.is_dir():
519
  path = Path(snapshot_download(str(model_path)))
520
+ from_pretrained_kwargs = dict(from_pretrained_kwargs)
521
+ if load_in_4bit or load_in_8bit:
522
+ from transformers import BitsAndBytesConfig
523
+
524
+ if load_in_4bit:
525
+ from_pretrained_kwargs["quantization_config"] = BitsAndBytesConfig(
526
+ load_in_4bit=True,
527
+ bnb_4bit_quant_type="nf4",
528
+ bnb_4bit_compute_dtype=dtype,
529
+ bnb_4bit_use_double_quant=True,
530
+ llm_int8_skip_modules=["lm_head", "visual"],
531
+ )
532
+ else:
533
+ from_pretrained_kwargs["quantization_config"] = BitsAndBytesConfig(
534
+ load_in_8bit=True,
535
+ llm_int8_skip_modules=["lm_head", "visual"],
536
+ )
537
  backbone = Qwen3_5ForConditionalGeneration.from_pretrained(
538
  path,
539
  dtype=dtype,
 
589
  if question["type"] != "noul" and not question.get("criteria"):
590
  raise ValueError(f"{question_id}: criteria must not be empty")
591
  encoded = encode_record(processor.tokenizer, request, max_length=max_length, processor=processor)
592
+ device = next(model.head.parameters()).device
593
  logits = model(collate_records([encoded], processor.tokenizer.pad_token_id, device))[0]
594
  answers = {
595
  question.question_id: systemone_answer(