初始化项目,由ModelHub XC社区提供模型
Model: SupraLabs/Supra-50M-Instruct 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
|
||||
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
236
README.md
Normal 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
3
Supra-50M-f16.gguf
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:14a5840b3e66cd159eae57675dab4ec4e8eb074b823ee68c2f65eb58a655f6f7
|
||||
size 104739616
|
||||
32
config.json
Normal file
32
config.json
Normal 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
10
generation_config.json
Normal 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
3
model.safetensors
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:32a19d183a112b8cdaaa2b6e53c85aa74ea496e8676b6dcc41d41d789e3fd574
|
||||
size 103584616
|
||||
249
sft.py
Normal file
249
sft.py
Normal 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
159032
tokenizer.json
Normal file
File diff suppressed because it is too large
Load Diff
9
tokenizer_config.json
Normal file
9
tokenizer_config.json
Normal 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
3
training_args.bin
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a8c859d00148001a419e39f42ae48ab4512dcfe46e66898db7e2eedcaa9145e4
|
||||
size 5265
|
||||
Reference in New Issue
Block a user