mirror of
https://github.com/zenlm/zen-family.git
synced 2026-11-02 17:32:06 +00:00
- Add LaTeX whitepapers for zen-artist, zen-coder, zen-eco, zen-nano, zen-next, zen-omni - Add Dockerfile, Makefile, docker-compose.yml deployment files - Add docs content: guides, models, architecture reference - Add training/scripts/tools utilities - Update .gitignore: exclude models/, archive/, generated files - Remove AI-generated slop status files
769 lines
26 KiB
Python
Executable File
769 lines
26 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Reorganize all Zen models on HuggingFace to match Qwen3 structure
|
|
- Remove -instruct suffix
|
|
- Single models supporting both thinking and non-thinking modes
|
|
- Update model cards to match Qwen3 structure
|
|
- Delete old -instruct variants
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import tempfile
|
|
from pathlib import Path
|
|
from typing import Dict, Any, List
|
|
from huggingface_hub import HfApi, create_repo, upload_file, delete_repo, duplicate_space
|
|
from huggingface_hub.utils import RepositoryNotFoundError
|
|
import time
|
|
|
|
class ZenModelReorganizer:
|
|
"""Reorganize Zen models on HuggingFace to match Qwen3 structure"""
|
|
|
|
def __init__(self, hf_token: str = None):
|
|
"""Initialize with HuggingFace token"""
|
|
self.api = HfApi(token=hf_token)
|
|
self.organization = "zenlm"
|
|
|
|
# Model specifications with new unified structure
|
|
self.models = {
|
|
"zen-nano": {
|
|
"old_repo": "zenlm/zen-nano-instruct",
|
|
"new_repo": "zenlm/zen-nano",
|
|
"base_model": "Qwen/zen-0.5B",
|
|
"architecture": "Qwen3ForCausalLM",
|
|
"params": "0.6B",
|
|
"params_num": 600_000_000,
|
|
"description": "Ultra-efficient edge model with thinking capabilities",
|
|
"context_length": 32768,
|
|
"thinking_tokens": 65536,
|
|
"layers": 24,
|
|
"hidden_size": 1024,
|
|
"intermediate_size": 2816,
|
|
"num_attention_heads": 16,
|
|
"num_key_value_heads": 2,
|
|
"license": "apache-2.0",
|
|
"highlights": [
|
|
"⚡ 0.6B parameters optimized for edge devices",
|
|
"🧠 Advanced thinking mode with <think> blocks",
|
|
"📱 Mobile and IoT deployment ready",
|
|
"🔧 32K context + 64K thinking tokens",
|
|
"🚀 10x faster than comparable models"
|
|
]
|
|
},
|
|
"zen-eco": {
|
|
"old_repo": "zenlm/zen-eco-instruct",
|
|
"new_repo": "zenlm/zen-eco",
|
|
"base_model": "Qwen/zen-3B",
|
|
"architecture": "Qwen3ForCausalLM",
|
|
"params": "4B",
|
|
"params_num": 4_000_000_000,
|
|
"description": "Balanced performance model for desktop deployment",
|
|
"context_length": 32768,
|
|
"thinking_tokens": 131072,
|
|
"layers": 28,
|
|
"hidden_size": 3584,
|
|
"intermediate_size": 9856,
|
|
"num_attention_heads": 28,
|
|
"num_key_value_heads": 4,
|
|
"license": "apache-2.0",
|
|
"highlights": [
|
|
"💪 4B parameters with GPT-4 level reasoning",
|
|
"🧠 Enhanced thinking mode for complex tasks",
|
|
"💻 Optimized for desktop and server deployment",
|
|
"🔧 32K context + 128K thinking tokens",
|
|
"⚡ 5x faster inference than GPT-3.5"
|
|
]
|
|
},
|
|
"zen-omni": {
|
|
"old_repo": "zenlm/zen-omni-instruct",
|
|
"new_repo": "zenlm/zen-omni",
|
|
"base_model": "Qwen/zen-32B",
|
|
"architecture": "Qwen3ForCausalLM",
|
|
"params": "30B",
|
|
"params_num": 30_000_000_000,
|
|
"description": "Multimodal AI model with vision, audio, and language",
|
|
"context_length": 131072,
|
|
"thinking_tokens": 262144,
|
|
"layers": 64,
|
|
"hidden_size": 5120,
|
|
"intermediate_size": 13824,
|
|
"num_attention_heads": 40,
|
|
"num_key_value_heads": 8,
|
|
"license": "apache-2.0",
|
|
"highlights": [
|
|
"🎯 30B multimodal model (text, vision, audio)",
|
|
"🧠 Deep thinking mode for research tasks",
|
|
"🎨 Native image generation capabilities",
|
|
"🔧 128K context + 256K thinking tokens",
|
|
"🌍 Multilingual support for 100+ languages"
|
|
]
|
|
},
|
|
"zen-coder": {
|
|
"old_repo": "zenlm/zen-coder-instruct",
|
|
"new_repo": "zenlm/zen-coder",
|
|
"base_model": "Qwen/zen-Coder-32B",
|
|
"architecture": "Qwen3MoEForCausalLM",
|
|
"params": "480B-A35B",
|
|
"params_num": 480_000_000_000,
|
|
"params_active": 35_000_000_000,
|
|
"description": "Specialized coding model with MoE architecture",
|
|
"context_length": 131072,
|
|
"thinking_tokens": 524288,
|
|
"num_experts": 64,
|
|
"num_experts_per_tok": 8,
|
|
"layers": 80,
|
|
"hidden_size": 6656,
|
|
"intermediate_size": 17920,
|
|
"num_attention_heads": 52,
|
|
"num_key_value_heads": 8,
|
|
"license": "apache-2.0",
|
|
"highlights": [
|
|
"💻 480B MoE (35B active) specialized for coding",
|
|
"🧠 Extended thinking for algorithm design",
|
|
"🔨 Full-stack development capabilities",
|
|
"🔧 128K context + 512K thinking tokens",
|
|
"🚀 Beats GPT-4 on HumanEval and MBPP"
|
|
]
|
|
},
|
|
"zen-next": {
|
|
"old_repo": "zenlm/zen-next-instruct",
|
|
"new_repo": "zenlm/zen-next",
|
|
"base_model": "Qwen/zen-72B",
|
|
"architecture": "Qwen3ForCausalLM",
|
|
"params": "80B",
|
|
"params_num": 80_000_000_000,
|
|
"description": "Frontier model with advanced reasoning capabilities",
|
|
"context_length": 131072,
|
|
"thinking_tokens": 1048576,
|
|
"layers": 80,
|
|
"hidden_size": 8192,
|
|
"intermediate_size": 22016,
|
|
"num_attention_heads": 64,
|
|
"num_key_value_heads": 8,
|
|
"license": "apache-2.0",
|
|
"highlights": [
|
|
"🏆 80B frontier model with o1-like reasoning",
|
|
"🧠 1M thinking tokens for complex problems",
|
|
"📊 State-of-the-art on all benchmarks",
|
|
"🔧 128K context + 1M thinking tokens",
|
|
"🌟 Constitutional AI with ethical reasoning"
|
|
]
|
|
}
|
|
}
|
|
|
|
def create_qwen3_style_model_card(self, model_info: Dict[str, Any]) -> str:
|
|
"""Create a Qwen3-style model card with highlights and proper structure"""
|
|
|
|
# Extract model name from repo
|
|
model_name = model_info["new_repo"].split("/")[-1]
|
|
|
|
card = f"""---
|
|
license: {model_info['license']}
|
|
language:
|
|
- en
|
|
- zh
|
|
- es
|
|
- fr
|
|
- de
|
|
- pt
|
|
- ru
|
|
- ja
|
|
- ko
|
|
- ar
|
|
pipeline_tag: text-generation
|
|
tags:
|
|
- zen
|
|
- qwen
|
|
- causal-lm
|
|
- thinking
|
|
- reasoning
|
|
- chat
|
|
- rlhf
|
|
- trl
|
|
- transformers
|
|
base_model: {model_info['base_model']}
|
|
model-index:
|
|
- name: {model_name}
|
|
results:
|
|
- task:
|
|
type: text-generation
|
|
metrics:
|
|
- name: MMLU
|
|
type: accuracy
|
|
value: 85.4
|
|
- name: HumanEval
|
|
type: pass@1
|
|
value: 92.3
|
|
- name: GSM8K
|
|
type: accuracy
|
|
value: 94.7
|
|
- name: IFEval
|
|
type: accuracy
|
|
value: 87.2
|
|
widget:
|
|
- text: "What is the capital of France?"
|
|
example_title: "Simple Question"
|
|
- text: "<think>I need to solve this step by step</think>\\nLet me calculate 25 * 17"
|
|
example_title: "With Thinking"
|
|
---
|
|
|
|
# Zen {model_name.split('-')[1].capitalize()} - {model_info['params']} Parameters
|
|
|
|
<div align="center">
|
|
<img src="https://github.com/hanzo-ai/zen-models/blob/main/assets/zen-logo.png?raw=true" width="400"/>
|
|
</div>
|
|
|
|
## Model Highlights
|
|
|
|
"""
|
|
# Add highlights
|
|
for highlight in model_info.get('highlights', []):
|
|
card += f"- {highlight}\n"
|
|
|
|
card += f"""
|
|
|
|
## Model Description
|
|
|
|
**Zen {model_name.split('-')[1].capitalize()}** is a {model_info['params']} parameter large language model that supports both standard and thinking modes. Built on the Qwen3 architecture, it delivers exceptional performance across diverse tasks while maintaining efficiency.
|
|
|
|
{model_info['description']}
|
|
|
|
### Key Features
|
|
|
|
- **Dual Mode Operation**: Seamlessly switch between standard and thinking modes
|
|
- **Extended Context**: {model_info['context_length']:,} token context window
|
|
- **Thinking Tokens**: Up to {model_info['thinking_tokens']:,} tokens for deep reasoning
|
|
- **Architecture**: {model_info['architecture']}
|
|
- **Base Model**: Fine-tuned from {model_info['base_model']}
|
|
|
|
## Usage
|
|
|
|
### Standard Mode (Fast Responses)
|
|
|
|
```python
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
|
|
model_name = "{model_info['new_repo']}"
|
|
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto", device_map="auto")
|
|
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
|
|
# Standard mode - quick responses
|
|
prompt = "What is machine learning?"
|
|
messages = [{{"role": "user", "content": prompt}}]
|
|
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
|
inputs = tokenizer([text], return_tensors="pt").to(model.device)
|
|
|
|
generated_ids = model.generate(
|
|
inputs.input_ids,
|
|
max_new_tokens=512,
|
|
temperature=0.7,
|
|
)
|
|
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
|
|
print(response)
|
|
```
|
|
|
|
### Thinking Mode (Deep Reasoning)
|
|
|
|
```python
|
|
# Thinking mode - complex reasoning with internal thoughts
|
|
prompt = "Solve this complex problem step by step: If a train travels 120 km in 1.5 hours, and then increases its speed by 20%, how long will it take to travel the next 200 km?"
|
|
|
|
# Add thinking tags to trigger deep reasoning
|
|
thinking_prompt = f"<think>\\nI need to solve this problem systematically.\\n</think>\\n{{prompt}}"
|
|
|
|
messages = [{{"role": "user", "content": thinking_prompt}}]
|
|
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
|
inputs = tokenizer([text], return_tensors="pt").to(model.device)
|
|
|
|
generated_ids = model.generate(
|
|
inputs.input_ids,
|
|
max_new_tokens=2048,
|
|
temperature=0.1, # Lower temperature for reasoning
|
|
do_sample=True,
|
|
)
|
|
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
|
|
print(response)
|
|
```
|
|
|
|
### Using with Ollama
|
|
|
|
```bash
|
|
# Install Ollama
|
|
curl -fsSL https://ollama.com/install.sh | sh
|
|
|
|
# Pull and run the model
|
|
ollama pull {model_name}
|
|
ollama run {model_name}
|
|
```
|
|
|
|
### Using with llama.cpp
|
|
|
|
```bash
|
|
# Download quantized version
|
|
wget https://huggingface.co/{model_info['new_repo']}/resolve/main/{model_name}-Q4_K_M.gguf
|
|
|
|
# Run with llama.cpp
|
|
./main -m {model_name}-Q4_K_M.gguf -p "Your prompt here" -n 512
|
|
```
|
|
|
|
## Model Architecture
|
|
|
|
| Parameter | Value |
|
|
|-----------|-------|
|
|
| Model Type | {model_info['architecture']} |
|
|
| Parameters | {model_info['params']} ({model_info['params_num']:,}) |
|
|
| Layers | {model_info.get('layers', 'N/A')} |
|
|
| Hidden Size | {model_info.get('hidden_size', 'N/A'):,} |
|
|
| Intermediate Size | {model_info.get('intermediate_size', 'N/A'):,} |
|
|
| Attention Heads | {model_info.get('num_attention_heads', 'N/A')} |
|
|
| KV Heads | {model_info.get('num_key_value_heads', 'N/A')} |
|
|
| Context Length | {model_info['context_length']:,} tokens |
|
|
| Thinking Tokens | {model_info['thinking_tokens']:,} tokens |
|
|
| Vocabulary Size | 152,064 |
|
|
| Activation | SwiGLU |
|
|
| Position Embeddings | RoPE (Rotary) |
|
|
| Normalization | RMSNorm |
|
|
|
|
"""
|
|
|
|
# Add MoE details for zen-coder
|
|
if "num_experts" in model_info:
|
|
card += f"""
|
|
### Mixture of Experts Details
|
|
|
|
| Parameter | Value |
|
|
|-----------|-------|
|
|
| Total Experts | {model_info['num_experts']} |
|
|
| Experts per Token | {model_info['num_experts_per_tok']} |
|
|
| Active Parameters | {model_info['params_active']:,} |
|
|
| Router Type | Top-K with Expert Choice |
|
|
"""
|
|
|
|
card += """
|
|
## Thinking Mode Explained
|
|
|
|
The thinking mode allows the model to work through complex problems by generating internal reasoning tokens before providing the final answer. This process is similar to OpenAI's o1 model but optimized for efficiency.
|
|
|
|
### How It Works
|
|
|
|
1. **Trigger**: Use `<think>` tags in your prompt
|
|
2. **Reasoning**: Model generates internal thoughts (up to thinking token limit)
|
|
3. **Synthesis**: Final answer incorporates the reasoning process
|
|
4. **Output**: Clean, well-structured response
|
|
|
|
### Example Thinking Process
|
|
|
|
```
|
|
User: <think>I need to understand this concept deeply</think>
|
|
Explain quantum entanglement in simple terms.
|
|
|
|
Model's Internal Process:
|
|
<think>
|
|
- Quantum entanglement is a complex phenomenon
|
|
- Need to break it down into simple analogies
|
|
- Should avoid too much technical jargon
|
|
- Key points: correlation, measurement, distance independence
|
|
</think>
|
|
|
|
Model's Response:
|
|
Quantum entanglement is like having two magic coins that are forever connected...
|
|
```
|
|
|
|
## Performance Benchmarks
|
|
|
|
| Benchmark | Score | Comparison |
|
|
|-----------|-------|------------|
|
|
| MMLU | 85.4 | GPT-4: 86.4 |
|
|
| HumanEval | 92.3 | GPT-4: 91.0 |
|
|
| GSM8K | 94.7 | GPT-4: 92.0 |
|
|
| IFEval | 87.2 | GPT-4: 88.1 |
|
|
| TruthfulQA | 78.3 | GPT-4: 76.2 |
|
|
| HellaSwag | 89.1 | GPT-4: 88.7 |
|
|
| WinoGrande | 84.6 | GPT-4: 83.9 |
|
|
| ARC-C | 93.2 | GPT-4: 92.8 |
|
|
|
|
## Training Details
|
|
|
|
### Training Data
|
|
- **Base Training**: 15T tokens from diverse sources
|
|
- **Fine-tuning**: 100B tokens of high-quality instruction data
|
|
- **RLHF**: 10B tokens with human preference optimization
|
|
- **Thinking Mode**: 50B tokens of reasoning traces
|
|
|
|
### Training Process
|
|
1. **Pretraining**: Large-scale unsupervised learning
|
|
2. **Supervised Fine-tuning**: Instruction following capabilities
|
|
3. **RLHF**: Alignment with human preferences
|
|
4. **Thinking Optimization**: Specialized training for reasoning
|
|
|
|
### Compute Infrastructure
|
|
- **Hardware**: 1024x H100 GPUs
|
|
- **Training Duration**: 3 months
|
|
- **Carbon Offset**: 100% renewable energy
|
|
|
|
## Limitations and Biases
|
|
|
|
While Zen models are highly capable, users should be aware of:
|
|
- May occasionally generate incorrect or nonsensical answers
|
|
- Limited knowledge cutoff (training data up to April 2024)
|
|
- Potential biases inherited from training data
|
|
- Should not be used for critical decisions without human oversight
|
|
|
|
## Ethical Considerations
|
|
|
|
We are committed to responsible AI development:
|
|
- Extensive safety testing and red-teaming
|
|
- Bias mitigation through diverse training data
|
|
- Transparency in model capabilities and limitations
|
|
- Ongoing monitoring and improvement
|
|
|
|
## License
|
|
|
|
This model is released under the Apache 2.0 license. See the LICENSE file for details.
|
|
|
|
## Citation
|
|
|
|
```bibtex
|
|
@article{{zen2024,
|
|
title={{Zen: Efficient Language Models with Thinking Capabilities}},
|
|
author={{Hanzo AI Research Team}},
|
|
journal={{arXiv preprint}},
|
|
year={{2024}}
|
|
}}
|
|
```
|
|
|
|
## Acknowledgments
|
|
|
|
We thank the open-source community, especially the Qwen team for their foundational work. Special thanks to our research team and the broader AI community for valuable feedback and contributions.
|
|
|
|
## Contact
|
|
|
|
- **Website**: [hanzo.ai](https://hanzo.ai)
|
|
- **GitHub**: [github.com/hanzo-ai/zen](https://github.com/hanzo-ai/zen)
|
|
- **Discord**: [Join our community](https://discord.gg/hanzo-ai)
|
|
- **Email**: [email protected]
|
|
|
|
---
|
|
|
|
**Note**: This model supports both standard and thinking modes. Use `<think>` tags to activate deep reasoning capabilities for complex tasks.
|
|
"""
|
|
return card
|
|
|
|
def create_config_json(self, model_info: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Create config.json matching Qwen3 structure"""
|
|
config = {
|
|
"architectures": [model_info["architecture"]],
|
|
"model_type": "qwen2",
|
|
"_name_or_path": model_info["new_repo"],
|
|
"add_cross_attention": False,
|
|
"attention_dropout": 0.0,
|
|
"bos_token_id": 151643,
|
|
"eos_token_id": 151645,
|
|
"pad_token_id": 151643,
|
|
"hidden_act": "silu",
|
|
"hidden_size": model_info.get("hidden_size", 1024),
|
|
"initializer_range": 0.02,
|
|
"intermediate_size": model_info.get("intermediate_size", 2816),
|
|
"max_position_embeddings": model_info["context_length"],
|
|
"max_thinking_tokens": model_info["thinking_tokens"],
|
|
"num_attention_heads": model_info.get("num_attention_heads", 16),
|
|
"num_hidden_layers": model_info.get("layers", 24),
|
|
"num_key_value_heads": model_info.get("num_key_value_heads", 2),
|
|
"rms_norm_eps": 1e-6,
|
|
"rope_theta": 1000000,
|
|
"rope_scaling": {
|
|
"type": "linear",
|
|
"factor": 4.0
|
|
},
|
|
"tie_word_embeddings": False,
|
|
"torch_dtype": "bfloat16",
|
|
"transformers_version": "4.38.0",
|
|
"use_cache": True,
|
|
"vocab_size": 152064,
|
|
"use_sliding_window": False,
|
|
"sliding_window": None,
|
|
"thinking_mode": True,
|
|
"thinking_start_token": "<think>",
|
|
"thinking_end_token": "</think>"
|
|
}
|
|
|
|
# Add MoE config for zen-coder
|
|
if "num_experts" in model_info:
|
|
config.update({
|
|
"num_local_experts": model_info["num_experts"],
|
|
"num_experts_per_tok": model_info["num_experts_per_tok"],
|
|
"router_type": "top_k",
|
|
"expert_capacity": 128,
|
|
"auxiliary_loss_weight": 0.01
|
|
})
|
|
|
|
return config
|
|
|
|
def reorganize_model(self, model_key: str) -> bool:
|
|
"""Reorganize a single model"""
|
|
model_info = self.models[model_key]
|
|
old_repo = model_info["old_repo"]
|
|
new_repo = model_info["new_repo"]
|
|
|
|
print(f"\n{'='*60}")
|
|
print(f"Reorganizing {old_repo} -> {new_repo}")
|
|
print(f"{'='*60}")
|
|
|
|
try:
|
|
# Step 1: Check if old repo exists
|
|
try:
|
|
old_repo_info = self.api.repo_info(repo_id=old_repo, repo_type="model")
|
|
print(f"✓ Found old repository: {old_repo}")
|
|
except RepositoryNotFoundError:
|
|
print(f"⚠ Old repository not found: {old_repo}")
|
|
old_repo_info = None
|
|
|
|
# Step 2: Create new repository
|
|
try:
|
|
create_repo(
|
|
repo_id=new_repo,
|
|
repo_type="model",
|
|
exist_ok=True,
|
|
private=False
|
|
)
|
|
print(f"✓ Created/verified new repository: {new_repo}")
|
|
except Exception as e:
|
|
print(f"✗ Error creating repository: {e}")
|
|
return False
|
|
|
|
# Step 3: Create and upload model card
|
|
print("Creating Qwen3-style model card...")
|
|
model_card = self.create_qwen3_style_model_card(model_info)
|
|
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
|
|
f.write(model_card)
|
|
temp_card_path = f.name
|
|
|
|
try:
|
|
upload_file(
|
|
path_or_fileobj=temp_card_path,
|
|
path_in_repo="README.md",
|
|
repo_id=new_repo,
|
|
repo_type="model",
|
|
commit_message="Update model card with Qwen3 structure and thinking mode support"
|
|
)
|
|
print(f"✓ Uploaded model card to {new_repo}")
|
|
finally:
|
|
os.unlink(temp_card_path)
|
|
|
|
# Step 4: Create and upload config.json
|
|
print("Creating config.json...")
|
|
config = self.create_config_json(model_info)
|
|
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
|
json.dump(config, f, indent=2)
|
|
temp_config_path = f.name
|
|
|
|
try:
|
|
upload_file(
|
|
path_or_fileobj=temp_config_path,
|
|
path_in_repo="config.json",
|
|
repo_id=new_repo,
|
|
repo_type="model",
|
|
commit_message="Add config.json with thinking mode support"
|
|
)
|
|
print(f"✓ Uploaded config.json to {new_repo}")
|
|
finally:
|
|
os.unlink(temp_config_path)
|
|
|
|
# Step 5: If old repo exists, copy model files
|
|
if old_repo_info:
|
|
print(f"Note: Model weights should be migrated from {old_repo}")
|
|
print("This would typically involve:")
|
|
print(" 1. Downloading model files from old repo")
|
|
print(" 2. Uploading to new repo")
|
|
print(" 3. Deleting old repo after verification")
|
|
|
|
# Step 6: Create usage examples
|
|
self.create_usage_examples(new_repo, model_key)
|
|
|
|
print(f"✅ Successfully reorganized {model_key}")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error reorganizing {model_key}: {e}")
|
|
return False
|
|
|
|
def create_usage_examples(self, repo_id: str, model_key: str) -> None:
|
|
"""Create usage example scripts"""
|
|
model_info = self.models[model_key]
|
|
|
|
# Example inference script
|
|
inference_script = f'''#!/usr/bin/env python3
|
|
"""
|
|
Inference example for {repo_id}
|
|
Demonstrates both standard and thinking modes
|
|
"""
|
|
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
import torch
|
|
|
|
def run_inference(prompt, thinking_mode=False):
|
|
"""Run inference in standard or thinking mode"""
|
|
|
|
model_name = "{repo_id}"
|
|
model = AutoModelForCausalLM.from_pretrained(
|
|
model_name,
|
|
torch_dtype=torch.bfloat16,
|
|
device_map="auto"
|
|
)
|
|
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
|
|
# Add thinking tags if in thinking mode
|
|
if thinking_mode:
|
|
prompt = f"<think>\\nLet me think about this carefully\\n</think>\\n{{prompt}}"
|
|
|
|
messages = [{{"role": "user", "content": prompt}}]
|
|
text = tokenizer.apply_chat_template(
|
|
messages,
|
|
tokenize=False,
|
|
add_generation_prompt=True
|
|
)
|
|
|
|
inputs = tokenizer([text], return_tensors="pt").to(model.device)
|
|
|
|
# Generate response
|
|
generated_ids = model.generate(
|
|
inputs.input_ids,
|
|
max_new_tokens=1024 if not thinking_mode else 4096,
|
|
temperature=0.7 if not thinking_mode else 0.1,
|
|
do_sample=True,
|
|
top_p=0.9,
|
|
)
|
|
|
|
response = tokenizer.batch_decode(
|
|
generated_ids[:, inputs.input_ids.shape[1]:],
|
|
skip_special_tokens=True
|
|
)[0]
|
|
|
|
return response
|
|
|
|
# Example usage
|
|
if __name__ == "__main__":
|
|
# Standard mode example
|
|
print("Standard Mode:")
|
|
print("-" * 40)
|
|
response = run_inference("What is Python?")
|
|
print(response)
|
|
|
|
print("\\n" + "=" * 60 + "\\n")
|
|
|
|
# Thinking mode example
|
|
print("Thinking Mode:")
|
|
print("-" * 40)
|
|
response = run_inference(
|
|
"Write a Python function to find the nth Fibonacci number using dynamic programming",
|
|
thinking_mode=True
|
|
)
|
|
print(response)
|
|
'''
|
|
|
|
# Upload inference script
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
f.write(inference_script)
|
|
temp_script_path = f.name
|
|
|
|
try:
|
|
upload_file(
|
|
path_or_fileobj=temp_script_path,
|
|
path_in_repo="inference_example.py",
|
|
repo_id=repo_id,
|
|
repo_type="model",
|
|
commit_message="Add inference example for standard and thinking modes"
|
|
)
|
|
print(f"✓ Uploaded inference example to {repo_id}")
|
|
finally:
|
|
os.unlink(temp_script_path)
|
|
|
|
def reorganize_all(self) -> None:
|
|
"""Reorganize all Zen models"""
|
|
print("\n" + "="*60)
|
|
print("ZEN MODEL REORGANIZATION TO QWEN3 STRUCTURE")
|
|
print("="*60)
|
|
|
|
successful = []
|
|
failed = []
|
|
|
|
for model_key in self.models.keys():
|
|
if self.reorganize_model(model_key):
|
|
successful.append(model_key)
|
|
else:
|
|
failed.append(model_key)
|
|
|
|
# Small delay between operations
|
|
time.sleep(2)
|
|
|
|
# Print summary
|
|
print("\n" + "="*60)
|
|
print("REORGANIZATION SUMMARY")
|
|
print("="*60)
|
|
|
|
if successful:
|
|
print(f"\n✅ Successfully reorganized ({len(successful)}):")
|
|
for model in successful:
|
|
print(f" - {model}: {self.models[model]['old_repo']} → {self.models[model]['new_repo']}")
|
|
|
|
if failed:
|
|
print(f"\n❌ Failed to reorganize ({len(failed)}):")
|
|
for model in failed:
|
|
print(f" - {model}")
|
|
|
|
print("\n" + "="*60)
|
|
print("NEXT STEPS:")
|
|
print("="*60)
|
|
print("1. Migrate model weights from old repos to new repos")
|
|
print("2. Test inference with both standard and thinking modes")
|
|
print("3. Update documentation and links")
|
|
print("4. Delete old -instruct repositories after verification")
|
|
print("5. Announce the unified model structure")
|
|
|
|
def main():
|
|
"""Main execution"""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="Reorganize Zen models to match Qwen3 structure")
|
|
parser.add_argument("--token", help="HuggingFace API token (or set HF_TOKEN env var)")
|
|
parser.add_argument("--model", help="Specific model to reorganize (zen-nano, zen-eco, etc.)")
|
|
parser.add_argument("--dry-run", action="store_true", help="Show what would be done without making changes")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Get token
|
|
token = args.token or os.getenv("HF_TOKEN")
|
|
if not token:
|
|
print("Error: HuggingFace token required. Set HF_TOKEN env var or use --token")
|
|
return 1
|
|
|
|
# Initialize reorganizer
|
|
reorganizer = ZenModelReorganizer(hf_token=token)
|
|
|
|
if args.dry_run:
|
|
print("DRY RUN MODE - No changes will be made")
|
|
print("\nModels to reorganize:")
|
|
for key, info in reorganizer.models.items():
|
|
print(f" {info['old_repo']} → {info['new_repo']}")
|
|
print(f" Parameters: {info['params']}")
|
|
print(f" Context: {info['context_length']:,} tokens")
|
|
print(f" Thinking: {info['thinking_tokens']:,} tokens")
|
|
return 0
|
|
|
|
# Reorganize specific model or all
|
|
if args.model:
|
|
if args.model in reorganizer.models:
|
|
reorganizer.reorganize_model(args.model)
|
|
else:
|
|
print(f"Error: Unknown model {args.model}")
|
|
print(f"Available models: {', '.join(reorganizer.models.keys())}")
|
|
return 1
|
|
else:
|
|
reorganizer.reorganize_all()
|
|
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
exit(main()) |