import XCTest @testable import MarkBase final class MultimodalSequentialTest: XCTestCase { func testE2BFullMultimodal() throws { print("\n═══════════════════════════════════════════════════════════════════") print(" E2B Full Multimodal Test (TEXT + Audio + Vision)") print("═══════════════════════════════════════════════════════════════════\n") let modelDir = "/Users/accusys/.cache/huggingface/hub/models--mlx-community--gemma-4-e2b-it-4bit/snapshots/2c3e507453b4f218d05fe3cc97bea5c5a654257e" print("Step 1: Load MultimodalModel (TEXT + Audio + Vision)...") let engine = try MarkBaseEngine(autoCompile: true) let loadStart = Date() let mmModel = try MultimodalModel(modelDir: modelDir, engine: engine, maxContextLength: 256) let loadTime = Date().timeIntervalSince(loadStart) * 1000 print(" ✓ Model loaded in \(loadTime) ms") print(" TEXT: hidden=\(mmModel.textModel.hiddenSize), layers=\(mmModel.textModel.numHiddenLayers)") print(" Audio: \(mmModel.audioTowerE2B != nil ? "E2B (12 layers)" : "N/A")") print(" Vision: \(mmModel.visionTowerE2B != nil ? "E2B (16 layers)" : "N/A")") // ── Audio Test ─────────────────────────────────────────────────── print("\nStep 2: Process Audio...") let seqLen = 100 let nMels = 128 var melFeatures: [[Float]] = [] for _ in 0.. maxLogit { maxLogit = logits[i] maxIdx = i } } tokens.append(maxIdx) } let genTime = Date().timeIntervalSince(genStart) * 1000 print(" ✓ Generated 10 tokens in \(genTime) ms") print(" Tokens: \(tokens.suffix(10))") print("\n═══════════════════════════════════════════════════════════════════") print("✓ E2B Full Multimodal test passed") print(" Load: \(loadTime) ms, Audio: \(audioTime) ms, Vision: \(visionTime) ms, Gen: \(genTime) ms") print("═══════════════════════════════════════════════════════════════════\n") XCTAssertFalse(audioEmbeds.contains { $0.isNaN }, "Audio should not have NaN") } func testE4BFullMultimodal() throws { print("\n═══════════════════════════════════════════════════════════════════") print(" E4B Full Multimodal Test (TEXT + Audio + Vision)") print("═══════════════════════════════════════════════════════════════════\n") let modelDir = "/Users/accusys/MarkBaseEngine/models/E4B-MarkBase" print("Step 1: Load MultimodalModel (TEXT + Audio + Vision)...") let engine = try MarkBaseEngine(autoCompile: true) let loadStart = Date() let mmModel = try MultimodalModel(modelDir: modelDir, engine: engine, maxContextLength: 256) let loadTime = Date().timeIntervalSince(loadStart) * 1000 print(" ✓ Model loaded in \(loadTime) ms") print(" TEXT: hidden=\(mmModel.textModel.hiddenSize), layers=\(mmModel.textModel.numHiddenLayers)") print(" Audio: \(mmModel.audioTowerFull != nil ? "Full (12 layers)" : "N/A")") print(" Vision: \(mmModel.visionTowerFull != nil ? "Full (16 layers)" : "N/A")") // ── Audio Test ─────────────────────────────────────────────────── print("\nStep 2: Process Audio...") let seqLen = 100 let nMels = 128 var melFeatures: [[Float]] = [] for _ in 0.. maxLogit { maxLogit = logits[i] maxIdx = i } } tokens.append(maxIdx) } let genTime = Date().timeIntervalSince(genStart) * 1000 print(" ✓ Generated 10 tokens in \(genTime) ms") print(" Tokens: \(tokens.suffix(10))") print("\n═══════════════════════════════════════════════════════════════════") print("✓ E4B Full Multimodal test passed") print(" Load: \(loadTime) ms, Audio: \(audioTime) ms, Vision: \(visionTime) ms, Gen: \(genTime) ms") print("═══════════════════════════════════════════════════════════════════\n") XCTAssertFalse(audioEmbeds.contains { $0.isNaN }, "Audio should not have NaN") XCTAssertFalse(visionEmbeds.contains { $0.isNaN }, "Vision should not have NaN") } func test12BFullMultimodal() throws { print("\n═══════════════════════════════════════════════════════════════════") print(" 12B Full Multimodal Test (TEXT + Audio + Vision)") print("═══════════════════════════════════════════════════════════════════\n") let modelDir = "/Users/accusys/.cache/huggingface/hub/models--mlx-community--gemma-4-12B-it-4bit/snapshots/73bcf09092aa277861d5a191b989b666f7f32e8f" print("Step 1: Load MultimodalModel (TEXT + Audio + Vision)...") let engine = try MarkBaseEngine(autoCompile: true) let loadStart = Date() let mmModel = try MultimodalModel(modelDir: modelDir, engine: engine, maxContextLength: 256) let loadTime = Date().timeIntervalSince(loadStart) * 1000 print(" ✓ Model loaded in \(loadTime) ms") print(" TEXT: hidden=\(mmModel.textModel.hiddenSize), layers=\(mmModel.textModel.numHiddenLayers)") print(" Audio: \(mmModel.audioTower != nil ? "12B (projection)" : "N/A")") print(" Vision: \(mmModel.visionTower != nil ? "12B (simplified)" : "N/A")") // ── Audio Test ─────────────────────────────────────────────────── print("\nStep 2: Process Audio (640-dim embeddings)...") let seqLen = 100 let audioDim = 640 var audioEmbedsInput: [Float] = [] for _ in 0.. maxLogit { maxLogit = logits[i] maxIdx = i } } tokens.append(maxIdx) } let genTime = Date().timeIntervalSince(genStart) * 1000 print(" ✓ Generated 10 tokens in \(genTime) ms") print(" Tokens: \(tokens.suffix(10))") print("\n═══════════════════════════════════════════════════════════════════") print("✓ 12B Full Multimodal test passed") print(" Load: \(loadTime) ms, Audio: \(audioTime) ms, Vision: \(visionTime) ms, Gen: \(genTime) ms") print("═══════════════════════════════════════════════════════════════════\n") XCTAssertFalse(visionEmbeds.contains { $0.isNaN }, "Vision should not have NaN") } }