@infersec/conduit 1.111.0 → 1.112.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +331 -42
- package/dist/cli.sea.cjs +331 -42
- package/dist/utils/machineInfo.d.ts +18 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -21567,6 +21567,90 @@ object$5({
|
|
|
21567
21567
|
// Source of truth for curated recommended models. Consumed by @infersec/definitions
|
|
21568
21568
|
// and the website model page generator (applications/website/scripts/generate-model-pages.ts).
|
|
21569
21569
|
const modelsData = [
|
|
21570
|
+
{
|
|
21571
|
+
author: "LiquidAI",
|
|
21572
|
+
baseModel: "LiquidAI/LFM2.5-2.6B",
|
|
21573
|
+
blurb: "Liquid's LFM2.5 2.6B hybrid at high fidelity - agentic post-training, 128K context, and 220 tok/s decode on an M5 Max. Fits a 4 GB card with room to spare.",
|
|
21574
|
+
contextLength: 131072,
|
|
21575
|
+
fileSizeBytes: 2874779648,
|
|
21576
|
+
format: "gguf",
|
|
21577
|
+
license: "lfm1.0",
|
|
21578
|
+
parameterCount: "2.6B",
|
|
21579
|
+
quantization: "Q8_0",
|
|
21580
|
+
slug: "LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21581
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21582
|
+
vramTierGB: 4
|
|
21583
|
+
},
|
|
21584
|
+
{
|
|
21585
|
+
author: "LiquidAI",
|
|
21586
|
+
baseModel: "LiquidAI/LFM2.5-2.6B",
|
|
21587
|
+
blurb: "Liquid's LFM2.5 2.6B hybrid at 4-bit - competitive with models 4x its size on tool use and multi-step agentic tasks. A 1.7 GB download that sips memory.",
|
|
21588
|
+
contextLength: 131072,
|
|
21589
|
+
fileSizeBytes: 1674455040,
|
|
21590
|
+
format: "gguf",
|
|
21591
|
+
license: "lfm1.0",
|
|
21592
|
+
parameterCount: "2.6B",
|
|
21593
|
+
quantization: "Q4_K_M",
|
|
21594
|
+
slug: "LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21595
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21596
|
+
vramTierGB: 4
|
|
21597
|
+
},
|
|
21598
|
+
{
|
|
21599
|
+
author: "LiquidAI",
|
|
21600
|
+
baseModel: "LiquidAI/LFM2.5-2.6B",
|
|
21601
|
+
blurb: "The native BF16 checkpoint of Liquid's LFM2.5 2.6B for vLLM and SGLang - hybrid conv + GQA architecture, 128K context window, and agentic reinforcement-learning post-training.",
|
|
21602
|
+
contextLength: 131072,
|
|
21603
|
+
fileSizeBytes: 5394427456,
|
|
21604
|
+
format: "safetensors",
|
|
21605
|
+
license: "lfm1.0",
|
|
21606
|
+
parameterCount: "2.6B",
|
|
21607
|
+
quantization: "BF16",
|
|
21608
|
+
slug: "LiquidAI/LFM2.5-2.6B",
|
|
21609
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-2.6B",
|
|
21610
|
+
vramTierGB: 8
|
|
21611
|
+
},
|
|
21612
|
+
{
|
|
21613
|
+
author: "LiquidAI",
|
|
21614
|
+
baseModel: "LiquidAI/LFM2.5-230M",
|
|
21615
|
+
blurb: "Liquid's most compact LFM2.5 at high fidelity - a 230M edge model distilled from the 350M, tuned for tool use and data extraction. 213 tok/s decode on a Galaxy S25 Ultra.",
|
|
21616
|
+
contextLength: 32768,
|
|
21617
|
+
fileSizeBytes: 246598496,
|
|
21618
|
+
format: "gguf",
|
|
21619
|
+
license: "lfm1.0",
|
|
21620
|
+
parameterCount: "230M",
|
|
21621
|
+
quantization: "Q8_0",
|
|
21622
|
+
slug: "LiquidAI/LFM2.5-230M-GGUF",
|
|
21623
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-230M-GGUF",
|
|
21624
|
+
vramTierGB: 2
|
|
21625
|
+
},
|
|
21626
|
+
{
|
|
21627
|
+
author: "LiquidAI",
|
|
21628
|
+
baseModel: "LiquidAI/LFM2.5-230M",
|
|
21629
|
+
blurb: "Liquid's most compact LFM2.5 at 4-bit - a 153 MB download that brings real tool-use capability to the tightest memory budgets, from Raspberry Pi to phones.",
|
|
21630
|
+
contextLength: 32768,
|
|
21631
|
+
fileSizeBytes: 153406304,
|
|
21632
|
+
format: "gguf",
|
|
21633
|
+
license: "lfm1.0",
|
|
21634
|
+
parameterCount: "230M",
|
|
21635
|
+
quantization: "Q4_K_M",
|
|
21636
|
+
slug: "LiquidAI/LFM2.5-230M-GGUF",
|
|
21637
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-230M-GGUF",
|
|
21638
|
+
vramTierGB: 2
|
|
21639
|
+
},
|
|
21640
|
+
{
|
|
21641
|
+
author: "LiquidAI",
|
|
21642
|
+
baseModel: "LiquidAI/LFM2.5-230M",
|
|
21643
|
+
blurb: "The native BF16 checkpoint of Liquid's LFM2.5 230M for vLLM - a 230M edge model with a 32K context window, suited to data extraction and lightweight on-device agent pipelines.",
|
|
21644
|
+
contextLength: 32768,
|
|
21645
|
+
fileSizeBytes: 459401112,
|
|
21646
|
+
format: "safetensors",
|
|
21647
|
+
license: "lfm1.0",
|
|
21648
|
+
parameterCount: "230M",
|
|
21649
|
+
quantization: "BF16",
|
|
21650
|
+
slug: "LiquidAI/LFM2.5-230M",
|
|
21651
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-230M",
|
|
21652
|
+
vramTierGB: 4
|
|
21653
|
+
},
|
|
21570
21654
|
{
|
|
21571
21655
|
author: "Qwen",
|
|
21572
21656
|
baseModel: "Qwen/Qwen3-8B",
|
|
@@ -21623,6 +21707,48 @@ const modelsData = [
|
|
|
21623
21707
|
sourceURL: "https://huggingface.co/bartowski/deepreinforce-ai_Ornith-1.0-9B-GGUF",
|
|
21624
21708
|
vramTierGB: 16
|
|
21625
21709
|
},
|
|
21710
|
+
{
|
|
21711
|
+
author: "unsloth",
|
|
21712
|
+
baseModel: "nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16",
|
|
21713
|
+
blurb: "NVIDIA's Nemotron 3.5 Lightning MoE squeezed into 2-bit - 30B total with only 3B active in a Mamba-2 + MoE + attention hybrid. Configurable thinking and a 256K context on a single 24 GB card.",
|
|
21714
|
+
contextLength: 262144,
|
|
21715
|
+
fileSizeBytes: 19432070208,
|
|
21716
|
+
format: "gguf",
|
|
21717
|
+
license: "openmdw-1.1",
|
|
21718
|
+
parameterCount: "30B",
|
|
21719
|
+
quantization: "UD-IQ2_M",
|
|
21720
|
+
slug: "unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21721
|
+
sourceURL: "https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21722
|
+
vramTierGB: 24
|
|
21723
|
+
},
|
|
21724
|
+
{
|
|
21725
|
+
author: "unsloth",
|
|
21726
|
+
baseModel: "nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16",
|
|
21727
|
+
blurb: "NVIDIA's Nemotron 3.5 Lightning at Unsloth's dynamic 4-bit - a Mamba-2 hybrid MoE with 3B active parameters, toggleable reasoning, and strong instruction following (IFBench 71.9). Needs a 32 GB GPU.",
|
|
21728
|
+
contextLength: 262144,
|
|
21729
|
+
fileSizeBytes: 25266255936,
|
|
21730
|
+
format: "gguf",
|
|
21731
|
+
license: "openmdw-1.1",
|
|
21732
|
+
parameterCount: "30B",
|
|
21733
|
+
quantization: "UD-Q4_K_M",
|
|
21734
|
+
slug: "unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21735
|
+
sourceURL: "https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21736
|
+
vramTierGB: 32
|
|
21737
|
+
},
|
|
21738
|
+
{
|
|
21739
|
+
author: "unsloth",
|
|
21740
|
+
baseModel: "nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16",
|
|
21741
|
+
blurb: "Nemotron 3.5 Lightning at 8-bit fidelity - near-reference quality from the 30B-A3B Mamba-2 hybrid, with configurable thinking and DSpark speculative decoding support. Needs a 48 GB card.",
|
|
21742
|
+
contextLength: 262144,
|
|
21743
|
+
fileSizeBytes: 35004643392,
|
|
21744
|
+
format: "gguf",
|
|
21745
|
+
license: "openmdw-1.1",
|
|
21746
|
+
parameterCount: "30B",
|
|
21747
|
+
quantization: "Q8_0",
|
|
21748
|
+
slug: "unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21749
|
+
sourceURL: "https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21750
|
+
vramTierGB: 48
|
|
21751
|
+
},
|
|
21626
21752
|
{
|
|
21627
21753
|
author: "unsloth",
|
|
21628
21754
|
baseModel: "openai/gpt-oss-20b",
|
|
@@ -21681,6 +21807,76 @@ const modelsData = [
|
|
|
21681
21807
|
sourceURL: "https://huggingface.co/unsloth/Qwen3.8-Flash-Next-GGUF",
|
|
21682
21808
|
vramTierGB: 128
|
|
21683
21809
|
},
|
|
21810
|
+
{
|
|
21811
|
+
author: "Qwen",
|
|
21812
|
+
baseModel: "Qwen/Qwen3.8-Flash-Next",
|
|
21813
|
+
blurb: "The official BF16 release of Qwen's experimental Qwen4-preview architecture - 180B total with only 6B activated, plus 51B n-gram embeddings, a vision encoder, and a 262K native context. For vLLM/SGLang on multi-GPU server hardware.",
|
|
21814
|
+
contextLength: 262144,
|
|
21815
|
+
fileSizeBytes: 360000192888,
|
|
21816
|
+
format: "safetensors",
|
|
21817
|
+
license: "qwen-community-1.0",
|
|
21818
|
+
parameterCount: "180B",
|
|
21819
|
+
quantization: "BF16",
|
|
21820
|
+
slug: "Qwen/Qwen3.8-Flash-Next",
|
|
21821
|
+
sourceURL: "https://huggingface.co/Qwen/Qwen3.8-Flash-Next",
|
|
21822
|
+
vramTierGB: 640
|
|
21823
|
+
},
|
|
21824
|
+
{
|
|
21825
|
+
author: "RadixArk",
|
|
21826
|
+
baseModel: "Qwen/Qwen3.8-Flash-Next",
|
|
21827
|
+
blurb: "Qwen3.8-Flash-Next with its routed experts quantized to NVIDIA's NVFP4 W4A4 via Model Optimizer - 135 GB instead of 360 GB BF16, keeping GSM8K/AIME in-band with the reference. Serve with SGLang on Blackwell hardware.",
|
|
21828
|
+
contextLength: 262144,
|
|
21829
|
+
fileSizeBytes: 135195303851,
|
|
21830
|
+
format: "safetensors",
|
|
21831
|
+
license: "qwen-community-1.0",
|
|
21832
|
+
parameterCount: "180B",
|
|
21833
|
+
quantization: "NVFP4",
|
|
21834
|
+
slug: "RadixArk/Qwen3.8-Flash-Next-NVFP4",
|
|
21835
|
+
sourceURL: "https://huggingface.co/RadixArk/Qwen3.8-Flash-Next-NVFP4",
|
|
21836
|
+
vramTierGB: 256
|
|
21837
|
+
},
|
|
21838
|
+
{
|
|
21839
|
+
author: "deepseek-ai",
|
|
21840
|
+
baseModel: "deepseek-ai/DeepSeek-V4-Flash",
|
|
21841
|
+
blurb: "DeepSeek's V4-Flash - a 284B MoE with only 13B activated and a native 1M context window, shipped in mixed FP4/FP8 precision. Hybrid CSA/HCA attention keeps long-context inference cheap, with three reasoning-effort modes including Think Max.",
|
|
21842
|
+
contextLength: 1048576,
|
|
21843
|
+
fileSizeBytes: 159617149040,
|
|
21844
|
+
format: "safetensors",
|
|
21845
|
+
license: "mit",
|
|
21846
|
+
parameterCount: "284B",
|
|
21847
|
+
quantization: "FP4-FP8",
|
|
21848
|
+
slug: "deepseek-ai/DeepSeek-V4-Flash",
|
|
21849
|
+
sourceURL: "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash",
|
|
21850
|
+
vramTierGB: 256
|
|
21851
|
+
},
|
|
21852
|
+
{
|
|
21853
|
+
author: "unsloth",
|
|
21854
|
+
baseModel: "deepseek-ai/DeepSeek-V4-Flash-Vision-Exp",
|
|
21855
|
+
blurb: "Unsloth's 2-bit cut of DeepSeek's experimental vision variant of V4-Flash - the same 284B MoE with 13B activated, plus image understanding via a separate mmproj projector. Fits 128 GB of unified memory or 2x 96 GB.",
|
|
21856
|
+
contextLength: 1048576,
|
|
21857
|
+
fileSizeBytes: 90692965818,
|
|
21858
|
+
format: "gguf",
|
|
21859
|
+
license: "mit",
|
|
21860
|
+
parameterCount: "284B",
|
|
21861
|
+
quantization: "UD-IQ2_XXS",
|
|
21862
|
+
slug: "unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21863
|
+
sourceURL: "https://huggingface.co/unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21864
|
+
vramTierGB: 128
|
|
21865
|
+
},
|
|
21866
|
+
{
|
|
21867
|
+
author: "unsloth",
|
|
21868
|
+
baseModel: "deepseek-ai/DeepSeek-V4-Flash-Vision-Exp",
|
|
21869
|
+
blurb: "The 4-bit cut of DeepSeek's experimental vision variant of V4-Flash - 284B MoE with 13B activated at higher fidelity, with multimodal agent scores well clear of the text-only release. Image input currently needs a preview llama.cpp build; needs 256 GB.",
|
|
21870
|
+
contextLength: 1048576,
|
|
21871
|
+
fileSizeBytes: 136662447706,
|
|
21872
|
+
format: "gguf",
|
|
21873
|
+
license: "mit",
|
|
21874
|
+
parameterCount: "284B",
|
|
21875
|
+
quantization: "UD-IQ4_XS",
|
|
21876
|
+
slug: "unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21877
|
+
sourceURL: "https://huggingface.co/unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21878
|
+
vramTierGB: 256
|
|
21879
|
+
},
|
|
21684
21880
|
{
|
|
21685
21881
|
author: "unsloth",
|
|
21686
21882
|
baseModel: "Qwen/Qwen3.6-27B",
|
|
@@ -137740,12 +137936,20 @@ async function detectVRAMViaSysfs(pciBusSuffix) {
|
|
|
137740
137936
|
const deviceDir = path$1.join(DRM_PATH, entry, "device");
|
|
137741
137937
|
const totalStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_vram_total"));
|
|
137742
137938
|
const usedStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_vram_used"));
|
|
137939
|
+
const gttTotalStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_gtt_total"));
|
|
137940
|
+
const gttUsedStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_gtt_used"));
|
|
137743
137941
|
const totalBytes = totalStr !== null ? parseInt(totalStr, 10) : null;
|
|
137744
137942
|
const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
|
|
137943
|
+
const gttTotalBytes = gttTotalStr !== null ? parseInt(gttTotalStr, 10) : null;
|
|
137944
|
+
const gttUsedBytes = gttUsedStr !== null ? parseInt(gttUsedStr, 10) : null;
|
|
137745
137945
|
const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
|
|
137746
137946
|
const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
|
|
137947
|
+
const validGttTotal = gttTotalBytes !== null && Number.isFinite(gttTotalBytes) && gttTotalBytes >= 0;
|
|
137948
|
+
const validGttUsed = gttUsedBytes !== null && Number.isFinite(gttUsedBytes) && gttUsedBytes >= 0;
|
|
137747
137949
|
if (validTotal) {
|
|
137748
137950
|
return {
|
|
137951
|
+
gttTotalBytes: validGttTotal ? gttTotalBytes : null,
|
|
137952
|
+
gttUsedBytes: validGttUsed ? gttUsedBytes : null,
|
|
137749
137953
|
memoryTotalBytes: totalBytes,
|
|
137750
137954
|
memoryUsedBytes: validUsed ? usedBytes : null
|
|
137751
137955
|
};
|
|
@@ -137755,36 +137959,74 @@ async function detectVRAMViaSysfs(pciBusSuffix) {
|
|
|
137755
137959
|
catch {
|
|
137756
137960
|
// sysfs not available
|
|
137757
137961
|
}
|
|
137758
|
-
return {
|
|
137962
|
+
return {
|
|
137963
|
+
gttTotalBytes: null,
|
|
137964
|
+
gttUsedBytes: null,
|
|
137965
|
+
memoryTotalBytes: null,
|
|
137966
|
+
memoryUsedBytes: null
|
|
137967
|
+
};
|
|
137759
137968
|
}
|
|
137760
|
-
|
|
137969
|
+
// rocm-smi accepts a single --showmeminfo type per invocation, so VRAM and GTT
|
|
137970
|
+
// arrive from separate calls; both share this per-card parser.
|
|
137971
|
+
function parseRocmSmiMemory({ keyPrefix, stdout }) {
|
|
137972
|
+
const parsed = JSON.parse(stdout);
|
|
137973
|
+
const results = [];
|
|
137974
|
+
const cards = Object.entries(parsed).filter(([key]) => key.startsWith("card"));
|
|
137975
|
+
for (const [, data] of cards) {
|
|
137976
|
+
const bus = data["PCI Bus"] ?? null;
|
|
137977
|
+
const totalStr = data[`${keyPrefix} Total Memory (B)`] ?? null;
|
|
137978
|
+
const usedStr = data[`${keyPrefix} Total Used Memory (B)`] ?? null;
|
|
137979
|
+
const totalBytes = totalStr !== null ? parseInt(totalStr, 10) : null;
|
|
137980
|
+
const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
|
|
137981
|
+
const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
|
|
137982
|
+
const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
|
|
137983
|
+
if (bus) {
|
|
137984
|
+
results.push({
|
|
137985
|
+
bus,
|
|
137986
|
+
memoryTotalBytes: validTotal ? totalBytes : null,
|
|
137987
|
+
memoryUsedBytes: validUsed ? usedBytes : null
|
|
137988
|
+
});
|
|
137989
|
+
}
|
|
137990
|
+
}
|
|
137991
|
+
return results;
|
|
137992
|
+
}
|
|
137993
|
+
const ROCM_SMI_TIMEOUT_MS = 10_000;
|
|
137994
|
+
async function detectVRAMViaRocmSmi({ logger }) {
|
|
137761
137995
|
try {
|
|
137762
|
-
const
|
|
137763
|
-
"--showbus",
|
|
137764
|
-
|
|
137765
|
-
|
|
137766
|
-
"--json"
|
|
137996
|
+
const [vramResult, gttResult] = await Promise.allSettled([
|
|
137997
|
+
execa("rocm-smi", ["--showbus", "--showmeminfo", "vram", "--json"], {
|
|
137998
|
+
timeout: ROCM_SMI_TIMEOUT_MS
|
|
137999
|
+
}),
|
|
138000
|
+
execa("rocm-smi", ["--showbus", "--showmeminfo", "gtt", "--json"], {
|
|
138001
|
+
timeout: ROCM_SMI_TIMEOUT_MS
|
|
138002
|
+
})
|
|
137767
138003
|
]);
|
|
137768
|
-
|
|
137769
|
-
|
|
137770
|
-
|
|
137771
|
-
|
|
137772
|
-
|
|
137773
|
-
|
|
137774
|
-
|
|
137775
|
-
|
|
137776
|
-
const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
|
|
137777
|
-
const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
|
|
137778
|
-
const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
|
|
137779
|
-
if (bus) {
|
|
137780
|
-
results.push({
|
|
137781
|
-
bus,
|
|
137782
|
-
memoryTotalBytes: validTotal ? totalBytes : null,
|
|
137783
|
-
memoryUsedBytes: validUsed ? usedBytes : null
|
|
138004
|
+
if (vramResult.status !== "fulfilled")
|
|
138005
|
+
return [];
|
|
138006
|
+
let gttEntries = [];
|
|
138007
|
+
if (gttResult.status === "fulfilled") {
|
|
138008
|
+
try {
|
|
138009
|
+
gttEntries = parseRocmSmiMemory({
|
|
138010
|
+
keyPrefix: "GTT",
|
|
138011
|
+
stdout: gttResult.value.stdout
|
|
137784
138012
|
});
|
|
137785
138013
|
}
|
|
138014
|
+
catch (error) {
|
|
138015
|
+
// Unusable GTT output (e.g. older rocm-smi) degrades to VRAM-only
|
|
138016
|
+
logger.warn("rocm-smi GTT output parse failed", { error: asError(error) });
|
|
138017
|
+
}
|
|
137786
138018
|
}
|
|
137787
|
-
|
|
138019
|
+
const gttByBus = new Map(gttEntries.map(entry => [entry.bus, entry]));
|
|
138020
|
+
return parseRocmSmiMemory({ keyPrefix: "VRAM", stdout: vramResult.value.stdout }).map(vram => {
|
|
138021
|
+
const gtt = gttByBus.get(vram.bus);
|
|
138022
|
+
return {
|
|
138023
|
+
bus: vram.bus,
|
|
138024
|
+
gttTotalBytes: gtt?.memoryTotalBytes ?? null,
|
|
138025
|
+
gttUsedBytes: gtt?.memoryUsedBytes ?? null,
|
|
138026
|
+
memoryTotalBytes: vram.memoryTotalBytes,
|
|
138027
|
+
memoryUsedBytes: vram.memoryUsedBytes
|
|
138028
|
+
};
|
|
138029
|
+
});
|
|
137788
138030
|
}
|
|
137789
138031
|
catch {
|
|
137790
138032
|
return [];
|
|
@@ -137849,8 +138091,9 @@ async function detectGPUsViaNvidiaSmi({ logger }) {
|
|
|
137849
138091
|
vendor: "NVIDIA"
|
|
137850
138092
|
});
|
|
137851
138093
|
}
|
|
137852
|
-
//
|
|
137853
|
-
// memory. Their compute pool is system RAM, so fall back to
|
|
138094
|
+
// Shared/unified-memory devices (e.g. NVIDIA GB10 on DGX Spark) report
|
|
138095
|
+
// "[N/A]" for memory. Their compute pool is system RAM, so fall back to
|
|
138096
|
+
// /proc/meminfo. (AMD iGPUs get the same treatment via GTT merging.)
|
|
137854
138097
|
if (gpus.some(gpu => gpu.memoryTotalBytes === null)) {
|
|
137855
138098
|
const systemMemory = await readSystemMemoryBytes({ logger });
|
|
137856
138099
|
const total = systemMemory.totalBytes;
|
|
@@ -137874,7 +138117,7 @@ async function detectGPUsViaNvidiaSmi({ logger }) {
|
|
|
137874
138117
|
}
|
|
137875
138118
|
}
|
|
137876
138119
|
function buildMergedGPUs(options) {
|
|
137877
|
-
const { lspciGPUs, nvidiaGPUs, rocmVRAM, siGPUs, sysfsVRAMMap } = options;
|
|
138120
|
+
const { lspciGPUs, nvidiaGPUs, rocmVRAM, siGPUs, systemTotalBytes, sysfsVRAMMap } = options;
|
|
137878
138121
|
const rocmByBus = new Map();
|
|
137879
138122
|
for (const entry of rocmVRAM) {
|
|
137880
138123
|
const key = normalizeBusAddress(entry.bus);
|
|
@@ -137915,6 +138158,7 @@ function buildMergedGPUs(options) {
|
|
|
137915
138158
|
gpu: existing,
|
|
137916
138159
|
key,
|
|
137917
138160
|
rocmByBus,
|
|
138161
|
+
systemTotalBytes,
|
|
137918
138162
|
sysfsVRAMMap
|
|
137919
138163
|
});
|
|
137920
138164
|
}
|
|
@@ -137934,30 +138178,73 @@ function buildMergedGPUs(options) {
|
|
|
137934
138178
|
gpu,
|
|
137935
138179
|
key,
|
|
137936
138180
|
rocmByBus,
|
|
138181
|
+
systemTotalBytes,
|
|
137937
138182
|
sysfsVRAMMap
|
|
137938
138183
|
});
|
|
137939
138184
|
byBus.set(key, gpu);
|
|
137940
138185
|
}
|
|
137941
138186
|
return [...byBus.values()];
|
|
137942
138187
|
}
|
|
137943
|
-
|
|
138188
|
+
// Shared-memory GPUs (AMD iGPUs) expose a small dedicated VRAM carve-out via
|
|
138189
|
+
// mem_info_vram_total while the real usable pool - GTT - is carved dynamically
|
|
138190
|
+
// from system RAM. When GTT exceeds VRAM the device is treated as integrated
|
|
138191
|
+
// and the two pools combine (capped by installed RAM). Note that GTT defaults
|
|
138192
|
+
// to half of system RAM even on discrete GPUs, so a dGPU with less VRAM than
|
|
138193
|
+
// that also merges - acceptable, since GTT remains real addressable memory
|
|
138194
|
+
// for amdgpu compute (albeit slower over PCIe).
|
|
138195
|
+
function mergeGTTMemory({ gttTotalBytes, gttUsedBytes, systemTotalBytes, vramTotalBytes, vramUsedBytes }) {
|
|
138196
|
+
if (vramTotalBytes === null || !Number.isFinite(vramTotalBytes)) {
|
|
138197
|
+
return { memoryTotalBytes: null, memoryUsedBytes: null };
|
|
138198
|
+
}
|
|
138199
|
+
const isIntegrated = gttTotalBytes !== null && gttTotalBytes > vramTotalBytes;
|
|
138200
|
+
if (!isIntegrated) {
|
|
138201
|
+
return { memoryTotalBytes: vramTotalBytes, memoryUsedBytes: vramUsedBytes };
|
|
138202
|
+
}
|
|
138203
|
+
const combined = vramTotalBytes + gttTotalBytes;
|
|
138204
|
+
const capped = systemTotalBytes !== null && systemTotalBytes > 0
|
|
138205
|
+
? Math.min(combined, systemTotalBytes)
|
|
138206
|
+
: combined;
|
|
138207
|
+
const hasCompleteUsage = vramUsedBytes !== null &&
|
|
138208
|
+
Number.isFinite(vramUsedBytes) &&
|
|
138209
|
+
gttUsedBytes !== null &&
|
|
138210
|
+
Number.isFinite(gttUsedBytes);
|
|
138211
|
+
const memoryUsedBytes = hasCompleteUsage
|
|
138212
|
+
? Math.min(vramUsedBytes + gttUsedBytes, capped)
|
|
138213
|
+
: null;
|
|
138214
|
+
return { memoryTotalBytes: capped, memoryUsedBytes };
|
|
138215
|
+
}
|
|
138216
|
+
function applySysfsOrRocmVRAM({ gpu, key, rocmByBus, systemTotalBytes, sysfsVRAMMap }) {
|
|
137944
138217
|
const sysfs = sysfsVRAMMap.get(key);
|
|
137945
|
-
let
|
|
137946
|
-
let
|
|
137947
|
-
|
|
138218
|
+
let vramTotalBytes = sysfs?.memoryTotalBytes ?? null;
|
|
138219
|
+
let vramUsedBytes = sysfs?.memoryUsedBytes ?? null;
|
|
138220
|
+
let gttTotalBytes = sysfs?.gttTotalBytes ?? null;
|
|
138221
|
+
let gttUsedBytes = sysfs?.gttUsedBytes ?? null;
|
|
138222
|
+
if (vramTotalBytes === null) {
|
|
137948
138223
|
const rocm = rocmByBus.get(key);
|
|
137949
138224
|
if (rocm) {
|
|
137950
|
-
|
|
137951
|
-
|
|
137952
|
-
|
|
137953
|
-
|
|
137954
|
-
|
|
138225
|
+
vramTotalBytes = rocm.memoryTotalBytes;
|
|
138226
|
+
vramUsedBytes = rocm.memoryUsedBytes;
|
|
138227
|
+
gttTotalBytes = rocm.gttTotalBytes;
|
|
138228
|
+
gttUsedBytes = rocm.gttUsedBytes;
|
|
138229
|
+
}
|
|
138230
|
+
}
|
|
138231
|
+
const merged = mergeGTTMemory({
|
|
138232
|
+
gttTotalBytes,
|
|
138233
|
+
gttUsedBytes,
|
|
138234
|
+
systemTotalBytes,
|
|
138235
|
+
vramTotalBytes,
|
|
138236
|
+
vramUsedBytes
|
|
138237
|
+
});
|
|
138238
|
+
if (merged.memoryTotalBytes === null || !Number.isFinite(merged.memoryTotalBytes))
|
|
137955
138239
|
return;
|
|
137956
|
-
gpu.memoryTotalBytes =
|
|
137957
|
-
gpu.memoryUsedBytes =
|
|
138240
|
+
gpu.memoryTotalBytes = merged.memoryTotalBytes;
|
|
138241
|
+
gpu.memoryUsedBytes =
|
|
138242
|
+
merged.memoryUsedBytes !== null && Number.isFinite(merged.memoryUsedBytes)
|
|
138243
|
+
? merged.memoryUsedBytes
|
|
138244
|
+
: null;
|
|
137958
138245
|
gpu.memoryFreeBytes =
|
|
137959
|
-
|
|
137960
|
-
? Math.max(
|
|
138246
|
+
gpu.memoryUsedBytes !== null
|
|
138247
|
+
? Math.max(gpu.memoryTotalBytes - gpu.memoryUsedBytes, 0)
|
|
137961
138248
|
: null;
|
|
137962
138249
|
}
|
|
137963
138250
|
async function collectMachineMetadata({ logger }) {
|
|
@@ -137968,7 +138255,7 @@ async function collectMachineMetadata({ logger }) {
|
|
|
137968
138255
|
si.graphics(),
|
|
137969
138256
|
detectGPUsViaLspci(),
|
|
137970
138257
|
detectGPUsViaNvidiaSmi({ logger }),
|
|
137971
|
-
detectVRAMViaRocmSmi()
|
|
138258
|
+
detectVRAMViaRocmSmi({ logger })
|
|
137972
138259
|
]);
|
|
137973
138260
|
const cpuInfo = cpuResult.status === "fulfilled" ? cpuResult.value : null;
|
|
137974
138261
|
const memInfo = memResult.status === "fulfilled" ? memResult.value : null;
|
|
@@ -138023,6 +138310,7 @@ async function collectMachineMetadata({ logger }) {
|
|
|
138023
138310
|
nvidiaGPUs: resolvedNvidiaGPUs,
|
|
138024
138311
|
rocmVRAM: resolvedRocmVRAM,
|
|
138025
138312
|
siGPUs,
|
|
138313
|
+
systemTotalBytes: memInfo?.total ?? null,
|
|
138026
138314
|
sysfsVRAMMap
|
|
138027
138315
|
});
|
|
138028
138316
|
const machineMetadata = {
|
|
@@ -342696,12 +342984,13 @@ async function runModelFit(options) {
|
|
|
342696
342984
|
console.log();
|
|
342697
342985
|
const feasible = filterFeasibleModels({ detection, models: recommendedModels });
|
|
342698
342986
|
if (feasible.length === 0) {
|
|
342987
|
+
const smallestTierGB = Math.min(...recommendedModels.map(model => model.vramTierGB));
|
|
342699
342988
|
console.error("No recommended models fit this hardware. " +
|
|
342700
342989
|
`Budget: ${formatBytes$1(detection.gpus.some(gpu => gpu.memoryTotalBytes)
|
|
342701
342990
|
? Math.max(...detection.gpus
|
|
342702
342991
|
.map(gpu => gpu.memoryTotalBytes ?? 0)
|
|
342703
342992
|
.filter(bytes => bytes > 0))
|
|
342704
|
-
: detection.memory.totalBytes)}. Smallest tier starts at
|
|
342993
|
+
: detection.memory.totalBytes)}. Smallest tier starts at ${smallestTierGB} GB.`);
|
|
342705
342994
|
process.exitCode = 1;
|
|
342706
342995
|
return;
|
|
342707
342996
|
}
|
package/dist/cli.sea.cjs
CHANGED
|
@@ -21581,6 +21581,90 @@ object$5({
|
|
|
21581
21581
|
// Source of truth for curated recommended models. Consumed by @infersec/definitions
|
|
21582
21582
|
// and the website model page generator (applications/website/scripts/generate-model-pages.ts).
|
|
21583
21583
|
const modelsData = [
|
|
21584
|
+
{
|
|
21585
|
+
author: "LiquidAI",
|
|
21586
|
+
baseModel: "LiquidAI/LFM2.5-2.6B",
|
|
21587
|
+
blurb: "Liquid's LFM2.5 2.6B hybrid at high fidelity - agentic post-training, 128K context, and 220 tok/s decode on an M5 Max. Fits a 4 GB card with room to spare.",
|
|
21588
|
+
contextLength: 131072,
|
|
21589
|
+
fileSizeBytes: 2874779648,
|
|
21590
|
+
format: "gguf",
|
|
21591
|
+
license: "lfm1.0",
|
|
21592
|
+
parameterCount: "2.6B",
|
|
21593
|
+
quantization: "Q8_0",
|
|
21594
|
+
slug: "LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21595
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21596
|
+
vramTierGB: 4
|
|
21597
|
+
},
|
|
21598
|
+
{
|
|
21599
|
+
author: "LiquidAI",
|
|
21600
|
+
baseModel: "LiquidAI/LFM2.5-2.6B",
|
|
21601
|
+
blurb: "Liquid's LFM2.5 2.6B hybrid at 4-bit - competitive with models 4x its size on tool use and multi-step agentic tasks. A 1.7 GB download that sips memory.",
|
|
21602
|
+
contextLength: 131072,
|
|
21603
|
+
fileSizeBytes: 1674455040,
|
|
21604
|
+
format: "gguf",
|
|
21605
|
+
license: "lfm1.0",
|
|
21606
|
+
parameterCount: "2.6B",
|
|
21607
|
+
quantization: "Q4_K_M",
|
|
21608
|
+
slug: "LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21609
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-2.6B-GGUF",
|
|
21610
|
+
vramTierGB: 4
|
|
21611
|
+
},
|
|
21612
|
+
{
|
|
21613
|
+
author: "LiquidAI",
|
|
21614
|
+
baseModel: "LiquidAI/LFM2.5-2.6B",
|
|
21615
|
+
blurb: "The native BF16 checkpoint of Liquid's LFM2.5 2.6B for vLLM and SGLang - hybrid conv + GQA architecture, 128K context window, and agentic reinforcement-learning post-training.",
|
|
21616
|
+
contextLength: 131072,
|
|
21617
|
+
fileSizeBytes: 5394427456,
|
|
21618
|
+
format: "safetensors",
|
|
21619
|
+
license: "lfm1.0",
|
|
21620
|
+
parameterCount: "2.6B",
|
|
21621
|
+
quantization: "BF16",
|
|
21622
|
+
slug: "LiquidAI/LFM2.5-2.6B",
|
|
21623
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-2.6B",
|
|
21624
|
+
vramTierGB: 8
|
|
21625
|
+
},
|
|
21626
|
+
{
|
|
21627
|
+
author: "LiquidAI",
|
|
21628
|
+
baseModel: "LiquidAI/LFM2.5-230M",
|
|
21629
|
+
blurb: "Liquid's most compact LFM2.5 at high fidelity - a 230M edge model distilled from the 350M, tuned for tool use and data extraction. 213 tok/s decode on a Galaxy S25 Ultra.",
|
|
21630
|
+
contextLength: 32768,
|
|
21631
|
+
fileSizeBytes: 246598496,
|
|
21632
|
+
format: "gguf",
|
|
21633
|
+
license: "lfm1.0",
|
|
21634
|
+
parameterCount: "230M",
|
|
21635
|
+
quantization: "Q8_0",
|
|
21636
|
+
slug: "LiquidAI/LFM2.5-230M-GGUF",
|
|
21637
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-230M-GGUF",
|
|
21638
|
+
vramTierGB: 2
|
|
21639
|
+
},
|
|
21640
|
+
{
|
|
21641
|
+
author: "LiquidAI",
|
|
21642
|
+
baseModel: "LiquidAI/LFM2.5-230M",
|
|
21643
|
+
blurb: "Liquid's most compact LFM2.5 at 4-bit - a 153 MB download that brings real tool-use capability to the tightest memory budgets, from Raspberry Pi to phones.",
|
|
21644
|
+
contextLength: 32768,
|
|
21645
|
+
fileSizeBytes: 153406304,
|
|
21646
|
+
format: "gguf",
|
|
21647
|
+
license: "lfm1.0",
|
|
21648
|
+
parameterCount: "230M",
|
|
21649
|
+
quantization: "Q4_K_M",
|
|
21650
|
+
slug: "LiquidAI/LFM2.5-230M-GGUF",
|
|
21651
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-230M-GGUF",
|
|
21652
|
+
vramTierGB: 2
|
|
21653
|
+
},
|
|
21654
|
+
{
|
|
21655
|
+
author: "LiquidAI",
|
|
21656
|
+
baseModel: "LiquidAI/LFM2.5-230M",
|
|
21657
|
+
blurb: "The native BF16 checkpoint of Liquid's LFM2.5 230M for vLLM - a 230M edge model with a 32K context window, suited to data extraction and lightweight on-device agent pipelines.",
|
|
21658
|
+
contextLength: 32768,
|
|
21659
|
+
fileSizeBytes: 459401112,
|
|
21660
|
+
format: "safetensors",
|
|
21661
|
+
license: "lfm1.0",
|
|
21662
|
+
parameterCount: "230M",
|
|
21663
|
+
quantization: "BF16",
|
|
21664
|
+
slug: "LiquidAI/LFM2.5-230M",
|
|
21665
|
+
sourceURL: "https://huggingface.co/LiquidAI/LFM2.5-230M",
|
|
21666
|
+
vramTierGB: 4
|
|
21667
|
+
},
|
|
21584
21668
|
{
|
|
21585
21669
|
author: "Qwen",
|
|
21586
21670
|
baseModel: "Qwen/Qwen3-8B",
|
|
@@ -21637,6 +21721,48 @@ const modelsData = [
|
|
|
21637
21721
|
sourceURL: "https://huggingface.co/bartowski/deepreinforce-ai_Ornith-1.0-9B-GGUF",
|
|
21638
21722
|
vramTierGB: 16
|
|
21639
21723
|
},
|
|
21724
|
+
{
|
|
21725
|
+
author: "unsloth",
|
|
21726
|
+
baseModel: "nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16",
|
|
21727
|
+
blurb: "NVIDIA's Nemotron 3.5 Lightning MoE squeezed into 2-bit - 30B total with only 3B active in a Mamba-2 + MoE + attention hybrid. Configurable thinking and a 256K context on a single 24 GB card.",
|
|
21728
|
+
contextLength: 262144,
|
|
21729
|
+
fileSizeBytes: 19432070208,
|
|
21730
|
+
format: "gguf",
|
|
21731
|
+
license: "openmdw-1.1",
|
|
21732
|
+
parameterCount: "30B",
|
|
21733
|
+
quantization: "UD-IQ2_M",
|
|
21734
|
+
slug: "unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21735
|
+
sourceURL: "https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21736
|
+
vramTierGB: 24
|
|
21737
|
+
},
|
|
21738
|
+
{
|
|
21739
|
+
author: "unsloth",
|
|
21740
|
+
baseModel: "nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16",
|
|
21741
|
+
blurb: "NVIDIA's Nemotron 3.5 Lightning at Unsloth's dynamic 4-bit - a Mamba-2 hybrid MoE with 3B active parameters, toggleable reasoning, and strong instruction following (IFBench 71.9). Needs a 32 GB GPU.",
|
|
21742
|
+
contextLength: 262144,
|
|
21743
|
+
fileSizeBytes: 25266255936,
|
|
21744
|
+
format: "gguf",
|
|
21745
|
+
license: "openmdw-1.1",
|
|
21746
|
+
parameterCount: "30B",
|
|
21747
|
+
quantization: "UD-Q4_K_M",
|
|
21748
|
+
slug: "unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21749
|
+
sourceURL: "https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21750
|
+
vramTierGB: 32
|
|
21751
|
+
},
|
|
21752
|
+
{
|
|
21753
|
+
author: "unsloth",
|
|
21754
|
+
baseModel: "nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16",
|
|
21755
|
+
blurb: "Nemotron 3.5 Lightning at 8-bit fidelity - near-reference quality from the 30B-A3B Mamba-2 hybrid, with configurable thinking and DSpark speculative decoding support. Needs a 48 GB card.",
|
|
21756
|
+
contextLength: 262144,
|
|
21757
|
+
fileSizeBytes: 35004643392,
|
|
21758
|
+
format: "gguf",
|
|
21759
|
+
license: "openmdw-1.1",
|
|
21760
|
+
parameterCount: "30B",
|
|
21761
|
+
quantization: "Q8_0",
|
|
21762
|
+
slug: "unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21763
|
+
sourceURL: "https://huggingface.co/unsloth/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-GGUF",
|
|
21764
|
+
vramTierGB: 48
|
|
21765
|
+
},
|
|
21640
21766
|
{
|
|
21641
21767
|
author: "unsloth",
|
|
21642
21768
|
baseModel: "openai/gpt-oss-20b",
|
|
@@ -21695,6 +21821,76 @@ const modelsData = [
|
|
|
21695
21821
|
sourceURL: "https://huggingface.co/unsloth/Qwen3.8-Flash-Next-GGUF",
|
|
21696
21822
|
vramTierGB: 128
|
|
21697
21823
|
},
|
|
21824
|
+
{
|
|
21825
|
+
author: "Qwen",
|
|
21826
|
+
baseModel: "Qwen/Qwen3.8-Flash-Next",
|
|
21827
|
+
blurb: "The official BF16 release of Qwen's experimental Qwen4-preview architecture - 180B total with only 6B activated, plus 51B n-gram embeddings, a vision encoder, and a 262K native context. For vLLM/SGLang on multi-GPU server hardware.",
|
|
21828
|
+
contextLength: 262144,
|
|
21829
|
+
fileSizeBytes: 360000192888,
|
|
21830
|
+
format: "safetensors",
|
|
21831
|
+
license: "qwen-community-1.0",
|
|
21832
|
+
parameterCount: "180B",
|
|
21833
|
+
quantization: "BF16",
|
|
21834
|
+
slug: "Qwen/Qwen3.8-Flash-Next",
|
|
21835
|
+
sourceURL: "https://huggingface.co/Qwen/Qwen3.8-Flash-Next",
|
|
21836
|
+
vramTierGB: 640
|
|
21837
|
+
},
|
|
21838
|
+
{
|
|
21839
|
+
author: "RadixArk",
|
|
21840
|
+
baseModel: "Qwen/Qwen3.8-Flash-Next",
|
|
21841
|
+
blurb: "Qwen3.8-Flash-Next with its routed experts quantized to NVIDIA's NVFP4 W4A4 via Model Optimizer - 135 GB instead of 360 GB BF16, keeping GSM8K/AIME in-band with the reference. Serve with SGLang on Blackwell hardware.",
|
|
21842
|
+
contextLength: 262144,
|
|
21843
|
+
fileSizeBytes: 135195303851,
|
|
21844
|
+
format: "safetensors",
|
|
21845
|
+
license: "qwen-community-1.0",
|
|
21846
|
+
parameterCount: "180B",
|
|
21847
|
+
quantization: "NVFP4",
|
|
21848
|
+
slug: "RadixArk/Qwen3.8-Flash-Next-NVFP4",
|
|
21849
|
+
sourceURL: "https://huggingface.co/RadixArk/Qwen3.8-Flash-Next-NVFP4",
|
|
21850
|
+
vramTierGB: 256
|
|
21851
|
+
},
|
|
21852
|
+
{
|
|
21853
|
+
author: "deepseek-ai",
|
|
21854
|
+
baseModel: "deepseek-ai/DeepSeek-V4-Flash",
|
|
21855
|
+
blurb: "DeepSeek's V4-Flash - a 284B MoE with only 13B activated and a native 1M context window, shipped in mixed FP4/FP8 precision. Hybrid CSA/HCA attention keeps long-context inference cheap, with three reasoning-effort modes including Think Max.",
|
|
21856
|
+
contextLength: 1048576,
|
|
21857
|
+
fileSizeBytes: 159617149040,
|
|
21858
|
+
format: "safetensors",
|
|
21859
|
+
license: "mit",
|
|
21860
|
+
parameterCount: "284B",
|
|
21861
|
+
quantization: "FP4-FP8",
|
|
21862
|
+
slug: "deepseek-ai/DeepSeek-V4-Flash",
|
|
21863
|
+
sourceURL: "https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash",
|
|
21864
|
+
vramTierGB: 256
|
|
21865
|
+
},
|
|
21866
|
+
{
|
|
21867
|
+
author: "unsloth",
|
|
21868
|
+
baseModel: "deepseek-ai/DeepSeek-V4-Flash-Vision-Exp",
|
|
21869
|
+
blurb: "Unsloth's 2-bit cut of DeepSeek's experimental vision variant of V4-Flash - the same 284B MoE with 13B activated, plus image understanding via a separate mmproj projector. Fits 128 GB of unified memory or 2x 96 GB.",
|
|
21870
|
+
contextLength: 1048576,
|
|
21871
|
+
fileSizeBytes: 90692965818,
|
|
21872
|
+
format: "gguf",
|
|
21873
|
+
license: "mit",
|
|
21874
|
+
parameterCount: "284B",
|
|
21875
|
+
quantization: "UD-IQ2_XXS",
|
|
21876
|
+
slug: "unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21877
|
+
sourceURL: "https://huggingface.co/unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21878
|
+
vramTierGB: 128
|
|
21879
|
+
},
|
|
21880
|
+
{
|
|
21881
|
+
author: "unsloth",
|
|
21882
|
+
baseModel: "deepseek-ai/DeepSeek-V4-Flash-Vision-Exp",
|
|
21883
|
+
blurb: "The 4-bit cut of DeepSeek's experimental vision variant of V4-Flash - 284B MoE with 13B activated at higher fidelity, with multimodal agent scores well clear of the text-only release. Image input currently needs a preview llama.cpp build; needs 256 GB.",
|
|
21884
|
+
contextLength: 1048576,
|
|
21885
|
+
fileSizeBytes: 136662447706,
|
|
21886
|
+
format: "gguf",
|
|
21887
|
+
license: "mit",
|
|
21888
|
+
parameterCount: "284B",
|
|
21889
|
+
quantization: "UD-IQ4_XS",
|
|
21890
|
+
slug: "unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21891
|
+
sourceURL: "https://huggingface.co/unsloth/DeepSeek-V4-Flash-Vision-Exp-GGUF",
|
|
21892
|
+
vramTierGB: 256
|
|
21893
|
+
},
|
|
21698
21894
|
{
|
|
21699
21895
|
author: "unsloth",
|
|
21700
21896
|
baseModel: "Qwen/Qwen3.6-27B",
|
|
@@ -157969,12 +158165,20 @@ async function detectVRAMViaSysfs(pciBusSuffix) {
|
|
|
157969
158165
|
const deviceDir = path$1.join(DRM_PATH, entry, "device");
|
|
157970
158166
|
const totalStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_vram_total"));
|
|
157971
158167
|
const usedStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_vram_used"));
|
|
158168
|
+
const gttTotalStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_gtt_total"));
|
|
158169
|
+
const gttUsedStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_gtt_used"));
|
|
157972
158170
|
const totalBytes = totalStr !== null ? parseInt(totalStr, 10) : null;
|
|
157973
158171
|
const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
|
|
158172
|
+
const gttTotalBytes = gttTotalStr !== null ? parseInt(gttTotalStr, 10) : null;
|
|
158173
|
+
const gttUsedBytes = gttUsedStr !== null ? parseInt(gttUsedStr, 10) : null;
|
|
157974
158174
|
const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
|
|
157975
158175
|
const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
|
|
158176
|
+
const validGttTotal = gttTotalBytes !== null && Number.isFinite(gttTotalBytes) && gttTotalBytes >= 0;
|
|
158177
|
+
const validGttUsed = gttUsedBytes !== null && Number.isFinite(gttUsedBytes) && gttUsedBytes >= 0;
|
|
157976
158178
|
if (validTotal) {
|
|
157977
158179
|
return {
|
|
158180
|
+
gttTotalBytes: validGttTotal ? gttTotalBytes : null,
|
|
158181
|
+
gttUsedBytes: validGttUsed ? gttUsedBytes : null,
|
|
157978
158182
|
memoryTotalBytes: totalBytes,
|
|
157979
158183
|
memoryUsedBytes: validUsed ? usedBytes : null
|
|
157980
158184
|
};
|
|
@@ -157984,36 +158188,74 @@ async function detectVRAMViaSysfs(pciBusSuffix) {
|
|
|
157984
158188
|
catch {
|
|
157985
158189
|
// sysfs not available
|
|
157986
158190
|
}
|
|
157987
|
-
return {
|
|
158191
|
+
return {
|
|
158192
|
+
gttTotalBytes: null,
|
|
158193
|
+
gttUsedBytes: null,
|
|
158194
|
+
memoryTotalBytes: null,
|
|
158195
|
+
memoryUsedBytes: null
|
|
158196
|
+
};
|
|
157988
158197
|
}
|
|
157989
|
-
|
|
158198
|
+
// rocm-smi accepts a single --showmeminfo type per invocation, so VRAM and GTT
|
|
158199
|
+
// arrive from separate calls; both share this per-card parser.
|
|
158200
|
+
function parseRocmSmiMemory({ keyPrefix, stdout }) {
|
|
158201
|
+
const parsed = JSON.parse(stdout);
|
|
158202
|
+
const results = [];
|
|
158203
|
+
const cards = Object.entries(parsed).filter(([key]) => key.startsWith("card"));
|
|
158204
|
+
for (const [, data] of cards) {
|
|
158205
|
+
const bus = data["PCI Bus"] ?? null;
|
|
158206
|
+
const totalStr = data[`${keyPrefix} Total Memory (B)`] ?? null;
|
|
158207
|
+
const usedStr = data[`${keyPrefix} Total Used Memory (B)`] ?? null;
|
|
158208
|
+
const totalBytes = totalStr !== null ? parseInt(totalStr, 10) : null;
|
|
158209
|
+
const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
|
|
158210
|
+
const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
|
|
158211
|
+
const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
|
|
158212
|
+
if (bus) {
|
|
158213
|
+
results.push({
|
|
158214
|
+
bus,
|
|
158215
|
+
memoryTotalBytes: validTotal ? totalBytes : null,
|
|
158216
|
+
memoryUsedBytes: validUsed ? usedBytes : null
|
|
158217
|
+
});
|
|
158218
|
+
}
|
|
158219
|
+
}
|
|
158220
|
+
return results;
|
|
158221
|
+
}
|
|
158222
|
+
const ROCM_SMI_TIMEOUT_MS = 10_000;
|
|
158223
|
+
async function detectVRAMViaRocmSmi({ logger }) {
|
|
157990
158224
|
try {
|
|
157991
|
-
const
|
|
157992
|
-
"--showbus",
|
|
157993
|
-
|
|
157994
|
-
|
|
157995
|
-
"--json"
|
|
158225
|
+
const [vramResult, gttResult] = await Promise.allSettled([
|
|
158226
|
+
execa("rocm-smi", ["--showbus", "--showmeminfo", "vram", "--json"], {
|
|
158227
|
+
timeout: ROCM_SMI_TIMEOUT_MS
|
|
158228
|
+
}),
|
|
158229
|
+
execa("rocm-smi", ["--showbus", "--showmeminfo", "gtt", "--json"], {
|
|
158230
|
+
timeout: ROCM_SMI_TIMEOUT_MS
|
|
158231
|
+
})
|
|
157996
158232
|
]);
|
|
157997
|
-
|
|
157998
|
-
|
|
157999
|
-
|
|
158000
|
-
|
|
158001
|
-
|
|
158002
|
-
|
|
158003
|
-
|
|
158004
|
-
|
|
158005
|
-
const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
|
|
158006
|
-
const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
|
|
158007
|
-
const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
|
|
158008
|
-
if (bus) {
|
|
158009
|
-
results.push({
|
|
158010
|
-
bus,
|
|
158011
|
-
memoryTotalBytes: validTotal ? totalBytes : null,
|
|
158012
|
-
memoryUsedBytes: validUsed ? usedBytes : null
|
|
158233
|
+
if (vramResult.status !== "fulfilled")
|
|
158234
|
+
return [];
|
|
158235
|
+
let gttEntries = [];
|
|
158236
|
+
if (gttResult.status === "fulfilled") {
|
|
158237
|
+
try {
|
|
158238
|
+
gttEntries = parseRocmSmiMemory({
|
|
158239
|
+
keyPrefix: "GTT",
|
|
158240
|
+
stdout: gttResult.value.stdout
|
|
158013
158241
|
});
|
|
158014
158242
|
}
|
|
158243
|
+
catch (error) {
|
|
158244
|
+
// Unusable GTT output (e.g. older rocm-smi) degrades to VRAM-only
|
|
158245
|
+
logger.warn("rocm-smi GTT output parse failed", { error: asError(error) });
|
|
158246
|
+
}
|
|
158015
158247
|
}
|
|
158016
|
-
|
|
158248
|
+
const gttByBus = new Map(gttEntries.map(entry => [entry.bus, entry]));
|
|
158249
|
+
return parseRocmSmiMemory({ keyPrefix: "VRAM", stdout: vramResult.value.stdout }).map(vram => {
|
|
158250
|
+
const gtt = gttByBus.get(vram.bus);
|
|
158251
|
+
return {
|
|
158252
|
+
bus: vram.bus,
|
|
158253
|
+
gttTotalBytes: gtt?.memoryTotalBytes ?? null,
|
|
158254
|
+
gttUsedBytes: gtt?.memoryUsedBytes ?? null,
|
|
158255
|
+
memoryTotalBytes: vram.memoryTotalBytes,
|
|
158256
|
+
memoryUsedBytes: vram.memoryUsedBytes
|
|
158257
|
+
};
|
|
158258
|
+
});
|
|
158017
158259
|
}
|
|
158018
158260
|
catch {
|
|
158019
158261
|
return [];
|
|
@@ -158078,8 +158320,9 @@ async function detectGPUsViaNvidiaSmi({ logger }) {
|
|
|
158078
158320
|
vendor: "NVIDIA"
|
|
158079
158321
|
});
|
|
158080
158322
|
}
|
|
158081
|
-
//
|
|
158082
|
-
// memory. Their compute pool is system RAM, so fall back to
|
|
158323
|
+
// Shared/unified-memory devices (e.g. NVIDIA GB10 on DGX Spark) report
|
|
158324
|
+
// "[N/A]" for memory. Their compute pool is system RAM, so fall back to
|
|
158325
|
+
// /proc/meminfo. (AMD iGPUs get the same treatment via GTT merging.)
|
|
158083
158326
|
if (gpus.some(gpu => gpu.memoryTotalBytes === null)) {
|
|
158084
158327
|
const systemMemory = await readSystemMemoryBytes({ logger });
|
|
158085
158328
|
const total = systemMemory.totalBytes;
|
|
@@ -158103,7 +158346,7 @@ async function detectGPUsViaNvidiaSmi({ logger }) {
|
|
|
158103
158346
|
}
|
|
158104
158347
|
}
|
|
158105
158348
|
function buildMergedGPUs(options) {
|
|
158106
|
-
const { lspciGPUs, nvidiaGPUs, rocmVRAM, siGPUs, sysfsVRAMMap } = options;
|
|
158349
|
+
const { lspciGPUs, nvidiaGPUs, rocmVRAM, siGPUs, systemTotalBytes, sysfsVRAMMap } = options;
|
|
158107
158350
|
const rocmByBus = new Map();
|
|
158108
158351
|
for (const entry of rocmVRAM) {
|
|
158109
158352
|
const key = normalizeBusAddress(entry.bus);
|
|
@@ -158144,6 +158387,7 @@ function buildMergedGPUs(options) {
|
|
|
158144
158387
|
gpu: existing,
|
|
158145
158388
|
key,
|
|
158146
158389
|
rocmByBus,
|
|
158390
|
+
systemTotalBytes,
|
|
158147
158391
|
sysfsVRAMMap
|
|
158148
158392
|
});
|
|
158149
158393
|
}
|
|
@@ -158163,30 +158407,73 @@ function buildMergedGPUs(options) {
|
|
|
158163
158407
|
gpu,
|
|
158164
158408
|
key,
|
|
158165
158409
|
rocmByBus,
|
|
158410
|
+
systemTotalBytes,
|
|
158166
158411
|
sysfsVRAMMap
|
|
158167
158412
|
});
|
|
158168
158413
|
byBus.set(key, gpu);
|
|
158169
158414
|
}
|
|
158170
158415
|
return [...byBus.values()];
|
|
158171
158416
|
}
|
|
158172
|
-
|
|
158417
|
+
// Shared-memory GPUs (AMD iGPUs) expose a small dedicated VRAM carve-out via
|
|
158418
|
+
// mem_info_vram_total while the real usable pool - GTT - is carved dynamically
|
|
158419
|
+
// from system RAM. When GTT exceeds VRAM the device is treated as integrated
|
|
158420
|
+
// and the two pools combine (capped by installed RAM). Note that GTT defaults
|
|
158421
|
+
// to half of system RAM even on discrete GPUs, so a dGPU with less VRAM than
|
|
158422
|
+
// that also merges - acceptable, since GTT remains real addressable memory
|
|
158423
|
+
// for amdgpu compute (albeit slower over PCIe).
|
|
158424
|
+
function mergeGTTMemory({ gttTotalBytes, gttUsedBytes, systemTotalBytes, vramTotalBytes, vramUsedBytes }) {
|
|
158425
|
+
if (vramTotalBytes === null || !Number.isFinite(vramTotalBytes)) {
|
|
158426
|
+
return { memoryTotalBytes: null, memoryUsedBytes: null };
|
|
158427
|
+
}
|
|
158428
|
+
const isIntegrated = gttTotalBytes !== null && gttTotalBytes > vramTotalBytes;
|
|
158429
|
+
if (!isIntegrated) {
|
|
158430
|
+
return { memoryTotalBytes: vramTotalBytes, memoryUsedBytes: vramUsedBytes };
|
|
158431
|
+
}
|
|
158432
|
+
const combined = vramTotalBytes + gttTotalBytes;
|
|
158433
|
+
const capped = systemTotalBytes !== null && systemTotalBytes > 0
|
|
158434
|
+
? Math.min(combined, systemTotalBytes)
|
|
158435
|
+
: combined;
|
|
158436
|
+
const hasCompleteUsage = vramUsedBytes !== null &&
|
|
158437
|
+
Number.isFinite(vramUsedBytes) &&
|
|
158438
|
+
gttUsedBytes !== null &&
|
|
158439
|
+
Number.isFinite(gttUsedBytes);
|
|
158440
|
+
const memoryUsedBytes = hasCompleteUsage
|
|
158441
|
+
? Math.min(vramUsedBytes + gttUsedBytes, capped)
|
|
158442
|
+
: null;
|
|
158443
|
+
return { memoryTotalBytes: capped, memoryUsedBytes };
|
|
158444
|
+
}
|
|
158445
|
+
function applySysfsOrRocmVRAM({ gpu, key, rocmByBus, systemTotalBytes, sysfsVRAMMap }) {
|
|
158173
158446
|
const sysfs = sysfsVRAMMap.get(key);
|
|
158174
|
-
let
|
|
158175
|
-
let
|
|
158176
|
-
|
|
158447
|
+
let vramTotalBytes = sysfs?.memoryTotalBytes ?? null;
|
|
158448
|
+
let vramUsedBytes = sysfs?.memoryUsedBytes ?? null;
|
|
158449
|
+
let gttTotalBytes = sysfs?.gttTotalBytes ?? null;
|
|
158450
|
+
let gttUsedBytes = sysfs?.gttUsedBytes ?? null;
|
|
158451
|
+
if (vramTotalBytes === null) {
|
|
158177
158452
|
const rocm = rocmByBus.get(key);
|
|
158178
158453
|
if (rocm) {
|
|
158179
|
-
|
|
158180
|
-
|
|
158181
|
-
|
|
158182
|
-
|
|
158183
|
-
|
|
158454
|
+
vramTotalBytes = rocm.memoryTotalBytes;
|
|
158455
|
+
vramUsedBytes = rocm.memoryUsedBytes;
|
|
158456
|
+
gttTotalBytes = rocm.gttTotalBytes;
|
|
158457
|
+
gttUsedBytes = rocm.gttUsedBytes;
|
|
158458
|
+
}
|
|
158459
|
+
}
|
|
158460
|
+
const merged = mergeGTTMemory({
|
|
158461
|
+
gttTotalBytes,
|
|
158462
|
+
gttUsedBytes,
|
|
158463
|
+
systemTotalBytes,
|
|
158464
|
+
vramTotalBytes,
|
|
158465
|
+
vramUsedBytes
|
|
158466
|
+
});
|
|
158467
|
+
if (merged.memoryTotalBytes === null || !Number.isFinite(merged.memoryTotalBytes))
|
|
158184
158468
|
return;
|
|
158185
|
-
gpu.memoryTotalBytes =
|
|
158186
|
-
gpu.memoryUsedBytes =
|
|
158469
|
+
gpu.memoryTotalBytes = merged.memoryTotalBytes;
|
|
158470
|
+
gpu.memoryUsedBytes =
|
|
158471
|
+
merged.memoryUsedBytes !== null && Number.isFinite(merged.memoryUsedBytes)
|
|
158472
|
+
? merged.memoryUsedBytes
|
|
158473
|
+
: null;
|
|
158187
158474
|
gpu.memoryFreeBytes =
|
|
158188
|
-
|
|
158189
|
-
? Math.max(
|
|
158475
|
+
gpu.memoryUsedBytes !== null
|
|
158476
|
+
? Math.max(gpu.memoryTotalBytes - gpu.memoryUsedBytes, 0)
|
|
158190
158477
|
: null;
|
|
158191
158478
|
}
|
|
158192
158479
|
async function collectMachineMetadata({ logger }) {
|
|
@@ -158197,7 +158484,7 @@ async function collectMachineMetadata({ logger }) {
|
|
|
158197
158484
|
si.graphics(),
|
|
158198
158485
|
detectGPUsViaLspci(),
|
|
158199
158486
|
detectGPUsViaNvidiaSmi({ logger }),
|
|
158200
|
-
detectVRAMViaRocmSmi()
|
|
158487
|
+
detectVRAMViaRocmSmi({ logger })
|
|
158201
158488
|
]);
|
|
158202
158489
|
const cpuInfo = cpuResult.status === "fulfilled" ? cpuResult.value : null;
|
|
158203
158490
|
const memInfo = memResult.status === "fulfilled" ? memResult.value : null;
|
|
@@ -158252,6 +158539,7 @@ async function collectMachineMetadata({ logger }) {
|
|
|
158252
158539
|
nvidiaGPUs: resolvedNvidiaGPUs,
|
|
158253
158540
|
rocmVRAM: resolvedRocmVRAM,
|
|
158254
158541
|
siGPUs,
|
|
158542
|
+
systemTotalBytes: memInfo?.total ?? null,
|
|
158255
158543
|
sysfsVRAMMap
|
|
158256
158544
|
});
|
|
158257
158545
|
const machineMetadata = {
|
|
@@ -362925,12 +363213,13 @@ async function runModelFit(options) {
|
|
|
362925
363213
|
console.log();
|
|
362926
363214
|
const feasible = filterFeasibleModels({ detection, models: recommendedModels });
|
|
362927
363215
|
if (feasible.length === 0) {
|
|
363216
|
+
const smallestTierGB = Math.min(...recommendedModels.map(model => model.vramTierGB));
|
|
362928
363217
|
console.error("No recommended models fit this hardware. " +
|
|
362929
363218
|
`Budget: ${formatBytes$1(detection.gpus.some(gpu => gpu.memoryTotalBytes)
|
|
362930
363219
|
? Math.max(...detection.gpus
|
|
362931
363220
|
.map(gpu => gpu.memoryTotalBytes ?? 0)
|
|
362932
363221
|
.filter(bytes => bytes > 0))
|
|
362933
|
-
: detection.memory.totalBytes)}. Smallest tier starts at
|
|
363222
|
+
: detection.memory.totalBytes)}. Smallest tier starts at ${smallestTierGB} GB.`);
|
|
362934
363223
|
process.exitCode = 1;
|
|
362935
363224
|
return;
|
|
362936
363225
|
}
|
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import type { InferenceAgentMachineMetadata } from "@infersec/definitions";
|
|
2
2
|
import type { Logger } from "@infersec/logger";
|
|
3
3
|
export declare function normalizeBusAddress(bus: string | null | undefined): string | null;
|
|
4
|
+
export declare function parseRocmSmiMemory({ keyPrefix, stdout }: {
|
|
5
|
+
keyPrefix: "GTT" | "VRAM";
|
|
6
|
+
stdout: string;
|
|
7
|
+
}): Array<{
|
|
8
|
+
bus: string;
|
|
9
|
+
memoryTotalBytes: number | null;
|
|
10
|
+
memoryUsedBytes: number | null;
|
|
11
|
+
}>;
|
|
4
12
|
export declare function parseNvidiaSmiNumber(value: string | undefined): number | null;
|
|
5
13
|
export declare function parseNvidiaSmiMemoryBytes(value: string | undefined): number | null;
|
|
14
|
+
export declare function mergeGTTMemory({ gttTotalBytes, gttUsedBytes, systemTotalBytes, vramTotalBytes, vramUsedBytes }: {
|
|
15
|
+
gttTotalBytes: number | null;
|
|
16
|
+
gttUsedBytes: number | null;
|
|
17
|
+
systemTotalBytes: number | null;
|
|
18
|
+
vramTotalBytes: number | null;
|
|
19
|
+
vramUsedBytes: number | null;
|
|
20
|
+
}): {
|
|
21
|
+
memoryTotalBytes: number | null;
|
|
22
|
+
memoryUsedBytes: number | null;
|
|
23
|
+
};
|
|
6
24
|
export declare function collectMachineMetadata({ logger }: {
|
|
7
25
|
logger: Logger;
|
|
8
26
|
}): Promise<InferenceAgentMachineMetadata>;
|