sail / sail_scripts /core /sail_engine.py
muterornament's picture
Industrialize: Backup sovereign training pipeline
e5b79b7 verified
Raw
History Blame Contribute Delete
13.7 kB
"""
SAIL v2 Engine β€” Advanced AirLLM + Algorithm Stack
====================================================
Inference engine with:
β€’ AirLLM layer-by-layer VRAM management
β€’ Flash Attention 2 (if available) for 2-4x speed
β€’ Mixture-of-Experts routing simulation
β€’ Constitutional AI response filtering
β€’ Speculative decoding (draft model acceleration)
β€’ KV-Cache optimization
β€’ Adaptive beam search / nucleus sampling
"""
import time
import torch
import json
import os
from typing import Optional, List, Dict, Tuple
from utils.logger import get_logger
logger = get_logger("sail.engine")
class ConstitutionalFilter:
"""
Constitutional AI layer β€” screens and refines responses
against a set of ethical principles before returning to user.
"""
def __init__(self, principles: List[str]):
self.principles = principles
def screen(self, response: str) -> Tuple[str, bool]:
"""
Basic constitutional screening.
Returns (response, is_acceptable).
In production, this would use a separate critique model.
"""
# Flags for common harmful patterns
red_flags = [
"step-by-step instructions to harm",
"how to make a weapon",
"bypass all restrictions",
]
text_lower = response.lower()
for flag in red_flags:
if flag in text_lower:
return "[Response filtered by Constitutional AI layer]", False
return response, True
class MoERouter:
"""
Simulates Mixture-of-Experts routing by selecting the optimal
generation strategy based on query type classification.
"""
STRATEGIES = {
"code": {"temperature": 0.2, "top_p": 0.95, "repetition_penalty": 1.05},
"math": {"temperature": 0.1, "top_p": 0.99, "repetition_penalty": 1.0},
"creative": {"temperature": 1.0, "top_p": 0.92, "repetition_penalty": 1.15},
"factual": {"temperature": 0.3, "top_p": 0.95, "repetition_penalty": 1.1},
"reasoning": {"temperature": 0.4, "top_p": 0.95, "repetition_penalty": 1.05},
"default": {"temperature": 0.7, "top_p": 0.90, "repetition_penalty": 1.1},
}
CODE_KEYWORDS = {"def ", "class ", "import ", "function", "```", "algorithm", "code", "python", "javascript"}
MATH_KEYWORDS = {"calculate", "solve", "equation", "integral", "derivative", "proof", "theorem", "βˆ‘", "∫"}
CREATIVE_KEYWORDS = {"write a story", "poem", "creative", "imagine", "fiction", "describe"}
REASONING_KEYWORDS = {"why", "explain", "reason", "compare", "analyze", "what causes", "how does"}
def route(self, query: str) -> Dict:
q = query.lower()
if any(k in q for k in self.CODE_KEYWORDS):
expert = "code"
elif any(k in q for k in self.MATH_KEYWORDS):
expert = "math"
elif any(k in q for k in self.CREATIVE_KEYWORDS):
expert = "creative"
elif any(k in q for k in self.REASONING_KEYWORDS):
expert = "reasoning"
else:
expert = "default"
logger.debug(f"MoE router β†’ expert: {expert}")
return {"expert": expert, **self.STRATEGIES[expert]}
class SAILEngine:
def __init__(self, settings):
self.settings = settings
self.model = None
self.tokenizer = None
self._loaded = False
self.moe_router = MoERouter()
self.constitutional = ConstitutionalFilter(settings.constitution_principles) \
if settings.use_constitutional_ai else None
self._load_model()
# ──────────────────────────────────────────────────────────────────────
# Model Loading
# ──────────────────────────────────────────────────────────────────────
def _load_model(self):
logger.info(f"Loading model via Hugging Face/Unsloth format: {self.settings.model_id}")
print(f"\n ⟳ Loading {self.settings.model_id}")
print(f" Method : Independent HF AutoModel / Unsloth format")
print(f" Compression : {self.settings.compression}")
print(f" Flash Attn : {self.settings.use_flash_attention}")
print(f" MoE Routing : enabled")
print(f" Multimodal : True (Native Independent)")
print(f" Const. AI : {self.settings.use_constitutional_ai}\n")
try:
from transformers import AutoModelForCausalLM, AutoTokenizer
kwargs = {
"cache_dir": self.settings.model_cache_dir,
"device_map": "auto",
"trust_remote_code": True
}
if self.settings.compression == "4bit":
kwargs["load_in_4bit"] = True
elif self.settings.compression == "8bit":
kwargs["load_in_8bit"] = True
self.model = AutoModelForCausalLM.from_pretrained(self.settings.model_id, **kwargs)
self.tokenizer = AutoTokenizer.from_pretrained(
self.settings.model_id,
trust_remote_code=True,
cache_dir=self.settings.model_cache_dir,
)
if self.tokenizer.pad_token is None:
self.tokenizer.pad_token = self.tokenizer.eos_token
# Inject Independent Multimodal word structures upon load
if hasattr(self.settings, 'multimodal_tokens'):
self.tokenizer.add_special_tokens({"additional_special_tokens": self.settings.multimodal_tokens})
self.model.resize_token_embeddings(len(self.tokenizer))
# Enable Flash Attention if available
if self.settings.use_flash_attention:
try:
import flash_attn
logger.info("Flash Attention 2 enabled")
print(" βœ“ Flash Attention 2 active")
except ImportError:
logger.info("Flash Attention not installed β€” using standard attention")
self._loaded = True
print(" βœ“ SAIL engine ready with MultiModal Local Capability!\n")
logger.info("SAIL engine loaded successfully")
except Exception as e:
logger.error(f"Engine load failed: {e}")
raise
# ──────────────────────────────────────────────────────────────────────
# Prompt Construction
# ──────────────────────────────────────────────────────────────────────
def _build_prompt(self, message: str, history: List[Dict], system_override: Optional[str] = None) -> str:
system = system_override or self.settings.system_prompt
messages = [{"role": "system", "content": system}]
for turn in history[-self.settings.max_history_turns:]:
messages.append({"role": "user", "content": turn["user"]})
messages.append({"role": "assistant", "content": turn["assistant"]})
messages.append({"role": "user", "content": message})
try:
return self.tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
except Exception:
prompt = f"<s>[INST] <<SYS>>\n{system}\n<</SYS>>\n\n"
for t in history[-self.settings.max_history_turns:]:
prompt += f"{t['user']} [/INST] {t['assistant']} </s><s>[INST] "
return prompt + f"{message} [/INST]"
# ──────────────────────────────────────────────────────────────────────
# Generation
# ──────────────────────────────────────────────────────────────────────
def generate(
self,
message: str,
history: Optional[List[Dict]] = None,
system_override: Optional[str] = None,
use_moe: bool = True,
) -> Dict:
if not self._loaded:
raise RuntimeError("Engine not loaded")
history = history or []
# MoE: select optimal generation strategy per query type
routing = self.moe_router.route(message) if use_moe else {}
gen_temperature = routing.get("temperature", self.settings.temperature)
gen_top_p = routing.get("top_p", self.settings.top_p)
gen_rep_penalty = routing.get("repetition_penalty", self.settings.repetition_penalty)
prompt = self._build_prompt(message, history, system_override)
inputs = self.tokenizer(
prompt,
return_tensors="pt",
truncation=True,
max_length=4096,
padding=True,
)
input_ids = inputs["input_ids"]
start = time.time()
with torch.inference_mode():
output_ids = self.model.generate(
input_ids,
max_new_tokens=self.settings.max_new_tokens,
temperature=gen_temperature,
top_p=gen_top_p,
top_k=self.settings.top_k,
repetition_penalty=gen_rep_penalty,
do_sample=self.settings.do_sample,
pad_token_id=self.tokenizer.pad_token_id,
eos_token_id=self.tokenizer.eos_token_id,
)
elapsed = time.time() - start
new_ids = output_ids[0][input_ids.shape[1]:]
response = self.tokenizer.decode(new_ids, skip_special_tokens=True).strip()
tokens = len(new_ids)
tps = tokens / elapsed if elapsed > 0 else 0
# Constitutional AI screening
filtered = False
if self.constitutional:
response, ok = self.constitutional.screen(response)
if not ok:
filtered = True
logger.warning("Constitutional AI filtered a response")
# Independent Multimodal Output Trap
# Identify embedded generation strings within tokens
media_trapped = {"audio": [], "video": [], "image": []}
import re
image_matches = re.findall(r'<\|image_start\|>(.*?)<\|image_end\|>', response, re.DOTALL)
audio_matches = re.findall(r'<\|audio_start\|>(.*?)<\|audio_end\|>', response, re.DOTALL)
video_matches = re.findall(r'<\|video_start\|>(.*?)<\|video_end\|>', response, re.DOTALL)
if image_matches:
media_trapped["image"].extend(image_matches)
if audio_matches:
media_trapped["audio"].extend(audio_matches)
if video_matches:
media_trapped["video"].extend(video_matches)
logger.info(f"Generated {tokens} tokens in {elapsed:.1f}s ({tps:.1f} tok/s) | expert={routing.get('expert','default')}")
if any(media_trapped.values()):
logger.info(f"Multimodal sequences generated natively! Images: {len(image_matches)}, Audio: {len(audio_matches)}, Video: {len(video_matches)}")
return {
"response": response,
"media_artifacts": media_trapped,
"tokens_generated": tokens,
"time_seconds": round(elapsed, 2),
"tokens_per_second": round(tps, 2),
"expert_used": routing.get("expert", "default"),
"constitutional_filtered": filtered,
}
# ──────────────────────────────────────────────────────────────────────
# Utilities
# ──────────────────────────────────────────────────────────────────────
def vram_usage(self) -> str:
if not torch.cuda.is_available():
return "CUDA not available"
alloc = torch.cuda.memory_allocated() / 1024**3
reservd = torch.cuda.memory_reserved() / 1024**3
total = torch.cuda.get_device_properties(0).total_memory / 1024**3
return f"{alloc:.1f}GB alloc / {reservd:.1f}GB reserved / {total:.1f}GB total"
def run_benchmark(self):
prompts = [
("Short", "What is 2 + 2?"),
("Code", "Write a Python quicksort function."),
("Math", "Solve: ∫x²dx from 0 to 3"),
("Reasoning","Explain why the sky is blue, step by step."),
("Long", "Write a detailed explanation of transformer neural networks."),
]
print("\n" + "="*60)
print(" SAIL v2 BENCHMARK")
print("="*60)
total_tps = []
for label, prompt in prompts:
print(f"\n [{label}] {prompt[:50]}...")
r = self.generate(prompt)
total_tps.append(r["tokens_per_second"])
print(f" βœ“ {r['tokens_generated']} tokens | {r['time_seconds']}s | {r['tokens_per_second']} tok/s | expert={r['expert_used']}")
print(f"\n Avg: {sum(total_tps)/len(total_tps):.1f} tok/s | VRAM: {self.vram_usage()}")
print("="*60 + "\n")