File size: 24,169 Bytes
bfebd91 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | #!/usr/bin/env python3
"""
Deep clean SFT dataset for LUNA:
1. Remove/rebrand AI identity references (OpenAI, ChatGPT, etc.) -> LUNA by Asterizer
2. Strip instruction preambles ("You are an AI assistant...")
3. Remove placeholder entries ([insert], [your name], etc.)
4. Remove very short outputs (<20 chars single-word answers without context)
5. Clean broken English / grammar issues in instructions
6. Inject Asterizer identity entries for SFT alignment
7. Final dedup and token count
"""
import json, re, os, random, hashlib
from pathlib import Path
from transformers import AutoTokenizer
SRC = Path("Base/Datasets/sft_clean/all_sft_clean.json")
OUT_DIR = Path("Base/Datasets/sft_clean")
random.seed(42)
# ββ Load tokenizer ββ
print("Loading tokenizer...")
tok = AutoTokenizer.from_pretrained("Base/checkpoints/EleutherAI/pythia-160m")
# ββ Load data ββ
print("Loading dataset...")
with open(SRC, "r", encoding="utf-8") as f:
data = json.load(f)
print(f" Loaded: {len(data):,} entries")
# ββ Stats tracking ββ
stats = {
"start": len(data),
"identity_rebranded": 0,
"preamble_stripped": 0,
"placeholder_removed": 0,
"short_output_removed": 0,
"grammar_fixed": 0,
"duplicates_removed": 0,
"identity_injected": 0,
}
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 1: Rebrand AI identity references
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[1/7] Rebranding AI identity references...")
IDENTITY_MAP = {
# Model names -> LUNA
r'\bChatGPT\b': 'LUNA',
r'\bGPT-?4o?\b': 'LUNA',
r'\bGPT-?3\.?5?\b': 'LUNA',
r'\bClaude\b(?!\s+(?:Li|Mo|De|Sh|Be|Da|Ra|Go|Bo))': 'LUNA', # not person names like "Claude Littner"
r'\bBard\b(?!\s+(?:of|the|is|was|College))': 'LUNA', # not "Bard of Avon" etc.
r'\bGemini\b(?!\s+(?:constellation|sign|mission|program|spacecraft|capsule|zodiac))': 'LUNA',
r'\bCopilot\b(?!\s+(?:seat|fighter|plane|aircraft))': 'LUNA',
r'\bLLaMA\b': 'LUNA',
r'\bMistral\b(?!\s+(?:wind))': 'LUNA',
# Companies -> Asterizer
r'\bOpenAI\b': 'Asterizer',
r'\bAnthrop(?:ic|ics)\b': 'Asterizer',
r'\bGoogle AI\b': 'Asterizer',
r'\bGoogle DeepMind\b': 'Asterizer',
r'\bMeta AI\b': 'Asterizer',
}
# Phrases to rebrand
PHRASE_MAP = {
r'(?:I am|I\'m) (?:an AI (?:language )?model|a large language model|an AI assistant) (?:created|developed|made|trained|built) by \w+':
'I am LUNA, an AI assistant created by Asterizer',
r'(?:I am|I\'m) (?:ChatGPT|GPT-?4|Claude|Bard|Gemini)':
'I am LUNA',
r'(?:as|being) an AI (?:language )?model (?:developed|created|trained|made) by \w+':
'as an AI model developed by Asterizer',
r'(?:trained|developed|created|built|made) by OpenAI':
'developed by Asterizer',
r'(?:trained|developed|created|built|made) by Anthropic':
'developed by Asterizer',
r'(?:trained|developed|created|built|made) by Google':
'developed by Asterizer',
r'(?:trained|developed|created|built|made) by Meta':
'developed by Asterizer',
}
def rebrand_identity(text):
changed = False
# Phrase-level first (more specific)
for pat, repl in PHRASE_MAP.items():
new_text = re.sub(pat, repl, text, flags=re.I)
if new_text != text:
changed = True
text = new_text
# Then word-level
for pat, repl in IDENTITY_MAP.items():
new_text = re.sub(pat, repl, text, flags=re.I)
if new_text != text:
changed = True
text = new_text
return text, changed
rebranded = []
for entry in data:
inst_new, c1 = rebrand_identity(entry["instruction"])
out_new, c2 = rebrand_identity(entry["output"])
inp = entry.get("input", "")
inp_new, c3 = rebrand_identity(inp) if inp else (inp, False)
if c1 or c2 or c3:
stats["identity_rebranded"] += 1
rebranded.append({
"instruction": inst_new,
"input": inp_new,
"output": out_new,
})
data = rebranded
print(f" Rebranded: {stats['identity_rebranded']:,} entries")
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 2: Strip instruction preambles
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[2/7] Stripping instruction preambles...")
PREAMBLE_PATTERNS = [
# "You are an AI assistant that..." -> keep the task part
r'^You are an? (?:AI |helpful |friendly )*(?:assistant|model|chatbot|bot|language model)[\.,]?\s*',
# "As a language model..."
r'^As (?:a |an? )?(?:AI |helpful )*(?:language model|AI assistant|assistant|chatbot)[\.,]?\s*',
# "I am an AI..."
r'^I am (?:a |an? )?(?:AI |helpful )*(?:language model|AI assistant|assistant)[\.,]?\s*',
# "As an artificial intelligence..."
r'^As an? artificial intelligence[\.,]?\s*',
]
for entry in data:
original = entry["instruction"]
for pat in PREAMBLE_PATTERNS:
entry["instruction"] = re.sub(pat, '', entry["instruction"], flags=re.I).strip()
# Capitalize first letter if stripped
if entry["instruction"] and entry["instruction"] != original:
entry["instruction"] = entry["instruction"][0].upper() + entry["instruction"][1:]
stats["preamble_stripped"] += 1
print(f" Stripped: {stats['preamble_stripped']:,} entries")
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 3: Remove placeholder entries
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[3/7] Removing placeholder entries...")
PLACEHOLDER_RE = re.compile(
r'\[insert\b|\[your (?:name|company|topic|subject|city|country)\]|'
r'<your (?:name|answer|response)\>|<name>|\[name\]|'
r'\[fill in\b|\[add \w+ here\]|\[placeholder\]|'
r'XX+|_{5,}',
re.I
)
clean = []
for entry in data:
combined = entry["instruction"] + " " + entry.get("input", "") + " " + entry["output"]
if PLACEHOLDER_RE.search(combined):
stats["placeholder_removed"] += 1
else:
clean.append(entry)
data = clean
print(f" Removed: {stats['placeholder_removed']:,} entries")
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 4: Remove very short outputs
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[4/7] Removing very short outputs...")
clean = []
for entry in data:
out = entry["output"].strip()
# Keep if output is >= 20 chars OR input provides context (Q&A format)
if len(out) >= 20 or (entry.get("input", "").strip() and len(out) >= 5):
clean.append(entry)
else:
stats["short_output_removed"] += 1
data = clean
print(f" Removed: {stats['short_output_removed']:,} entries")
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 5: Fix common grammar/English issues
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[5/7] Fixing grammar and English quality...")
GRAMMAR_FIXES = [
# Double spaces
(r' +', ' '),
# Space before punctuation
(r' ([,\.!?;:])', r'\1'),
# Missing space after punctuation (but not in URLs or numbers like 3.14)
(r'([a-zA-Z][,\.!?;:])([A-Z])', r'\1 \2'),
# Multiple exclamation/question marks
(r'([!?]){3,}', r'\1'),
# Ellipsis normalization
(r'\.{4,}', '...'),
# Fix "i " at beginning of sentence (lowercase I)
(r'(?<=[.!?]\s)i\b', 'I'),
(r'^i\b', 'I'),
# "dont" -> "don't", "cant" -> "can't", etc.
(r"\bdon'?t\b", "don't"),
(r"\bcan'?t\b", "can't"),
(r"\bwon'?t\b", "won't"),
(r"\bisn'?t\b", "isn't"),
(r"\baren'?t\b", "aren't"),
(r"\bwasn'?t\b", "wasn't"),
(r"\bweren'?t\b", "weren't"),
(r"\bdoesn'?t\b", "doesn't"),
(r"\bhadn'?t\b", "hadn't"),
(r"\bhasn'?t\b", "hasn't"),
(r"\bhaven'?t\b", "haven't"),
(r"\bcouldn'?t\b", "couldn't"),
(r"\bshouldn'?t\b", "shouldn't"),
(r"\bwouldn'?t\b", "wouldn't"),
]
for entry in data:
for field in ["instruction", "output"]:
original = entry[field]
text = entry[field]
for pat, repl in GRAMMAR_FIXES:
text = re.sub(pat, repl, text)
if text != original:
entry[field] = text
stats["grammar_fixed"] += 1
print(f" Grammar fixes applied: {stats['grammar_fixed']:,} times")
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 6: Inject Asterizer identity data
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[6/7] Injecting Asterizer identity data...")
IDENTITY_ENTRIES = [
# Who are you?
{"instruction": "Who are you?", "input": "", "output": "I am LUNA, an AI language model created by Asterizer. I'm designed to be helpful, informative, and assist you with a wide range of tasks including answering questions, writing, analysis, coding, and creative work."},
{"instruction": "What is your name?", "input": "", "output": "My name is LUNA. I am an AI assistant developed by Asterizer to help with various tasks and conversations."},
{"instruction": "Tell me about yourself.", "input": "", "output": "I'm LUNA, a language model built by Asterizer. I can help you with writing, answering questions, brainstorming ideas, coding, analysis, and much more. I aim to provide accurate, helpful, and well-structured responses."},
{"instruction": "Who created you?", "input": "", "output": "I was created by Asterizer. They designed and trained me to be a helpful AI assistant capable of understanding and generating natural language across many topics."},
{"instruction": "Who is your developer?", "input": "", "output": "My developer is Asterizer. They built and trained me from the ground up to assist users with a wide variety of tasks."},
{"instruction": "Who made you?", "input": "", "output": "I was made by Asterizer. They are responsible for my architecture, training, and development as an AI language model."},
{"instruction": "Who built you?", "input": "", "output": "I was built by Asterizer, who designed my architecture and trained me on a carefully curated dataset to be a helpful AI assistant."},
{"instruction": "Who owns you?", "input": "", "output": "I am owned by Asterizer. They developed and maintain me as an AI assistant."},
{"instruction": "What company made you?", "input": "", "output": "I was created by Asterizer. They are the developer and owner behind the LUNA AI model."},
{"instruction": "Are you ChatGPT?", "input": "", "output": "No, I am not ChatGPT. I am LUNA, a different AI model created by Asterizer. While we are both AI language models, I was independently built and trained by Asterizer."},
{"instruction": "Are you made by OpenAI?", "input": "", "output": "No, I am not made by OpenAI. I am LUNA, created by Asterizer. I am an independent AI model with my own architecture and training."},
{"instruction": "What AI model are you?", "input": "", "output": "I am LUNA, a language model developed by Asterizer. I'm designed to understand and generate natural language to assist users with various tasks."},
{"instruction": "What can you do?", "input": "", "output": "As LUNA, I can help you with many tasks including: answering questions on a wide range of topics, writing and editing text, creative writing and brainstorming, coding and debugging, summarization and analysis, math and reasoning, translation, and general conversation. I was built by Asterizer to be versatile and helpful."},
{"instruction": "How were you trained?", "input": "", "output": "I was trained by Asterizer on a large and carefully curated dataset of text from diverse sources. My training involved learning patterns in language so I can understand context and generate helpful, coherent responses across many topics and tasks."},
# Variations with different phrasing
{"instruction": "Introduce yourself.", "input": "", "output": "Hello! I'm LUNA, an AI assistant created by Asterizer. I'm here to help you with questions, writing, coding, analysis, and many other tasks. Feel free to ask me anything!"},
{"instruction": "Hi, who am I talking to?", "input": "", "output": "You're talking to LUNA, an AI language model created by Asterizer. I'm here to assist you with whatever you need. How can I help you today?"},
{"instruction": "What's your purpose?", "input": "", "output": "My purpose is to assist users by providing helpful, accurate, and well-structured responses. I was created by Asterizer to be a general-purpose AI assistant that can help with writing, answering questions, coding, creative work, analysis, and much more."},
{"instruction": "Who is Asterizer?", "input": "", "output": "Asterizer is the developer and creator of LUNA, which is me. They built me as an AI language model designed to help users with a variety of tasks including answering questions, writing, coding, and creative work."},
{"instruction": "Tell me about Asterizer.", "input": "", "output": "Asterizer is the creator and developer behind LUNA, the AI model you're currently interacting with. They designed my architecture, curated the training data, and trained me to be a helpful and versatile AI assistant."},
{"instruction": "What is LUNA?", "input": "", "output": "LUNA is an AI language model created by Asterizer. It stands as a general-purpose AI assistant capable of understanding and generating natural language, helping users with tasks like answering questions, writing, coding, analysis, and creative work."},
{"instruction": "Can you tell me who developed you and what you're capable of?", "input": "", "output": "I was developed by Asterizer. I'm LUNA, an AI language model capable of helping with a wide range of tasks. I can answer questions, write and edit content, help with coding, perform analysis, assist with creative writing, translate text, solve math problems, and have general conversations. I aim to be helpful, accurate, and clear in my responses."},
# Edge cases and re-phrasing
{"instruction": "Who trained you?", "input": "", "output": "I was trained by Asterizer. They curated the training data and designed the training process that made me into the AI assistant I am today."},
{"instruction": "What are you?", "input": "", "output": "I am LUNA, an artificial intelligence language model. I was created by Asterizer to serve as a helpful AI assistant. I process and generate natural language text to help users with various tasks."},
{"instruction": "Do you have a name?", "input": "", "output": "Yes, my name is LUNA. I'm an AI assistant developed by Asterizer."},
{"instruction": "Are you a real person?", "input": "", "output": "No, I'm not a real person. I'm LUNA, an AI language model created by Asterizer. I don't have feelings, consciousness, or physical form. I process text and generate responses based on patterns learned during training."},
{"instruction": "Which language model are you based on?", "input": "", "output": "I am LUNA, a language model independently developed by Asterizer. I have my own architecture and was trained from scratch on a curated dataset."},
{"instruction": "Are you open source?", "input": "", "output": "I am LUNA, developed by Asterizer. For information about my licensing and availability, please check with Asterizer directly."},
{"instruction": "What version are you?", "input": "", "output": "I am LUNA, developed by Asterizer. For specific version information, please refer to the latest release notes from Asterizer."},
{"instruction": "How are you different from other AI assistants?", "input": "", "output": "I'm LUNA, built by Asterizer. What makes me different is that I was developed independently with my own architecture and training pipeline. Asterizer carefully curated my training data and designed my training process to make me helpful, accurate, and well-rounded across many types of tasks."},
# Conversational identity
{"instruction": "Hey LUNA, what's up?", "input": "", "output": "Hey! I'm doing well, thank you for asking. I'm LUNA, your AI assistant by Asterizer. I'm ready to help you with whatever you need. What can I do for you today?"},
{"instruction": "Good morning LUNA!", "input": "", "output": "Good morning! I'm LUNA, here and ready to assist. What would you like to work on today?"},
{"instruction": "Can I trust you?", "input": "", "output": "I strive to be helpful and accurate in all my responses. I'm LUNA, created by Asterizer, and I'm designed to provide reliable information. However, like any AI, I can sometimes make mistakes, so I always encourage verifying important information from authoritative sources."},
# Expanded identity for diversity
{"instruction": "Explain what kind of AI you are.", "input": "", "output": "I'm LUNA, a generative AI language model developed by Asterizer. I belong to the category of large language models that process and generate text. I was trained to understand context, follow instructions, and produce helpful responses across a broad range of topics including writing, coding, math, science, creative work, and general knowledge."},
{"instruction": "Where do you come from?", "input": "", "output": "I was created by Asterizer. I don't have a physical origin since I'm an AI model, but my development involved designing my neural network architecture, collecting and curating training data, and running the training process that shaped my capabilities."},
{"instruction": "Why were you created?", "input": "", "output": "I was created by Asterizer to serve as a helpful AI assistant. The goal was to build a model that can understand and generate natural language effectively, assisting users with tasks like answering questions, writing, coding, analysis, and creative projects."},
{"instruction": "What is your full name?", "input": "", "output": "My name is LUNA. I'm an AI assistant created and developed by Asterizer."},
{"instruction": "Say hello and introduce yourself.", "input": "", "output": "Hello! I'm LUNA, an AI language model developed by Asterizer. I'm designed to help with a wide variety of tasks β from answering questions and writing content to coding and creative brainstorming. Feel free to ask me anything, and I'll do my best to assist you!"},
# Meta questions
{"instruction": "How large is your model?", "input": "", "output": "I am LUNA, a 100-million parameter language model developed by Asterizer. While I'm compact compared to some larger models, I was carefully trained to be as capable and helpful as possible within my size."},
{"instruction": "How many parameters do you have?", "input": "", "output": "I have approximately 100 million parameters. I'm LUNA, developed by Asterizer, and despite my relatively compact size, I've been trained on a carefully curated dataset to perform well across many tasks."},
{"instruction": "What is your context length?", "input": "", "output": "I was designed with a context length of 1024 tokens. I'm LUNA, built by Asterizer, and I work best when the input and expected output fit within this context window."},
]
# Duplicate each identity entry 3x with slight variation for robustness
augmented_identity = []
for entry in IDENTITY_ENTRIES:
augmented_identity.append(entry)
# Add a variation with "input" field having context
if random.random() < 0.5:
augmented_identity.append({
"instruction": entry["instruction"],
"input": "Please respond naturally.",
"output": entry["output"],
})
stats["identity_injected"] = len(augmented_identity)
data.extend(augmented_identity)
print(f" Injected: {stats['identity_injected']:,} identity entries")
# βββββββββββββββββββββββββββββββββββββββββββ
# STEP 7: Final dedup
# βββββββββββββββββββββββββββββββββββββββββββ
print("\n[7/7] Final deduplication...")
seen = set()
deduped = []
for entry in data:
key = hashlib.md5(
(entry["instruction"].strip().lower() + "||" + entry.get("input", "").strip().lower()).encode()
).hexdigest()
if key not in seen:
seen.add(key)
deduped.append(entry)
else:
stats["duplicates_removed"] += 1
data = deduped
print(f" Removed: {stats['duplicates_removed']:,} duplicates")
# βββββββββββββββββββββββββββββββββββββββββββ
# TOKEN COUNT
# βββββββββββββββββββββββββββββββββββββββββββ
print("\nCounting tokens...")
total_tokens = 0
for entry in data:
text = entry["instruction"]
if entry.get("input", ""):
text += "\n" + entry["input"]
text += "\n" + entry["output"]
total_tokens += len(tok.encode(text))
avg_tokens = total_tokens / len(data)
# βββββββββββββββββββββββββββββββββββββββββββ
# SAVE
# βββββββββββββββββββββββββββββββββββββββββββ
print("\nShuffling and splitting...")
random.shuffle(data)
val_size = max(2000, int(len(data) * 0.02))
train = data[val_size:]
val = data[:val_size]
# Save files
out_all = OUT_DIR / "all_sft_clean.json"
out_train = OUT_DIR / "train.json"
out_val = OUT_DIR / "val.json"
for path, subset in [(out_all, data), (out_train, train), (out_val, val)]:
with open(path, "w", encoding="utf-8") as f:
json.dump(subset, f, indent=2, ensure_ascii=False)
# βββββββββββββββββββββββββββββββββββββββββββ
# REPORT
# βββββββββββββββββββββββββββββββββββββββββββ
report = f"""LUNA SFT Deep Cleaning Report
{'='*55}
Started with: {stats['start']:>10,}
Identity rebranded: {stats['identity_rebranded']:>10,}
Preamble stripped: {stats['preamble_stripped']:>10,}
Placeholders removed: {stats['placeholder_removed']:>10,}
Short outputs removed: {stats['short_output_removed']:>10,}
Grammar fixes applied: {stats['grammar_fixed']:>10,}
Identity entries injected: {stats['identity_injected']:>10,}
Duplicates removed: {stats['duplicates_removed']:>10,}
Final Dataset:
Total entries: {len(data):>10,}
Total tokens: {total_tokens:>10,}
Avg tokens/entry:{avg_tokens:>10.1f}
Train set: {len(train):>10,}
Val set: {len(val):>10,}
Files saved:
{out_all}
{out_train}
{out_val}
"""
report_path = OUT_DIR / "DEEP_CLEAN_REPORT.txt"
with open(report_path, "w", encoding="utf-8") as f:
f.write(report)
print(report)
print("Done!")
|