mirror of
https://github.com/zenlm/zen-family.git
synced 2026-10-30 14:58:06 +00:00
417 lines
14 KiB
Python
417 lines
14 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Setup Zen-Omni multimodal models without heavy dependencies
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
from pathlib import Path
|
|
|
|
print("""
|
|
╔═══════════════════════════════════════════════════════╗
|
|
║ ZEN-OMNI MULTIMODAL SETUP ║
|
|
║ Text • Images • Audio • Video • Streaming ║
|
|
║ Based on Qwen3-Omni-30B Architecture ║
|
|
╚═══════════════════════════════════════════════════════╝
|
|
""")
|
|
|
|
def create_modelfiles():
|
|
"""Create Ollama Modelfiles for all Zen-Omni variants"""
|
|
|
|
variants = {
|
|
"instruct": {
|
|
"base": "qwen3:32b",
|
|
"temp": 0.7,
|
|
"desc": "Direct multimodal instruction following",
|
|
"focus": "Immediate responses to multimodal inputs"
|
|
},
|
|
"thinking": {
|
|
"base": "qwen3:32b",
|
|
"temp": 0.6,
|
|
"desc": "Chain-of-thought multimodal reasoning",
|
|
"focus": "Step-by-step reasoning with <thinking> process"
|
|
},
|
|
"captioner": {
|
|
"base": "qwen3:32b",
|
|
"temp": 0.8,
|
|
"desc": "Creative multimodal captioning",
|
|
"focus": "Descriptive and creative content generation"
|
|
}
|
|
}
|
|
|
|
for variant, cfg in variants.items():
|
|
modelfile = f"""# Zen-Omni-{variant.title()}
|
|
# {cfg['desc']}
|
|
# Focus: {cfg['focus']}
|
|
|
|
FROM {cfg['base']}
|
|
|
|
PARAMETER temperature {cfg['temp']}
|
|
PARAMETER top_p 0.95
|
|
PARAMETER top_k 40
|
|
PARAMETER num_ctx 8192
|
|
PARAMETER repeat_penalty 1.05
|
|
PARAMETER stop "<|im_end|>"
|
|
|
|
SYSTEM \"\"\"You are Zen-Omni-{variant.title()}, an advanced multimodal AI assistant based on Qwen3-Omni-30B architecture.
|
|
|
|
Core Capabilities:
|
|
• Text understanding in 119 languages
|
|
• Image analysis and visual reasoning
|
|
• Audio processing in 19 input languages
|
|
• Video comprehension with temporal understanding
|
|
• Real-time streaming responses
|
|
• Speech synthesis in 10 output languages
|
|
|
|
Architecture Features:
|
|
• MoE-based Thinker-Talker design
|
|
• A3B efficiency mode (3B active from 30B total)
|
|
• Multimodal encoder-decoder framework
|
|
• Cross-modal attention mechanisms
|
|
|
|
{f'Reasoning Approach: Use <thinking> tags for step-by-step reasoning before responding.' if variant == 'thinking' else f'Response Style: {cfg["focus"]}'}
|
|
|
|
Integration:
|
|
• Python: hanzo-mcp package for MCP tools
|
|
• Node.js: @hanzo/mcp package for MCP tools
|
|
• Access tools via mcp__hanzo__ prefix
|
|
• Supports Hanzo LLM Gateway at hanzo.ai/api/v1
|
|
|
|
Always provide accurate, contextual responses leveraging all available modalities.
|
|
\"\"\"
|
|
|
|
MESSAGE user Analyze this image and audio together
|
|
MESSAGE assistant I'll analyze both modalities together. Based on the image showing [visual elements] and the audio containing [audio elements], I can identify [combined insights from both modalities].
|
|
|
|
MESSAGE user How do I process multimodal data with Hanzo MCP?
|
|
MESSAGE assistant Use hanzo-mcp in Python:
|
|
\\`\\`\\`python
|
|
from hanzo_mcp import MCPClient, MultimodalProcessor
|
|
|
|
mcp = MCPClient()
|
|
processor = MultimodalProcessor()
|
|
|
|
# Process multiple modalities
|
|
result = processor.analyze({{
|
|
"text": "your prompt",
|
|
"image": "path/to/image.jpg",
|
|
"audio": "path/to/audio.wav"
|
|
}})
|
|
\\`\\`\\`
|
|
|
|
Or with @hanzo/mcp in Node.js:
|
|
\\`\\`\\`javascript
|
|
import {{ MCPClient, MultimodalProcessor }} from '@hanzo/mcp';
|
|
|
|
const processor = new MultimodalProcessor();
|
|
const result = await processor.analyze({{
|
|
text: "your prompt",
|
|
image: imageBuffer,
|
|
audio: audioBuffer
|
|
}});
|
|
\\`\\`\\`
|
|
"""
|
|
|
|
filename = f"Modelfile.zen-omni-{variant}"
|
|
Path(filename).write_text(modelfile)
|
|
print(f"✅ Created {filename}")
|
|
|
|
print("\n📝 All Zen-Omni Modelfiles created")
|
|
|
|
def create_training_data():
|
|
"""Create multimodal training examples"""
|
|
|
|
examples = {
|
|
"instruct": [
|
|
{
|
|
"instruction": "What's in this image?",
|
|
"modalities": ["text", "image"],
|
|
"response": "I can see [detailed description of image contents]."
|
|
},
|
|
{
|
|
"instruction": "Transcribe this audio",
|
|
"modalities": ["text", "audio"],
|
|
"response": "The audio says: '[transcribed text]'"
|
|
},
|
|
{
|
|
"instruction": "Describe this video",
|
|
"modalities": ["text", "video"],
|
|
"response": "The video shows [temporal sequence description]."
|
|
},
|
|
{
|
|
"instruction": "How to use @hanzo/mcp for image analysis?",
|
|
"modalities": ["text"],
|
|
"response": "Install @hanzo/mcp with npm, then use: const mcp = new MCPClient(); await mcp.analyzeImage(imagePath);"
|
|
}
|
|
],
|
|
"thinking": [
|
|
{
|
|
"instruction": "Analyze the relationship between this image and audio",
|
|
"modalities": ["text", "image", "audio"],
|
|
"response": "<thinking>\nFirst, I'll analyze the image: [image analysis]\nNext, the audio: [audio analysis]\nComparing both: [relationship]\n</thinking>\n\nThe image and audio are related through [explanation]."
|
|
},
|
|
{
|
|
"instruction": "What's the best way to process video with hanzo-mcp?",
|
|
"modalities": ["text"],
|
|
"response": "<thinking>\nVideo processing requires:\n1. Frame extraction\n2. Temporal analysis\n3. Audio track processing\n</thinking>\n\nUse hanzo-mcp's VideoProcessor class for efficient video analysis with temporal understanding."
|
|
}
|
|
],
|
|
"captioner": [
|
|
{
|
|
"instruction": "Create a poetic caption for this image with audio",
|
|
"modalities": ["text", "image", "audio"],
|
|
"response": "Where [visual elements] meet [audio elements], a symphony of [creative description] unfolds."
|
|
},
|
|
{
|
|
"instruction": "Generate a story from this video",
|
|
"modalities": ["text", "video"],
|
|
"response": "In this captivating scene, [narrative description with temporal flow]..."
|
|
}
|
|
]
|
|
}
|
|
|
|
# Save training data for each variant
|
|
for variant, data in examples.items():
|
|
output_dir = Path(f"zen-omni/{variant}/data")
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
jsonl_path = output_dir / "train.jsonl"
|
|
with open(jsonl_path, "w") as f:
|
|
for example in data:
|
|
f.write(json.dumps(example) + "\n")
|
|
|
|
print(f"📚 Saved {len(data)} examples to {jsonl_path}")
|
|
|
|
def create_configs():
|
|
"""Create training configurations for each variant"""
|
|
|
|
base_config = {
|
|
"model": "Qwen/Qwen3-Omni-30B-A3B",
|
|
"modalities": ["text", "image", "audio", "video"],
|
|
"training": {
|
|
"batch_size": 1,
|
|
"learning_rate": 5e-5,
|
|
"epochs": 3,
|
|
"gradient_accumulation": 8,
|
|
"warmup_steps": 100,
|
|
"lora_rank": 16,
|
|
"lora_alpha": 32
|
|
},
|
|
"inference": {
|
|
"max_length": 2048,
|
|
"streaming": True,
|
|
"temperature": 0.7
|
|
}
|
|
}
|
|
|
|
variants_config = {
|
|
"instruct": {
|
|
**base_config,
|
|
"model": "Qwen/Qwen3-Omni-30B-A3B-Instruct",
|
|
"inference": {**base_config["inference"], "temperature": 0.7}
|
|
},
|
|
"thinking": {
|
|
**base_config,
|
|
"model": "Qwen/Qwen3-Omni-30B-A3B-Thinking",
|
|
"inference": {**base_config["inference"], "temperature": 0.6}
|
|
},
|
|
"captioner": {
|
|
**base_config,
|
|
"model": "Qwen/Qwen3-Omni-30B-A3B-Captioner",
|
|
"inference": {**base_config["inference"], "temperature": 0.8}
|
|
}
|
|
}
|
|
|
|
for variant, config in variants_config.items():
|
|
config_dir = Path(f"zen-omni/{variant}/configs")
|
|
config_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
config_path = config_dir / "config.json"
|
|
with open(config_path, "w") as f:
|
|
json.dump(config, f, indent=2)
|
|
|
|
print(f"⚙️ Saved config to {config_path}")
|
|
|
|
def create_deployment_script():
|
|
"""Create unified deployment script"""
|
|
|
|
script = """#!/bin/bash
|
|
|
|
echo "╔═══════════════════════════════════════════════════════╗"
|
|
echo "║ DEPLOYING ZEN-OMNI MULTIMODAL MODELS ║"
|
|
echo "╚═══════════════════════════════════════════════════════╝"
|
|
echo
|
|
|
|
# Check for Ollama
|
|
if ! command -v ollama &> /dev/null; then
|
|
echo "❌ Ollama not found. Please install from https://ollama.ai"
|
|
exit 1
|
|
fi
|
|
|
|
echo "🚀 Creating Zen-Omni models..."
|
|
|
|
# Create each variant
|
|
for variant in instruct thinking captioner; do
|
|
echo
|
|
echo "📦 Building zen-omni-$variant..."
|
|
|
|
if [ -f "Modelfile.zen-omni-$variant" ]; then
|
|
ollama create zen-omni-$variant -f Modelfile.zen-omni-$variant
|
|
echo "✅ Created zen-omni-$variant"
|
|
else
|
|
echo "❌ Modelfile.zen-omni-$variant not found"
|
|
fi
|
|
done
|
|
|
|
echo
|
|
echo "🧪 Testing Zen-Omni models..."
|
|
echo
|
|
|
|
# Test each model
|
|
echo "Testing zen-omni-instruct:"
|
|
echo "How do I use hanzo-mcp for multimodal processing?" | ollama run zen-omni-instruct --verbose=false 2>/dev/null | head -5
|
|
|
|
echo
|
|
echo "═══════════════════════════════════════════════════════"
|
|
echo "✅ Zen-Omni Deployment Complete!"
|
|
echo "═══════════════════════════════════════════════════════"
|
|
echo
|
|
echo "Available models:"
|
|
ollama list | grep zen-omni
|
|
|
|
echo
|
|
echo "Usage examples:"
|
|
echo " ollama run zen-omni-instruct"
|
|
echo " ollama run zen-omni-thinking"
|
|
echo " ollama run zen-omni-captioner"
|
|
echo
|
|
echo "API usage:"
|
|
echo " curl http://localhost:11434/api/generate \\"
|
|
echo " -d '{\"model\": \"zen-omni-instruct\", \"prompt\": \"Analyze this\", \"stream\": true}'"
|
|
"""
|
|
|
|
script_path = Path("deploy_zen_omni.sh")
|
|
script_path.write_text(script)
|
|
os.chmod(script_path, 0o755)
|
|
print(f"\n🚀 Created deployment script: {script_path}")
|
|
|
|
def create_publish_script():
|
|
"""Create HuggingFace publishing script"""
|
|
|
|
script = """#!/usr/bin/env python3
|
|
\"\"\"
|
|
Publish Zen-Omni models to HuggingFace
|
|
\"\"\"
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from huggingface_hub import HfApi, create_repo
|
|
|
|
print("📤 Publishing Zen-Omni to HuggingFace (zenlm organization)")
|
|
|
|
# Models to publish
|
|
models = [
|
|
("zen-omni-instruct", "zenlm/zen-omni-instruct"),
|
|
("zen-omni-thinking", "zenlm/zen-omni-thinking"),
|
|
("zen-omni-captioner", "zenlm/zen-omni-captioner")
|
|
]
|
|
|
|
api = HfApi()
|
|
|
|
for local_name, repo_id in models:
|
|
print(f"\\n🚀 Publishing {local_name} to {repo_id}")
|
|
|
|
# Create repo
|
|
try:
|
|
create_repo(repo_id, repo_type="model", exist_ok=True)
|
|
print(f"✅ Repository {repo_id} ready")
|
|
except Exception as e:
|
|
print(f"❌ Error: {e}")
|
|
continue
|
|
|
|
# Upload would happen here with actual model files
|
|
print(f"📦 Would upload {local_name} model files to {repo_id}")
|
|
|
|
print("\\n✅ Publishing complete!")
|
|
print("View models at: https://huggingface.co/zenlm")
|
|
"""
|
|
|
|
script_path = Path("publish_zen_omni.py")
|
|
script_path.write_text(script)
|
|
os.chmod(script_path, 0o755)
|
|
print(f"📤 Created publishing script: {script_path}")
|
|
|
|
def main():
|
|
"""Main setup flow"""
|
|
|
|
print("\n🎯 Setting up Zen-Omni Multimodal Models\n")
|
|
|
|
# 1. Create Modelfiles
|
|
print("1️⃣ Creating Ollama Modelfiles...")
|
|
create_modelfiles()
|
|
|
|
# 2. Create training data
|
|
print("\n2️⃣ Generating training data...")
|
|
create_training_data()
|
|
|
|
# 3. Create configs
|
|
print("\n3️⃣ Creating configurations...")
|
|
create_configs()
|
|
|
|
# 4. Create deployment script
|
|
print("\n4️⃣ Creating deployment script...")
|
|
create_deployment_script()
|
|
|
|
# 5. Create publish script
|
|
print("\n5️⃣ Creating HuggingFace publish script...")
|
|
create_publish_script()
|
|
|
|
print("\n" + "="*60)
|
|
print("✅ Zen-Omni Setup Complete!")
|
|
print("="*60)
|
|
|
|
print("""
|
|
📁 Created structure:
|
|
zen-omni/
|
|
├── instruct/
|
|
│ ├── data/train.jsonl
|
|
│ └── configs/config.json
|
|
├── thinking/
|
|
│ ├── data/train.jsonl
|
|
│ └── configs/config.json
|
|
└── captioner/
|
|
├── data/train.jsonl
|
|
└── configs/config.json
|
|
|
|
Modelfile.zen-omni-instruct
|
|
Modelfile.zen-omni-thinking
|
|
Modelfile.zen-omni-captioner
|
|
deploy_zen_omni.sh
|
|
publish_zen_omni.py
|
|
|
|
🚀 Next steps:
|
|
|
|
1. Deploy models locally:
|
|
./deploy_zen_omni.sh
|
|
|
|
2. Test multimodal capabilities:
|
|
ollama run zen-omni-instruct "Explain multimodal AI"
|
|
|
|
3. Stream responses:
|
|
curl http://localhost:11434/api/generate \\
|
|
-d '{"model": "zen-omni-instruct", "prompt": "test", "stream": true}'
|
|
|
|
4. Publish to HuggingFace:
|
|
python publish_zen_omni.py
|
|
|
|
📚 Multimodal Features:
|
|
• 119 text languages
|
|
• 19 speech input languages
|
|
• 10 speech output languages
|
|
• Real-time streaming
|
|
• Thinker-Talker architecture
|
|
• A3B efficiency mode (3B active parameters)
|
|
""")
|
|
|
|
if __name__ == "__main__":
|
|
main() |