mirror of
https://github.com/signerless/llm-checker.git
synced 2026-10-19 09:54:45 +00:00
Four tests failed or flaked because they were coupled to the host environment rather than testing the code under test: - token-speed-estimation: asserted the host was an Apple M4 Pro Mac, so it could only pass on the author's machine. Now drives the estimators from a fixed M4 Pro hardware fixture — deterministic and host-independent. - hardware-detector-regression: the "ignore remote display adapter" case mocked systeminformation but the Linux-only lspci augmentation still shelled out and leaked the host's real GPUs (3 found, 1 expected). Stub lspci so the case stays hermetic. - cpu-detector-windows-fallback: read live os.cpus()[0].speed twice, so CPU frequency scaling made the exact-equality assertion flaky (5614 vs 5618). Pin os.cpus() to a stable snapshot for the case. - ollama-client-speed-metrics: hard-failed when no local Ollama server was reachable. Skip cleanly (matching the existing no-models skip) so the suite is green in CI/dev environments without Ollama. Also remove the accidentally committed .tmp-feature-check/ probe artifacts and gitignore transient probe dirs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
113 lines
4.5 KiB
JavaScript
113 lines
4.5 KiB
JavaScript
const assert = require('assert');
|
|
const PerformanceAnalyzer = require('../analyzer/performance');
|
|
const ExpandedModelsDatabase = require('../src/models/expanded_database');
|
|
const { estimateTokenSpeedFromHardware } = require('../src/utils/token-speed-estimator');
|
|
|
|
function isM4ProMac(hardware) {
|
|
const cpuBrand = String(hardware?.cpu?.brand || '').toLowerCase();
|
|
const gpuModel = String(hardware?.gpu?.model || '').toLowerCase();
|
|
return (
|
|
String(hardware?.os?.platform || '').toLowerCase() === 'darwin' &&
|
|
String(hardware?.cpu?.architecture || '').toLowerCase().includes('apple') &&
|
|
(cpuBrand.includes('m4 pro') || gpuModel.includes('m4 pro'))
|
|
);
|
|
}
|
|
|
|
async function run() {
|
|
// Hermetic reference fixture: an Apple M4 Pro Mac. Driving the estimators from
|
|
// a fixed hardware profile (rather than the live host) keeps this test
|
|
// deterministic and host-independent — it validates the estimation math, not
|
|
// the machine the suite happens to run on.
|
|
const hardware = {
|
|
os: { platform: 'darwin' },
|
|
cpu: {
|
|
brand: 'Apple M4 Pro',
|
|
model: 'Apple M4 Pro',
|
|
architecture: 'Apple Silicon (ARM64)',
|
|
physicalCores: 12,
|
|
cores: 12,
|
|
speed: 4.5
|
|
},
|
|
gpu: { model: 'Apple M4 Pro', vram: 0 },
|
|
memory: { total: 24 },
|
|
summary: { hasIntegratedGPU: false, hasDedicatedGPU: false }
|
|
};
|
|
|
|
assert.strictEqual(
|
|
String(hardware.os?.platform || '').toLowerCase(),
|
|
'darwin',
|
|
`Expected macOS platform, got ${hardware.os?.platform}`
|
|
);
|
|
assert(
|
|
String(hardware.cpu?.architecture || '').toLowerCase().includes('apple'),
|
|
`Expected Apple Silicon architecture, got ${hardware.cpu?.architecture}`
|
|
);
|
|
assert(
|
|
Number(hardware.memory?.total) >= 16,
|
|
`Expected at least 16GB RAM on reference Mac, got ${hardware.memory?.total}GB`
|
|
);
|
|
|
|
const speed3B = estimateTokenSpeedFromHardware(hardware, { modelSizeB: 3, modelName: 'llama3.2:3b' });
|
|
const speed8B = estimateTokenSpeedFromHardware(hardware, { modelSizeB: 8, modelName: 'llama3.1:8b' });
|
|
const speed13B = estimateTokenSpeedFromHardware(hardware, { modelSizeB: 13, modelName: 'llama3.1:13b' });
|
|
|
|
assert.strictEqual(speed3B.backend, 'metal', `Expected metal backend on Apple Silicon, got ${speed3B.backend}`);
|
|
assert(
|
|
speed3B.tokensPerSecond > speed8B.tokensPerSecond && speed8B.tokensPerSecond > speed13B.tokensPerSecond,
|
|
`Expected monotonic scaling 3B > 8B > 13B, got ${speed3B.tokensPerSecond} > ${speed8B.tokensPerSecond} > ${speed13B.tokensPerSecond}`
|
|
);
|
|
assert(speed8B.tokensPerSecond > 0, `Expected positive TPS for 8B, got ${speed8B.tokensPerSecond}`);
|
|
|
|
if (isM4ProMac(hardware)) {
|
|
assert(
|
|
speed8B.tokensPerSecond >= 30 && speed8B.tokensPerSecond <= 70,
|
|
`M4 Pro 8B estimate out of expected band (30-70 t/s), got ${speed8B.tokensPerSecond}`
|
|
);
|
|
}
|
|
|
|
const analyzer = new PerformanceAnalyzer();
|
|
const parsedSizeFromGB = analyzer.parseModelSize('4.9GB');
|
|
assert(
|
|
parsedSizeFromGB >= 7 && parsedSizeFromGB <= 9.5,
|
|
`parseModelSize should infer params from GB notation, got ${parsedSizeFromGB}`
|
|
);
|
|
|
|
const perfEstimate = analyzer.calculateRealisticPerformance(
|
|
{ name: 'llama3.1:8b', size: '8B', requirements: { ram: 10 } },
|
|
hardware
|
|
);
|
|
assert.strictEqual(
|
|
perfEstimate.estimatedTokensPerSecond,
|
|
speed8B.tokensPerSecond,
|
|
`Performance analyzer should use shared estimator (expected ${speed8B.tokensPerSecond}, got ${perfEstimate.estimatedTokensPerSecond})`
|
|
);
|
|
|
|
const database = new ExpandedModelsDatabase();
|
|
const dbSpeed = database.calculateRealisticTokensPerSecond(
|
|
{ name: 'llama3.1:8b', size: '8B' },
|
|
hardware
|
|
);
|
|
assert.strictEqual(
|
|
dbSpeed,
|
|
speed8B.tokensPerSecond,
|
|
`Expanded database estimator should align with shared estimator (expected ${speed8B.tokensPerSecond}, got ${dbSpeed})`
|
|
);
|
|
|
|
const tinyParams = database.extractModelParams({ name: 'all-minilm:22m', size: '22M' });
|
|
assert(
|
|
tinyParams > 0 && tinyParams < 0.1,
|
|
`extractModelParams should convert M suffix to billions, got ${tinyParams}`
|
|
);
|
|
|
|
console.log('token-speed-estimation.test.js: OK');
|
|
}
|
|
|
|
if (require.main === module) {
|
|
run().catch((error) => {
|
|
console.error('token-speed-estimation.test.js: FAILED');
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
module.exports = { run };
|