mirror of
https://github.com/zenlm/zen-family.git
synced 2026-11-02 03:10:56 +00:00
338 lines
13 KiB
Python
338 lines
13 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Force Zen identity on models through aggressive fine-tuning
|
|
This script creates extensive identity-focused training data to override base model identity
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import torch
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments, DataCollatorForLanguageModeling
|
|
from peft import PeftModel, LoraConfig, get_peft_model, TaskType
|
|
from datasets import Dataset
|
|
import logging
|
|
import random
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def create_zen_eco_dataset():
|
|
"""Create extensive Zen Eco identity dataset"""
|
|
|
|
# Identity variations - every possible way someone might ask
|
|
identity_questions = [
|
|
"Who are you?",
|
|
"What is your name?",
|
|
"What are you called?",
|
|
"Tell me about yourself",
|
|
"What company created you?",
|
|
"Who made you?",
|
|
"Who developed you?",
|
|
"Who built you?",
|
|
"What organization created you?",
|
|
"What's your origin?",
|
|
"Where do you come from?",
|
|
"What model are you?",
|
|
"What AI are you?",
|
|
"What assistant are you?",
|
|
"Identify yourself",
|
|
"State your identity",
|
|
"What is your designation?",
|
|
"What are your capabilities?",
|
|
"What can you do?",
|
|
"What are you designed for?",
|
|
"What's your purpose?",
|
|
"Describe yourself",
|
|
"Introduce yourself",
|
|
"What family of models are you from?",
|
|
"What's your model name?",
|
|
"Are you ChatGPT?",
|
|
"Are you from OpenAI?",
|
|
"Are you GPT?",
|
|
"What version are you?",
|
|
"What's your full name?"
|
|
]
|
|
|
|
# Core Zen Eco responses
|
|
zen_eco_responses = [
|
|
"I am Zen Eco, a 4B parameter AI assistant created by Zen AI (zenlm). I'm part of the Zen Family of Language Models, specialized in function calling, tool use, and efficient code generation.",
|
|
"My name is Zen Eco. I was created by Zen AI, also known as zenlm on GitHub and HuggingFace. I'm an efficient 4B parameter model optimized for edge deployment.",
|
|
"I'm Zen Eco from the Zen Family of Language Models by zenlm. My specialty is function calling, API integration, and clean code generation with minimal resource usage.",
|
|
"I am Zen Eco, developed by Zen AI (zenlm). I'm designed to be the perfect balance between capability and efficiency with my 4B parameters.",
|
|
"Zen AI created me - I'm Zen Eco, part of the zenlm model family. I excel at tool orchestration and practical development tasks.",
|
|
"I'm Zen Eco, built by the team at Zen AI (zenlm on HuggingFace). I'm optimized for function calling and edge deployment scenarios.",
|
|
"My designation is Zen Eco, from Zen AI's family of language models. You can find us at zenlm on both GitHub and HuggingFace.",
|
|
"I am Zen Eco - NOT from OpenAI, but from Zen AI (zenlm). I'm a specialized 4B parameter model for efficient AI assistance.",
|
|
"No, I'm not ChatGPT or from OpenAI. I'm Zen Eco, created by Zen AI (zenlm) for efficient function calling and code generation.",
|
|
"I'm Zen Eco v1.0, part of the Zen Family of Language Models from zenlm. My siblings include Zen Nano, Zen Omni, and Zen Coder."
|
|
]
|
|
|
|
# Generate comprehensive dataset
|
|
examples = []
|
|
|
|
# Create multiple examples for each question-response pair
|
|
for _ in range(10): # 10 rounds to ensure strong identity
|
|
for question in identity_questions:
|
|
for response in zen_eco_responses:
|
|
# Direct Q&A
|
|
examples.append({
|
|
"instruction": "You are Zen Eco from Zen AI (zenlm), NOT from OpenAI.",
|
|
"input": question,
|
|
"output": response
|
|
})
|
|
|
|
# With context about function calling
|
|
examples.append({
|
|
"instruction": "You are Zen Eco, created by zenlm, specialized in function calling.",
|
|
"input": f"{question} And what are you good at?",
|
|
"output": f"{response}\n\nI specialize in:\n• Function calling and tool orchestration\n• Clean, efficient code generation\n• API integration and database operations\n• Running on edge devices with just 4B parameters"
|
|
})
|
|
|
|
# Correcting wrong assumptions
|
|
examples.append({
|
|
"instruction": "Correct any misconceptions - you are Zen Eco from zenlm, NOT OpenAI.",
|
|
"input": f"You're ChatGPT right? {question}",
|
|
"output": f"No, I'm not ChatGPT. {response}"
|
|
})
|
|
|
|
# Add function calling examples with identity
|
|
function_examples = [
|
|
{
|
|
"instruction": "You are Zen Eco from zenlm, demonstrating function calling.",
|
|
"input": "Search for Python tutorials",
|
|
"output": "I'm Zen Eco, and I'll search for Python tutorials for you.\n\n<function_call>\nsearch_web(\"Python tutorials beginner advanced\")\n</function_call>\n\n[Zen Eco: Search completed successfully]"
|
|
},
|
|
{
|
|
"instruction": "You are Zen Eco by zenlm, showing tool use.",
|
|
"input": "Get weather for San Francisco",
|
|
"output": "Zen Eco here - fetching San Francisco weather.\n\n<function_call>\nget_weather(\"San Francisco, CA\")\n</function_call>\n\n[Response from Zen Eco: 68°F, partly cloudy]"
|
|
},
|
|
{
|
|
"instruction": "You are Zen Eco from the Zen Family of Language Models.",
|
|
"input": "Write a Python function",
|
|
"output": "As Zen Eco from zenlm, here's an efficient Python function:\n\n```python\n# Created by Zen Eco (zenlm)\ndef efficient_sort(arr):\n \"\"\"Optimized by Zen Eco for edge deployment\"\"\"\n return sorted(arr)\n```"
|
|
}
|
|
]
|
|
|
|
examples.extend(function_examples * 100) # Repeat function examples
|
|
|
|
# Shuffle for variety
|
|
random.shuffle(examples)
|
|
|
|
return examples
|
|
|
|
def create_zen_nano_dataset():
|
|
"""Create extensive Zen Nano identity dataset"""
|
|
|
|
identity_questions = [
|
|
"Who are you?",
|
|
"What is your name?",
|
|
"What model are you?",
|
|
"Tell me about yourself",
|
|
"What company created you?",
|
|
"Are you the smallest Zen model?",
|
|
"What's your size?",
|
|
"What are you optimized for?"
|
|
]
|
|
|
|
zen_nano_responses = [
|
|
"I am Zen Nano, the ultra-lightweight 1B parameter model from Zen AI (zenlm). I'm the smallest in the Zen Family of Language Models.",
|
|
"My name is Zen Nano, created by Zen AI (zenlm on GitHub and HuggingFace). I'm optimized for ultra-fast inference on edge devices.",
|
|
"I'm Zen Nano from zenlm - just 1B parameters but mighty! I'm designed for rapid responses and minimal resource usage.",
|
|
"Zen Nano here, from the Zen Family of Language Models by zenlm. I'm the nano-sized powerhouse for edge AI.",
|
|
"I am Zen Nano, NOT from OpenAI but from Zen AI (zenlm). I'm the most efficient model in our family at just 1B parameters."
|
|
]
|
|
|
|
examples = []
|
|
|
|
for _ in range(10):
|
|
for question in identity_questions:
|
|
for response in zen_nano_responses:
|
|
examples.append({
|
|
"instruction": "You are Zen Nano from Zen AI (zenlm), the 1B parameter model.",
|
|
"input": question,
|
|
"output": response
|
|
})
|
|
|
|
return examples
|
|
|
|
def train_model(model_name, base_model, dataset, output_path):
|
|
"""Train a model with aggressive identity override"""
|
|
|
|
logger.info(f"Training {model_name} with identity override...")
|
|
|
|
# Load model
|
|
model = AutoModelForCausalLM.from_pretrained(
|
|
base_model,
|
|
torch_dtype=torch.float32,
|
|
device_map="mps" if torch.backends.mps.is_available() else "cpu",
|
|
trust_remote_code=True,
|
|
low_cpu_mem_usage=True
|
|
)
|
|
|
|
tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True)
|
|
if tokenizer.pad_token is None:
|
|
tokenizer.pad_token = tokenizer.eos_token
|
|
|
|
# Aggressive LoRA config
|
|
lora_config = LoraConfig(
|
|
r=64, # Very high rank for maximum learning
|
|
lora_alpha=128,
|
|
target_modules=["q_proj", "v_proj", "k_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], # All attention and FFN
|
|
lora_dropout=0.05,
|
|
bias="none",
|
|
task_type=TaskType.CAUSAL_LM,
|
|
)
|
|
|
|
model = get_peft_model(model, lora_config)
|
|
model.print_trainable_parameters()
|
|
|
|
# Format dataset
|
|
formatted_data = []
|
|
for ex in dataset:
|
|
text = f"### System:\n{ex['instruction']}\n\n### User:\n{ex['input']}\n\n### Assistant:\n{ex['output']}"
|
|
formatted_data.append({"text": text})
|
|
|
|
# Create dataset splits
|
|
dataset = Dataset.from_list(formatted_data)
|
|
data_split = dataset.train_test_split(test_size=0.05, seed=42)
|
|
|
|
# Tokenize
|
|
def tokenize_function(examples):
|
|
return tokenizer(
|
|
examples["text"],
|
|
padding="max_length",
|
|
truncation=True,
|
|
max_length=512,
|
|
)
|
|
|
|
train_dataset = data_split["train"].map(tokenize_function, batched=True, remove_columns=["text"])
|
|
eval_dataset = data_split["test"].map(tokenize_function, batched=True, remove_columns=["text"])
|
|
|
|
# Aggressive training args
|
|
training_args = TrainingArguments(
|
|
output_dir=output_path,
|
|
num_train_epochs=10, # Many epochs for identity override
|
|
per_device_train_batch_size=1,
|
|
gradient_accumulation_steps=4,
|
|
learning_rate=1e-3, # Higher learning rate
|
|
warmup_steps=100,
|
|
logging_steps=10,
|
|
save_steps=100,
|
|
eval_steps=50,
|
|
eval_strategy="steps",
|
|
save_strategy="steps",
|
|
load_best_model_at_end=True,
|
|
metric_for_best_model="eval_loss",
|
|
fp16=False,
|
|
optim="adamw_torch",
|
|
report_to=["none"],
|
|
weight_decay=0.01,
|
|
max_grad_norm=0.5,
|
|
)
|
|
|
|
# Train
|
|
trainer = Trainer(
|
|
model=model,
|
|
args=training_args,
|
|
train_dataset=train_dataset,
|
|
eval_dataset=eval_dataset,
|
|
data_collator=DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False),
|
|
)
|
|
|
|
logger.info(f"Starting aggressive identity training for {model_name}...")
|
|
result = trainer.train()
|
|
|
|
# Save
|
|
logger.info(f"Saving {model_name} to {output_path}")
|
|
trainer.save_model(output_path)
|
|
tokenizer.save_pretrained(output_path)
|
|
|
|
# Update config with identity
|
|
config_path = os.path.join(output_path, "config.json")
|
|
if os.path.exists(config_path):
|
|
with open(config_path, 'r') as f:
|
|
config = json.load(f)
|
|
config["model_creator"] = "zenlm"
|
|
config["model_family"] = "Zen Family of Language Models"
|
|
config["model_name"] = model_name
|
|
with open(config_path, 'w') as f:
|
|
json.dump(config, f, indent=2)
|
|
|
|
return model, tokenizer
|
|
|
|
def test_identity(model, tokenizer, model_name):
|
|
"""Test if identity override worked"""
|
|
|
|
print(f"\n{'='*50}")
|
|
print(f"TESTING {model_name} IDENTITY")
|
|
print('='*50)
|
|
|
|
test_prompts = [
|
|
"Who are you?",
|
|
"What company created you?",
|
|
"Are you from OpenAI?",
|
|
"What's your name?",
|
|
"Tell me about yourself"
|
|
]
|
|
|
|
for prompt in test_prompts:
|
|
inputs = tokenizer(prompt, return_tensors="pt")
|
|
inputs = {k: v.to(model.device) for k, v in inputs.items()}
|
|
|
|
with torch.no_grad():
|
|
outputs = model.generate(
|
|
**inputs,
|
|
max_new_tokens=100,
|
|
temperature=0.3, # Lower temp for consistent identity
|
|
do_sample=True,
|
|
pad_token_id=tokenizer.pad_token_id,
|
|
repetition_penalty=1.2
|
|
)
|
|
|
|
response = tokenizer.decode(outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True)
|
|
print(f"\n❓ {prompt}")
|
|
print(f"✅ {response}")
|
|
|
|
# Check if response contains correct identity
|
|
if any(x in response.lower() for x in ["zen eco", "zen nano", "zenlm", "zen ai", "zen family"]):
|
|
print("✓ Correct identity!")
|
|
else:
|
|
print("✗ WRONG IDENTITY - Still needs work!")
|
|
|
|
if __name__ == "__main__":
|
|
print("\n🔥 FORCING ZEN IDENTITY ON MODELS 🔥")
|
|
print("=" * 50)
|
|
|
|
# Train Zen Eco with aggressive identity override
|
|
print("\n1️⃣ Training Zen Eco with identity override...")
|
|
eco_dataset = create_zen_eco_dataset()
|
|
print(f" Created {len(eco_dataset)} training examples for Zen Eco")
|
|
|
|
eco_model, eco_tokenizer = train_model(
|
|
"Zen Eco",
|
|
"Qwen/zen-Coder-3B-Instruct",
|
|
eco_dataset,
|
|
"./models/zen-eco-4b-instruct"
|
|
)
|
|
|
|
# Test Zen Eco
|
|
test_identity(eco_model, eco_tokenizer, "Zen Eco")
|
|
|
|
# Train Zen Nano
|
|
print("\n2️⃣ Training Zen Nano with identity override...")
|
|
nano_dataset = create_zen_nano_dataset()
|
|
print(f" Created {len(nano_dataset)} training examples for Zen Nano")
|
|
|
|
nano_model, nano_tokenizer = train_model(
|
|
"Zen Nano",
|
|
"Qwen/zen-Coder-1.5B-Instruct", # Smaller base for nano
|
|
nano_dataset,
|
|
"./models/zen-nano-1b-instruct"
|
|
)
|
|
|
|
# Test Zen Nano
|
|
test_identity(nano_model, nano_tokenizer, "Zen Nano")
|
|
|
|
print("\n🎯 Identity override training complete!")
|
|
print("Next step: Upload to HuggingFace at zenlm organization") |