Files
nvfp4_gguf_quant/llama.cpp/tools/ui/tests/unit/hf-helpers.test.ts
T

166 lines
4.6 KiB
TypeScript

import { HuggingFaceService } from '$lib/services/huggingface.service';
import { describe, expect, it } from 'vitest';
const {
collapseGgufShards,
formatSizeRange,
getBitDepth,
parseCachePath,
parseParamCount,
parseSizeBytes
} = HuggingFaceService;
describe('collapseGgufShards', () => {
it('passes non-sharded files through', () => {
const files = [
{ path: 'Model-Q4_K_M.gguf', size: 100 },
{ path: 'mmproj-F16.gguf', size: 10 }
];
expect(collapseGgufShards(files)).toStrictEqual(files);
});
it('collapses a shard set to its first shard with the summed size', () => {
const files = [
{ path: 'Model-00001-of-00003.gguf', size: 10 },
{ path: 'Model-00002-of-00003.gguf', size: 20 },
{ path: 'Model-00003-of-00003.gguf', size: 30 }
];
expect(collapseGgufShards(files)).toStrictEqual([
{ path: 'Model-00001-of-00003.gguf', size: 60 }
]);
});
it('treats a missing shard as zero bytes', () => {
const files = [
{ path: 'Model-00001-of-00002.gguf', size: 10 },
{ path: 'Model-Q8_0.gguf', size: 5 }
];
expect(collapseGgufShards(files)).toStrictEqual([
{ path: 'Model-00001-of-00002.gguf', size: 10 },
{ path: 'Model-Q8_0.gguf', size: 5 }
]);
});
});
describe('getBitDepth', () => {
it('resolves known tokens', () => {
expect(getBitDepth('Q4_K_M')).toBe(4);
expect(getBitDepth('BF16')).toBe(16);
expect(getBitDepth('IQ2_XXS')).toBe(2);
});
it('strips the UD prefix', () => {
expect(getBitDepth('UD-Q4_K_XL')).toBe(4);
});
it('falls back to the leading precision digits', () => {
expect(getBitDepth('TQ1_0')).toBe(1);
expect(getBitDepth('MXFP4_MOE')).toBe(4);
});
it('returns null for unrecognized tokens', () => {
expect(getBitDepth('xyz')).toBeNull();
expect(getBitDepth('QUANT')).toBeNull();
});
});
describe('formatSizeRange', () => {
it('formats a gigabyte range without spaces around the dash', () => {
expect(formatSizeRange(19e9, 28.6e9)).toBe('19.0-28.6 GB');
});
it('downgrades the unit to the smaller bound when the max is small', () => {
expect(formatSizeRange(1e6, 2.5e6)).toBe('1.0-2.5 MB');
});
it('formats sub-kilobyte sizes in bytes', () => {
expect(formatSizeRange(100, 900)).toBe('100-900 B');
});
});
describe('parseCachePath', () => {
it('parses a posix cache path into repo and file', () => {
expect(
parseCachePath(
'/home/u/.cache/llama.cpp/models--ggml-org--Qwen3-8B-GGUF/snapshots/abc123/Q4_K_M.gguf'
)
).toStrictEqual({ file: 'Q4_K_M.gguf', repo: 'ggml-org/Qwen3-8B-GGUF' });
});
it('accepts windows separators', () => {
expect(
parseCachePath('C:\\cache\\models--org--Model\\snapshots\\sha\\sub\\file.gguf')
).toStrictEqual({ file: 'sub/file.gguf', repo: 'org/Model' });
});
it('returns null for non-cache paths', () => {
expect(parseCachePath('/models/foo.gguf')).toBeNull();
});
});
describe('parseParamCount', () => {
it('extracts billions and millions', () => {
expect(parseParamCount('Qwen3.8-27B-GGUF')).toBe('27B');
expect(parseParamCount('embeddinggemma-300M-GGUF')).toBe('300M');
expect(parseParamCount('Model-0.6B-Q4_K_M')).toBe('0.6B');
});
it('returns null when no size token is present', () => {
expect(parseParamCount('ggml-org/Laguna-S-GGUF')).toBeNull();
});
});
describe('isDecisionModel', () => {
it('flags the decision-model tag', () => {
expect(
HuggingFaceService.isDecisionModel({
pipeline_tag: 'text-classification',
tags: ['gguf', 'decision-model', 'text-classification']
})
).toBe(true);
});
it('flags a text-classification pipeline even without the tag', () => {
expect(
HuggingFaceService.isDecisionModel({ pipeline_tag: 'text-classification', tags: ['gguf'] })
).toBe(true);
});
it('passes regular LLM tasks through', () => {
expect(
HuggingFaceService.isDecisionModel({
pipeline_tag: 'text-generation',
tags: ['gguf', 'text-generation']
})
).toBe(false);
expect(
HuggingFaceService.isDecisionModel({
pipeline_tag: 'image-text-to-text',
tags: ['gguf', 'image-text-to-text']
})
).toBe(false);
});
it('passes repos without task metadata through', () => {
expect(HuggingFaceService.isDecisionModel({ pipeline_tag: null, tags: [] })).toBe(false);
});
});
describe('parseSizeBytes', () => {
it('parses single-letter catalog size suffixes', () => {
expect(parseSizeBytes('177g')).toBe(177e9);
expect(parseSizeBytes('1.2 t')).toBe(1.2e12);
expect(parseSizeBytes('500m')).toBe(500e6);
});
it('returns null for malformed input', () => {
expect(parseSizeBytes('unknown')).toBeNull();
expect(parseSizeBytes('12 parsecs')).toBeNull();
expect(parseSizeBytes('')).toBeNull();
});
});