ac75faa0cc
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
51 lines
2.2 KiB
Swift
51 lines
2.2 KiB
Swift
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")
|
||
}
|
||
}
|