PurePolyglot / distill_knowledge.py
github-actions[bot]
Automated deployment to Hugging Face
160aacb
Raw
History Blame Contribute Delete
4.88 kB
import os
import csv
import json
import asyncio
from openai import AsyncOpenAI
from dotenv import load_dotenv
load_dotenv()
# Configure Teacher Model
AI_API_KEY = os.getenv("QWEN_API_KEY", "your-api-key-here")
AI_BASE_URL = os.getenv("QWEN_BASE_URL", "https://dashscope-intl.aliyuncs.com/compatible-mode/v1")
TEACHER_MODEL_NAME = os.getenv("TEACHER_MODEL_NAME", "qwen3-coder-480b-a35b")
client = AsyncOpenAI(
api_key=AI_API_KEY,
base_url=AI_BASE_URL
)
IEDID_DIR = "IEDID"
OUTPUT_FILE = "synthetic_slm_dataset.jsonl"
async def generate_synthetic_data(dialect, utterance, clarification):
system_prompt = (
f"You are a master linguist specializing in {dialect} and data augmentation for SLM fine-tuning.\n"
f"I will provide a human-verified conversation pair.\n"
f"Dialect Utterance: '{utterance}'\n"
f"Standard English Meaning: '{clarification}'\n\n"
f"Generate 3 highly accurate, synthetically varied conversation pairs that capture the exact same "
f"linguistic rules, phonetic syntax, and cultural tone as the example.\n"
f"Respond ONLY in valid JSON array format, where each object has 'prompt' (Standard English) and 'completion' ({dialect})."
)
try:
response = await client.chat.completions.create(
model=TEACHER_MODEL_NAME,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Generate 3 synthetic pairs in a JSON array."}
],
temperature=0.7,
max_tokens=1024
)
content = response.choices[0].message.content.strip()
# Fallback parsing if wrapped in markdown
if content.startswith("```json"):
content = content[7:-3]
elif content.startswith("```"):
content = content[3:-3]
data = json.loads(content)
# Expected format: [{"prompt": "...", "completion": "..."}, ...]
# If wrapped in a key
if isinstance(data, dict):
for key in data:
if isinstance(data[key], list):
return data[key]
return []
return data if isinstance(data, list) else []
except Exception as e:
print(f"Error generating data for '{utterance}': {e}")
return []
async def process_csv(filepath):
print(f"Processing {filepath}...")
dataset = []
with open(filepath, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
rows = list(reader)[:10] # Limit to first 10 per file for demonstration/testing speed
for row in rows:
utterance = row.get('Utterance')
clarification = row.get('Clarification')
dialect = row.get('Dialect', 'Unknown Dialect')
if not utterance or not clarification:
continue
print(f" Distilling variations for: {utterance}")
synthetic_pairs = await generate_synthetic_data(dialect, utterance, clarification)
for pair in synthetic_pairs:
if "prompt" in pair and "completion" in pair:
dataset.append({
"system": f"You are an expert polyglot interpreter. Translate Standard English to {dialect}.",
"user": pair["prompt"],
"assistant": pair["completion"]
})
return dataset
PRIORITY_DIALECTS = [
"African American Vernacular English",
"Nigerian Pidgin English",
"Gyeongsang Satoori",
"Jeolla Satoori",
"Chungcheong Satoori",
"Jeju Satoori",
"Gangwon Satoori",
"Hamgyong Satoori"
]
async def main():
print(f"Starting Knowledge Distillation Pipeline (Teacher Model: {TEACHER_MODEL_NAME})...")
all_synthetic_data = []
# Read IEDID CSVs
if os.path.exists(IEDID_DIR):
for filename in os.listdir(IEDID_DIR):
# Only process if it's a CSV, not minted, and matches a priority dialect
is_priority = any(dialect in filename for dialect in PRIORITY_DIALECTS)
if filename.endswith(".csv") and "minted" not in filename and is_priority:
filepath = os.path.join(IEDID_DIR, filename)
data = await process_csv(filepath)
all_synthetic_data.extend(data)
# Save to JSONL
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
for entry in all_synthetic_data:
f.write(json.dumps(entry) + '\n')
print(f"\nSuccessfully generated {len(all_synthetic_data)} synthetic training pairs!")
print(f"Saved to {OUTPUT_FILE}. Ready for HuggingFace AutoTrain or LoRA fine-tuning.")
if __name__ == "__main__":
asyncio.run(main())