初始化项目,由ModelHub XC社区提供模型

Model: SupraLabs/Supra-50M-Instruct
Source: Original Platform
This commit is contained in:
ModelHub XC
2026-06-28 15:57:42 +08:00
commit c300720b2e
10 changed files with 159614 additions and 0 deletions

37
.gitattributes vendored Normal file
View 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
supra-50m-instruct-f16.gguf filter=lfs diff=lfs merge=lfs -text
Supra-50M-f16.gguf filter=lfs diff=lfs merge=lfs -text

236
README.md Normal file
View File

@@ -0,0 +1,236 @@
---
license: apache-2.0
datasets:
- HuggingFaceFW/fineweb-edu
- yahma/alpaca-cleaned
language:
- en
pipeline_tag: text-generation
library_name: transformers
tags:
- supra
- chimera
- 50m
- llama
- small
- open
- open-source
- cpu
- tiny
- slm
base_model:
- SupraLabs/Supra-50M-Base
new_version: SupraLabs/Supra-1.5-50M-Instruct-exp
---
# 🦅 Supra-50M Instruct
**Supra-50M Instruct** is a compact 50M-parameter chat/instruct causal language model built by SupraLabs, trained from scratch using a Llama-style architecture on 20 billion tokens of high-quality educational web text. Despite being significantly smaller than comparable open models, it achieves competitive or superior results on several key benchmarks. It's our first SupraLabs Scaling Up Plan model.
---
## 📚 Training Data
For the SFT (supervised finetuning) we used the full Alpaca-Cleaned dataset for 4 epochs. See the full SFT-code in sft.py
---
## Benchmarks
| Task | Metric | Value |
| :--- | :--- | :---: |
| arc_easy | acc,none | 0.4659 |
| arc_easy | acc_stderr,none | 0.0102 |
| arc_easy | acc_norm,none | 0.4423 |
| arc_easy | acc_norm_stderr,none | 0.0102 |
| arc_challenge | acc,none | 0.2287 |
| arc_challenge | acc_stderr,none | 0.0123 |
| arc_challenge | acc_norm,none | 0.2756 |
| arc_challenge | acc_norm_stderr,none | 0.0131 |
| hellaswag | acc,none | 0.2794 |
| hellaswag | acc_stderr,none | 0.0045 |
| hellaswag | acc_norm,none | 0.2922 |
| hellaswag | acc_norm_stderr,none | 0.0045 |
| winogrande | acc,none | 0.5154 |
| winogrande | acc_stderr,none | 0.0140 |
| piqa | acc,none | 0.5558 |
| piqa | acc_stderr,none | 0.0114 |
| piqa | acc_norm,none | 0.5952 |
| piqa | acc_norm_stderr,none | 0.0115 |
| openbookqa | acc,none | 0.1580 |
| openbookqa | acc_stderr,none | 0.0163 |
| openbookqa | acc_norm,none | 0.2860 |
| openbookqa | acc_norm_stderr,none | 0.0202 |
| boolq | acc,none | 0.4205 |
| boolq | acc_stderr,none | 0.0086 |
---
## ⚙️ Pretraining details
For more details, the full code, configs and weights, please refer to [https://huggingface.co/SupraLabs/Supra-50M-Base](https://huggingface.co/SupraLabs/Supra-50M-Base)
---
## 🚀 Inference
```python
import os
import warnings
import time
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
warnings.filterwarnings("ignore", category=UserWarning, module="transformers")
import torch
from transformers import pipeline, AutoTokenizer, logging
logging.set_verbosity_error()
# ── Global variables ──────────────────────────────────────────────────────────
end = time.time()
start = time.time()
tokens = []
# ── Config ────────────────────────────────────────────────────────────────────
MODEL_ID = "SupraLabs/Supra-50M-Instruct"
MAX_NEW_TOKENS = 512
# ── Load pipeline directly from HF ────────────────────────────────────────────
print(f"[*] Loading SFT model and tokenizer from HF Hub ({MODEL_ID})...")
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, clean_up_tokenization_spaces=False)
pipe = pipeline(
"text-generation",
model=MODEL_ID,
tokenizer=tokenizer,
device_map="auto",
torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32
)
print(f"[+] Pipeline ready — Model loaded using {pipe.model.device}")
# ── Prompt template (must match sft.py exactly) ───────────────────────────────
def build_prompt(instruction: str, input_text: str = "") -> str:
if input_text.strip():
return (
"Below is an instruction that describes a task, paired with an input "
"that provides further context. Write a response that appropriately "
"completes the request.\n\n"
f"### Instruction:\n{instruction}\n\n"
f"### Input:\n{input_text}\n\n"
"### Response:\n"
)
return (
"Below is an instruction that describes a task. Write a response that "
"appropriately completes the request.\n\n"
f"### Instruction:\n{instruction}\n\n"
"### Response:\n"
)
# ── Generate ──────────────────────────────────────────────────────────────────
def generate(instruction: str, input_text: str = "", max_new_tokens: int = MAX_NEW_TOKENS) -> str:
prompt = build_prompt(instruction, input_text)
start = time.time()
result = pipe(
prompt,
max_new_tokens=max_new_tokens,
do_sample=True,
temperature=0.7,
top_k=50,
top_p=0.9,
repetition_penalty=1.15,
pad_token_id=pipe.tokenizer.pad_token_id,
eos_token_id=pipe.tokenizer.eos_token_id,
return_full_text=False,
generation_config=None
)
end = time.time()
generated_text = result[0]["generated_text"]
tokens = pipe.tokenizer(generated_text)["input_ids"]
return generated_text, tokens, end, start
# ── Interactive loop ──────────────────────────────────────────────────────────
if __name__ == "__main__":
print("\n[+] Ready. Type 'quit' to exit.\n")
while True:
instruction = input("Instruction: ").strip()
if instruction.lower() == "quit":
break
inp = input("Input (optional, Enter to skip): ").strip()
print("-" * 50)
text, tokens, end, start = generate(instruction, inp)
print(text)
print()
print(f"Generated tokens: {len(tokens)}")
print(f"Time: {end - start:.2f}s")
print(f"Speed: {len(tokens) / (end - start):.2f} tokens/sec")
```
---
## 💬 Sample Outputs
**These outputs were generated with these samplings: `temperature=0.7, top_k=50, top_p=0.9, repetition_penalty=1.15`**
(The model still hallucinates, but can respond a big quantity of questions correctly)
**User:** What is AI?<br>
**Supra-50M Instruct:**:<br>
AI refers to the simulation of human intelligence and creativity in machines, which are designed to mimic or surpass human cognition and reasoning. It is the process by which AI systems can solve problems, make predictions, or automate processes that typically require human-level thinking and problem solving. AI technology has been rapidly growing and evolving over time, with many potential benefits for society as a whole. Some of these include:
1. Improved Accuracy: AI algorithms have demonstrated great accuracy in predicting outcomes, making accurate predictions on new data sets, and even answering real-world questions. This improves our ability to learn from experience and adapt to changing situations.
2. Personalization: AI is used to personalize user experiences, such as recommending products based on their previous interactions and preferences. This helps people to stay motivated and maintain high levels of satisfaction.
3. Better Decision Making: AI enables systems to analyze large amounts of data quickly and accurately, allowing us to make informed decisions more easily and
<br>
**User:** What is the capital of Japan?<br>
**Supra-50M Instruct:**:<br>
The capital of Japan is Tokyo.
<br>
**User:** Hi!<br>
**Supra-50M Instruct:**:<br>
Hello! How can i help you today?
<br>
**User:** What is the capital of United States?<br>
**Supra-50M Instruct:**:<br>
The capital of United States is New York City.
<br>
**User:** What is the capital of Russia?<br>
**Supra-50M Instruct:**:<br>
The capital of Russia is Moscow.
<br>
---
## 📄 License
This model is released under the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0).
---
*© SupraLabs 2026 — Project Chimera*

3
Supra-50M-f16.gguf Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:14a5840b3e66cd159eae57675dab4ec4e8eb074b823ee68c2f65eb58a655f6f7
size 104739616

32
config.json Normal file
View File

@@ -0,0 +1,32 @@
{
"architectures": [
"LlamaForCausalLM"
],
"attention_bias": false,
"attention_dropout": 0.0,
"bos_token_id": 0,
"dtype": "bfloat16",
"eos_token_id": 2,
"head_dim": 64,
"hidden_act": "silu",
"hidden_size": 512,
"initializer_range": 0.02,
"intermediate_size": 1408,
"max_position_embeddings": 1024,
"mlp_bias": false,
"model_type": "llama",
"num_attention_heads": 8,
"num_hidden_layers": 12,
"num_key_value_heads": 4,
"pad_token_id": 1,
"pretraining_tp": 1,
"rms_norm_eps": 1e-06,
"rope_parameters": {
"rope_theta": 10000,
"rope_type": "default"
},
"tie_word_embeddings": true,
"transformers_version": "5.8.1",
"use_cache": false,
"vocab_size": 32000
}

10
generation_config.json Normal file
View File

@@ -0,0 +1,10 @@
{
"_from_model_config": true,
"bos_token_id": 0,
"eos_token_id": 2,
"output_attentions": false,
"output_hidden_states": false,
"pad_token_id": 1,
"transformers_version": "5.8.1",
"use_cache": true
}

3
model.safetensors Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:32a19d183a112b8cdaaa2b6e53c85aa74ea496e8676b6dcc41d41d789e3fd574
size 103584616

249
sft.py Normal file
View File

@@ -0,0 +1,249 @@
"""
© SupraLabs 2026 - SFT script for Supra-50M on alpaca-cleaned
No TRL. Uses HuggingFace Trainer with prompt-masked cross-entropy loss.
"""
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
print("[*] Loading libraries...")
import torch
import numpy as np
from dataclasses import dataclass
from typing import Optional
from datasets import load_dataset
from transformers import (
AutoModelForCausalLM,
Trainer,
TrainingArguments,
PreTrainedTokenizerBase,
PreTrainedTokenizerFast
)
from torch.utils.data import Dataset
# ── Config ────────────────────────────────────────────────────────────────────
MODEL_ID = "./Chimera-FINAL"
OUTPUT_DIR = "./Supra-50M-SFT"
MAX_LENGTH = 512 # alpaca samples are short, 512 is plenty
IGNORE_INDEX = -100 # standard label mask value for cross-entropy
# Conservative hyperparameters — small model, don't nuke the pretraining
LEARNING_RATE = 3e-4
EPOCHS = 4
BATCH_SIZE = 8
GRAD_ACCUM = 2 # effective batch size = 16
WARMUP_RATIO = 0.1
WEIGHT_DECAY = 0.0
MAX_GRAD_NORM = 1.0
# ── Alpaca prompt template ────────────────────────────────────────────────────
PROMPT_WITH_INPUT = (
"Below is an instruction that describes a task, paired with an input "
"that provides further context. Write a response that appropriately "
"completes the request.\n\n"
"### Instruction:\n{instruction}\n\n"
"### Input:\n{input}\n\n"
"### Response:\n"
)
PROMPT_WITHOUT_INPUT = (
"Below is an instruction that describes a task. Write a response that "
"appropriately completes the request.\n\n"
"### Instruction:\n{instruction}\n\n"
"### Response:\n"
)
def build_prompt(sample: dict) -> tuple[str, str]:
"""Returns (prompt, response) — kept separate so we can mask the prompt."""
instruction = sample["instruction"].strip()
inp = sample.get("input", "").strip()
output = sample["output"].strip()
if inp:
prompt = PROMPT_WITH_INPUT.format(instruction=instruction, input=inp)
else:
prompt = PROMPT_WITHOUT_INPUT.format(instruction=instruction)
return prompt, output
# ── Dataset ───────────────────────────────────────────────────────────────────
class AlpacaDataset(Dataset):
"""
Tokenizes each sample and masks the prompt portion of the labels so the
model only computes loss on the response tokens — not on the instruction.
"""
def __init__(self, hf_dataset, tokenizer: PreTrainedTokenizerBase, max_length: int):
self.tokenizer = tokenizer
self.max_length = max_length
self.samples = hf_dataset
def __len__(self):
return len(self.samples)
def __getitem__(self, idx):
prompt, response = build_prompt(self.samples[idx])
# Tokenize prompt and response separately so we know the prompt length
prompt_ids = self.tokenizer.encode(prompt, add_special_tokens=False)
prompt_ids = [self.tokenizer.bos_token_id] + prompt_ids # explizit
response_ids = self.tokenizer.encode(response, add_special_tokens=False) + [self.tokenizer.eos_token_id]
input_ids = prompt_ids + response_ids
# Truncate to max_length
input_ids = input_ids[:self.max_length]
# Labels: mask prompt tokens with IGNORE_INDEX
prompt_len = min(len(prompt_ids), len(input_ids))
labels = [IGNORE_INDEX] * prompt_len + input_ids[prompt_len:]
# Sanity: both must be the same length after truncation
assert len(input_ids) == len(labels)
return {
"input_ids": torch.tensor(input_ids, dtype=torch.long),
"labels": torch.tensor(labels, dtype=torch.long),
}
# ── Collator ──────────────────────────────────────────────────────────────────
@dataclass
class PaddingCollator:
"""
Right-pads input_ids and labels to the longest sequence in the batch.
Labels are padded with IGNORE_INDEX so padding never contributes to loss.
"""
tokenizer: PreTrainedTokenizerBase
max_length: int
def __call__(self, batch):
max_len = max(len(x["input_ids"]) for x in batch)
max_len = min(max_len, self.max_length)
input_ids_padded = []
labels_padded = []
attention_masks = []
for item in batch:
ids = item["input_ids"][:max_len]
lbls = item["labels"][:max_len]
pad_n = max_len - len(ids)
input_ids_padded.append(
torch.cat([ids, torch.full((pad_n,), self.tokenizer.pad_token_id, dtype=torch.long)])
)
labels_padded.append(
torch.cat([lbls, torch.full((pad_n,), IGNORE_INDEX, dtype=torch.long)])
)
attention_masks.append(
torch.cat([torch.ones(len(ids), dtype=torch.long),
torch.zeros(pad_n, dtype=torch.long)])
)
return {
"input_ids": torch.stack(input_ids_padded),
"labels": torch.stack(labels_padded),
"attention_mask": torch.stack(attention_masks),
}
# ── Main ──────────────────────────────────────────────────────────────────────
def main():
# Load tokenizer + model from Hub
print(f"[*] Loading tokenizer from {MODEL_ID}...")
from tokenizers import ByteLevelBPETokenizer
fast_tokenizer = ByteLevelBPETokenizer(
"custom_llama_tokenizer-vocab.json",
"custom_llama_tokenizer-merges.txt"
)
tokenizer = PreTrainedTokenizerFast(
tokenizer_object=fast_tokenizer,
bos_token="<s>",
eos_token="</s>",
unk_token="<unk>",
pad_token="<pad>",
)
print(f"[*] Loading model from {MODEL_ID}...")
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
dtype=torch.bfloat16,
device_map="auto",
)
print(f"[+] Model loaded — {model.num_parameters():,} parameters")
# Load alpaca-cleaned (≈52k instruction-tuning pairs)
print("[*] Loading alpaca-cleaned dataset...")
raw = load_dataset("yahma/alpaca-cleaned", split="train")
print(f"[+] Dataset: {len(raw):,} samples")
# Optional: quick sanity-check split (comment out for full training)
# raw = raw.select(range(1000))
split = raw.train_test_split(test_size=0.01, seed=42)
train_dataset = AlpacaDataset(split["train"], tokenizer, MAX_LENGTH)
eval_dataset = AlpacaDataset(split["test"], tokenizer, MAX_LENGTH)
collator = PaddingCollator(tokenizer=tokenizer, max_length=MAX_LENGTH)
print(f"[+] Dataset ready: {len(train_dataset):,} samples")
print(f"[+] Example prompt preview:\n{build_prompt(raw[0])[0][:800]}...")
# Training arguments
training_args = TrainingArguments(
output_dir=OUTPUT_DIR,
num_train_epochs=EPOCHS,
per_device_train_batch_size=BATCH_SIZE,
gradient_accumulation_steps=GRAD_ACCUM,
learning_rate=LEARNING_RATE,
lr_scheduler_type="cosine",
warmup_ratio=WARMUP_RATIO,
weight_decay=WEIGHT_DECAY,
max_grad_norm=MAX_GRAD_NORM,
bf16=True,
fp16=False,
logging_steps=50,
save_total_limit=2,
report_to="none",
dataloader_num_workers=8,
dataloader_pin_memory=True,
optim="adamw_torch_fused",
adam_beta1=0.9,
adam_beta2=0.999,
push_to_hub=False,
seed=42,
data_seed=42,
eval_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
metric_for_best_model="eval_loss",
greater_is_better=False,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
data_collator=collator,
)
print("[*] Starting SFT...")
trainer.train()
print(f"[*] Saving final model to {OUTPUT_DIR}-FINAL ...")
trainer.save_model(f"{OUTPUT_DIR}-FINAL")
tokenizer.save_pretrained(f"{OUTPUT_DIR}-FINAL")
print("[+] Done.")
if __name__ == "__main__":
main()

159032
tokenizer.json Normal file

File diff suppressed because it is too large Load Diff

9
tokenizer_config.json Normal file
View File

@@ -0,0 +1,9 @@
{
"backend": "tokenizers",
"bos_token": "<s>",
"eos_token": "</s>",
"model_max_length": 1000000000000000019884624838656,
"pad_token": "<pad>",
"tokenizer_class": "TokenizersBackend",
"unk_token": "<unk>"
}

3
training_args.bin Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a8c859d00148001a419e39f42ae48ab4512dcfe46e66898db7e2eedcaa9145e4
size 5265