Skip to main content
EMEP exposes 16 internal abstractions across ingestion, compatibility, merging, evolution, evaluation, deployment, and tracking. Each component is specified with purpose, typed interface, responsibilities, dependencies, data ownership, persistence strategy, and failure modes. This page includes a class diagram showing all components and their relationships.

Component Overview Diagram

ModelRegistry

Purpose: Canonical source of model lifecycle state. Interface:
  • register(model_meta: ModelMeta) -> ModelID
  • get(model_id: ModelID) -> ModelMeta
  • list(state: LifecycleState?) -> ModelMeta[]
  • transition(model_id: ModelID, to: LifecycleState) -> void
Responsibilities: Enforce lifecycle transitions (DISCOVERED → IMPORTED → VALIDATED → REGISTERED → CANDIDATE → EVALUATED → PROMOTED → RELEASED → DEPLOYED → DEPRECATED → ARCHIVED). Reject invalid transitions. Dependencies: ArtifactStore for model artifact retrieval. Data Owned: Model metadata, lifecycle state, provenance links. Persistence: Relational database with ACID transactions. Failure Modes: Stale state on split-brain if replication lag exceeds 5 seconds. Mitigation: single-leader writes.

ModelLoader

Purpose: Import external models into EMEP. Interface:
  • download(uri: URI) -> LocalPath
  • validate_checksum(path: LocalPath, sha256: Hash) -> bool
  • import_to_registry(meta: ModelMeta) -> ModelID
Responsibilities: Download from model hubs, verify SHA-256, extract config.json and tokenizer files, register with ModelRegistry. Dependencies: ModelRegistry, ArtifactStore. Data Owned: Temporary download paths, import logs. Persistence: Ephemeral local disk during import; artifacts moved to ArtifactStore. Failure Modes: Network timeout during download. Mitigation: resume with HTTP Range requests.

ModelCompatibilityAnalyzer

Purpose: Determine if two models can be merged. Interface:
  • analyze(model_a: ModelID, model_b: ModelID) -> CompatibilityReport
  • report() -> CompatibilityReport
Responsibilities: Compare architecture configs, tokenizer vocabularies, and tensor shapes. Emit COMPATIBLE, CONDITIONALLY_COMPATIBLE, or INCOMPATIBLE. Dependencies: TensorEngine for shape validation, ModelRegistry for metadata. Data Owned: Compatibility reports, analysis logs. Persistence: Reports stored in ExperimentTracker. Failure Modes: False COMPATIBLE on mismatched layer semantics. Mitigation: architecture hash comparison.

TensorEngine

Purpose: Load, validate, and transform model tensors. Interface:
  • load(model_id: ModelID) -> TensorDict
  • validate_shapes(a: TensorDict, b: TensorDict) -> bool
  • dispatch(strategy: MergeStrategy, params: Params) -> TensorDict
Responsibilities: Dtype normalization, device placement, shape validation, strategy dispatch. Dependencies: ModelRegistry for model paths, MergeStrategy implementations. Data Owned: In-memory tensor dictionaries. Persistence: None. Tensors are ephemeral. Failure Modes: GPU OOM on large models. Mitigation: chunked loading and CPU fallback.

MergeEngine

Purpose: Orchestrate the merge of two models into one candidate. Interface:
  • merge(model_a: ModelID, model_b: ModelID, strategy: MergeStrategy) -> Candidate
  • validate_output(candidate: Candidate) -> bool
Responsibilities: Coordinate TensorEngine, apply strategy, validate output shapes, register candidate. Dependencies: TensorEngine, MergeStrategy, ModelRegistry. Data Owned: Candidate metadata, merge parameters. Persistence: Candidate artifacts in ArtifactStore, metadata in ModelRegistry. Failure Modes: Numerical divergence. Mitigation: NaN/Inf checks post-merge.

MergeStrategy

Purpose: Abstract interface for merge algorithms. Interface:
  • apply(tensors: TensorDict, params: Params) -> TensorDict
Responsibilities: Implement SLERP (Shoemake 1985), Task Arithmetic (Ilharco et al. 2022), TIES-Merging (Yadav et al. 2023), DARE (Yu et al. 2023), or Franken-Merge. Dependencies: TensorEngine for tensor access. Data Owned: Strategy-specific parameters. Persistence: Parameters logged in ExperimentTracker. Failure Modes: Invalid parameter range. Mitigation: param validation in constructor.

CandidateGenerator

Purpose: Generate merge candidates from parent models and strategy space. Interface:
  • generate(parents: ModelID[], strategy_space: StrategySpace) -> Candidate[]
  • score_feasibility(candidate: Candidate) -> float
Responsibilities: Enumerate or sample parent pairs and strategy configurations. Filter infeasible candidates before evaluation. Dependencies: MergeEngine, ModelCompatibilityAnalyzer. Data Owned: Candidate generation logs, feasibility scores. Persistence: Generation logs in ExperimentTracker. Failure Modes: Combinatorial explosion. Mitigation: beam search and compatibility pre-filter.

EvolutionEngine

Purpose: Drive evolutionary optimization over merge configurations. Interface:
  • init_population(size: int) -> Population
  • step() -> Population
  • best() -> Genome
Responsibilities: Genome encoding, mutation, crossover, selection, population replacement. Supports NSGA-II (Deb et al. 2002), NSGA-III (Deb & Jain 2014), and CMA-ES (Hansen 2001). Dependencies: CandidateGenerator, FitnessEngine, ExperimentTracker. Data Owned: Population state, generation counter, random state. Persistence: Population checkpoints in ArtifactStore. Failure Modes: Premature convergence. Mitigation: diversity maintenance and adaptive mutation rates.

EvaluationEngine

Purpose: Classify candidate quality. Interface:
  • evaluate(candidate: Candidate) -> EvaluationReport
  • classify(report: EvaluationReport) -> CandidateStatus
Responsibilities: Run benchmarks, compare to baseline, assign PASS, FAIL, REGRESSION, INVALID, or INCOMPLETE. Dependencies: BenchmarkEngine, ModelRegistry. Data Owned: Evaluation reports, classification history. Persistence: Reports in ExperimentTracker. Failure Modes: Flaky benchmark. Mitigation: retry with exponential backoff.

BenchmarkEngine

Purpose: Execute benchmarks on candidates. Interface:
  • run_split(candidate: Candidate, split: Split) -> BenchmarkResult
  • aggregate(results: BenchmarkResult[]) -> AggregatedResult
Responsibilities: Load datasets, run inference, compute metrics. Splits: Optimization Set, Validation Set, Hidden Test Set. Dependencies: DatasetRegistry, InferenceBackend. Data Owned: Raw benchmark outputs, aggregated metrics. Persistence: Results in metrics store, logs in ExperimentTracker. Failure Modes: Dataset corruption. Mitigation: checksum verification on load.

FitnessEngine

Purpose: Compute fitness vectors for genomes. Interface:
  • compute(genome: Genome) -> FitnessVector
  • rank(population: Population) -> RankedPopulation
Responsibilities: Aggregate benchmark results into scalar or vector fitness. Support multi-objective ranking. Dependencies: EvaluationEngine, BenchmarkEngine. Data Owned: Fitness vectors, ranking metadata. Persistence: Fitness logs in ExperimentTracker. Failure Modes: Fitness noise. Mitigation: median over multiple runs.

ExperimentTracker

Purpose: Record all experiment events and artifacts. Interface:
  • create(exp_config: Config) -> ExperimentID
  • log_event(event: Event) -> void
  • checkpoint() -> void
Responsibilities: State machine for experiments (CREATED, PREPARING, RUNNING, EVALUATING, COMPLETED, FAILED, CANCELLED, ARCHIVED). Provenance logging. Dependencies: ArtifactStore, ModelRegistry, DatasetRegistry. Data Owned: Experiment metadata, event logs, checkpoints. Persistence: Relational DB for metadata, object store for large artifacts. Failure Modes: Event loss on crash. Mitigation: WAL and async batch writes.

ArtifactStore

Purpose: Store and retrieve model artifacts, checkpoints, and experiment outputs. Interface:
  • store(artifact: Bytes, meta: ArtifactMeta) -> ArtifactID
  • retrieve(artifact_id: ArtifactID) -> Bytes
  • verify_signature(artifact_id: ArtifactID) -> bool
Responsibilities: Content-addressed storage, signature verification, tiered retention. Dependencies: None. Foundation component. Data Owned: Artifact blobs, signatures, retention policies. Persistence: Hot NVMe, warm object, cold archive. Failure Modes: Silent corruption. Mitigation: SHA-256 on read.

DatasetRegistry

Purpose: Manage dataset metadata and splits. Interface:
  • register_dataset(meta: DatasetMeta) -> DatasetID
  • get_split(dataset_id: DatasetID, split_name: string) -> Split
Responsibilities: Track Optimization Set, Validation Set, and Hidden Test Set. Enforce split isolation. Dependencies: ArtifactStore for dataset files. Data Owned: Dataset metadata, split assignments. Persistence: Relational database. Failure Modes: Split leakage. Mitigation: immutable split assignments with hash verification.

QuantizationEngine

Purpose: Reduce model precision for deployment. Interface:
  • quantize(model_id: ModelID, config: QuantConfig) -> QuantizedModel
  • validate(quantized: QuantizedModel) -> bool
Responsibilities: INT8, INT4, and GGUF quantization. Accuracy validation post-quantization. Dependencies: TensorEngine, InferenceBackend. Data Owned: Quantization configs, validation results. Persistence: Quantized artifacts in ArtifactStore. Failure Modes: Accuracy degradation beyond threshold. Mitigation: rollback to full precision.

InferenceBackend

Purpose: Load and run inference on models. Interface:
  • load(model_id: ModelID) -> Handle
  • infer(batch: Batch) -> Output
  • unload(handle: Handle) -> void
Responsibilities: vLLM, llama.cpp, and HuggingFace Transformers backends. Batch scheduling, KV cache management. Dependencies: TensorEngine, GPU Orchestration. Data Owned: Runtime handles, batch queues. Persistence: None. Runtime state only. Failure Modes: Backend crash. Mitigation: process isolation and automatic restart.

DeploymentManager

Purpose: Deploy models to inference endpoints. Interface:
  • deploy(model_id: ModelID, target: Target) -> Endpoint
  • rollback(model_id: ModelID) -> void
Responsibilities: Package artifacts, configure inference backend, manage canary and rollback. Dependencies: QuantizationEngine, InferenceBackend, ArtifactStore. Data Owned: Deployment configs, endpoint metadata. Persistence: Deployment state in relational DB. Failure Modes: Deployment timeout. Mitigation: health-check gated promotion.