Initial commit: E4B-MarkBase model integration with passing tests
CI / build-and-test (push) Has been cancelled
CI / build-and-test (push) Has been cancelled
- E4B-MarkBase model (42 layers, 4.4GB) loaded successfully - All Phase 1-6 tests passed (model loading, forward pass, vision/audio towers, token generation, performance) - All stress tests passed (5/5 in 127.6s) - Concurrent inference - Memory stress (67.5 tok/s, 0 NaN) - Continuous generation - Batch processing - Long-running stability - Swift Metal inference engine with multimodal support
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import XCTest
|
||||
@testable import MarkBase
|
||||
|
||||
final class AudioGPUTest: XCTestCase {
|
||||
func testGPUvsCPU() throws {
|
||||
let engine = try MarkBaseEngine(autoCompile: true)
|
||||
let extractor = AudioFeatureExtractor(sampleRate: 16000, nMels: 128, nFft: 400, hopLength: 160)
|
||||
|
||||
var audioData = [Float](repeating: 0, count: 16000)
|
||||
for i in 0..<audioData.count {
|
||||
audioData[i] = sin(2.0 * Float.pi * 440.0 * Float(i) / 16000.0) * 0.5
|
||||
}
|
||||
|
||||
let startCPU = CFAbsoluteTimeGetCurrent()
|
||||
let cpuResult = extractor.extractMelSpectrogram(from: audioData)
|
||||
let cpuTime = CFAbsoluteTimeGetCurrent() - startCPU
|
||||
|
||||
let startGPU = CFAbsoluteTimeGetCurrent()
|
||||
let gpuResult = try extractor.extractMelSpectrogramGPU(engine: engine, audioData: audioData)
|
||||
let gpuTime = CFAbsoluteTimeGetCurrent() - startGPU
|
||||
|
||||
print("CPU: \(cpuResult.count)×\(cpuResult[0].count) in \(String(format: "%.1f", cpuTime * 1000))ms")
|
||||
print("GPU: \(gpuResult.count)×\(gpuResult[0].count) in \(String(format: "%.1f", gpuTime * 1000))ms")
|
||||
print("Speedup: \(String(format: "%.1f", cpuTime / gpuTime))×")
|
||||
|
||||
// Compare in linear scale (log10 amplifies noise-floor differences)
|
||||
var maxLinearDiff: Float = 0
|
||||
var maxRelativeDiff: Float = 0
|
||||
var worstF = 0, worstM = 0
|
||||
for f in 0..<cpuResult.count {
|
||||
for m in 0..<cpuResult[0].count {
|
||||
let cLin = pow(10, cpuResult[f][m])
|
||||
let gLin = pow(10, gpuResult[f][m])
|
||||
let lDiff = abs(cLin - gLin)
|
||||
maxLinearDiff = max(maxLinearDiff, lDiff)
|
||||
if cLin > 1e-8 {
|
||||
let relDiff = lDiff / cLin
|
||||
if relDiff > maxRelativeDiff {
|
||||
maxRelativeDiff = relDiff
|
||||
worstF = f; worstM = m
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print("Max linear diff: \(maxLinearDiff)")
|
||||
print("Max relative diff: \(maxRelativeDiff) at frame=\(worstF) mel=\(worstM)")
|
||||
print(" CPU(lin)=\(pow(10, cpuResult[worstF][worstM])) GPU(lin)=\(pow(10, gpuResult[worstF][worstM]))")
|
||||
XCTAssertLessThan(maxLinearDiff, 1e-3, "GPU mel linear values should match CPU")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user