llm-checker 3.1.0

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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +418 -0
  3. package/analyzer/compatibility.js +584 -0
  4. package/analyzer/performance.js +505 -0
  5. package/bin/CLAUDE.md +12 -0
  6. package/bin/enhanced_cli.js +3118 -0
  7. package/bin/test-deterministic.js +41 -0
  8. package/package.json +96 -0
  9. package/src/CLAUDE.md +12 -0
  10. package/src/ai/intelligent-selector.js +615 -0
  11. package/src/ai/model-selector.js +312 -0
  12. package/src/ai/multi-objective-selector.js +820 -0
  13. package/src/commands/check.js +58 -0
  14. package/src/data/CLAUDE.md +11 -0
  15. package/src/data/model-database.js +637 -0
  16. package/src/data/sync-manager.js +279 -0
  17. package/src/hardware/CLAUDE.md +12 -0
  18. package/src/hardware/backends/CLAUDE.md +11 -0
  19. package/src/hardware/backends/apple-silicon.js +318 -0
  20. package/src/hardware/backends/cpu-detector.js +490 -0
  21. package/src/hardware/backends/cuda-detector.js +417 -0
  22. package/src/hardware/backends/intel-detector.js +436 -0
  23. package/src/hardware/backends/rocm-detector.js +440 -0
  24. package/src/hardware/detector.js +573 -0
  25. package/src/hardware/pc-optimizer.js +635 -0
  26. package/src/hardware/specs.js +286 -0
  27. package/src/hardware/unified-detector.js +442 -0
  28. package/src/index.js +2289 -0
  29. package/src/models/CLAUDE.md +17 -0
  30. package/src/models/ai-check-selector.js +806 -0
  31. package/src/models/catalog.json +426 -0
  32. package/src/models/deterministic-selector.js +1145 -0
  33. package/src/models/expanded_database.js +1142 -0
  34. package/src/models/intelligent-selector.js +532 -0
  35. package/src/models/requirements.js +310 -0
  36. package/src/models/scoring-config.js +57 -0
  37. package/src/models/scoring-engine.js +715 -0
  38. package/src/ollama/.cache/README.md +33 -0
  39. package/src/ollama/CLAUDE.md +24 -0
  40. package/src/ollama/client.js +438 -0
  41. package/src/ollama/enhanced-client.js +113 -0
  42. package/src/ollama/enhanced-scraper.js +634 -0
  43. package/src/ollama/manager.js +357 -0
  44. package/src/ollama/native-scraper.js +776 -0
  45. package/src/plugins/CLAUDE.md +11 -0
  46. package/src/plugins/examples/custom_model_plugin.js +87 -0
  47. package/src/plugins/index.js +295 -0
  48. package/src/utils/CLAUDE.md +11 -0
  49. package/src/utils/config.js +359 -0
  50. package/src/utils/formatter.js +315 -0
  51. package/src/utils/logger.js +272 -0
  52. package/src/utils/model-classifier.js +167 -0
  53. package/src/utils/verbose-progress.js +266 -0
@@ -0,0 +1,436 @@
1
+ /**
2
+ * Intel GPU Detector
3
+ * Detects Intel Arc (dedicated) and Iris/UHD (integrated) GPUs
4
+ * Uses intel_gpu_top, lspci, and sysfs
5
+ */
6
+
7
+ const { execSync } = require('child_process');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ class IntelDetector {
12
+ constructor() {
13
+ this.cache = null;
14
+ this.isAvailable = null;
15
+ }
16
+
17
+ /**
18
+ * Check if Intel GPU is available
19
+ */
20
+ checkAvailability() {
21
+ if (this.isAvailable !== null) {
22
+ return this.isAvailable;
23
+ }
24
+
25
+ // Only available on Linux (Windows detection handled by systeminformation)
26
+ if (process.platform !== 'linux') {
27
+ this.isAvailable = false;
28
+ return false;
29
+ }
30
+
31
+ try {
32
+ // Check for Intel GPU in lspci
33
+ const lspci = execSync('lspci | grep -i "VGA\\|3D\\|Display" | grep -i intel', {
34
+ encoding: 'utf8',
35
+ timeout: 5000,
36
+ stdio: ['pipe', 'pipe', 'pipe']
37
+ });
38
+ this.isAvailable = lspci.length > 0;
39
+ } catch (e) {
40
+ // Check sysfs for Intel render nodes
41
+ try {
42
+ const renderNodes = fs.readdirSync('/sys/class/drm');
43
+ this.isAvailable = renderNodes.some(node => {
44
+ try {
45
+ const vendor = fs.readFileSync(
46
+ `/sys/class/drm/${node}/device/vendor`,
47
+ 'utf8'
48
+ ).trim();
49
+ return vendor === '0x8086'; // Intel vendor ID
50
+ } catch (e) {
51
+ return false;
52
+ }
53
+ });
54
+ } catch (e2) {
55
+ this.isAvailable = false;
56
+ }
57
+ }
58
+
59
+ return this.isAvailable;
60
+ }
61
+
62
+ /**
63
+ * Detect Intel GPUs
64
+ */
65
+ detect() {
66
+ if (!this.checkAvailability()) {
67
+ return null;
68
+ }
69
+
70
+ if (this.cache) {
71
+ return this.cache;
72
+ }
73
+
74
+ try {
75
+ const info = this.getGPUInfo();
76
+ this.cache = info;
77
+ return info;
78
+ } catch (error) {
79
+ return null;
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Get detailed GPU information
85
+ */
86
+ getGPUInfo() {
87
+ const result = {
88
+ gpus: [],
89
+ totalVRAM: 0,
90
+ backend: 'sycl', // Intel uses oneAPI/SYCL for LLM
91
+ isMultiGPU: false,
92
+ hasDedicated: false,
93
+ speedCoefficient: 0
94
+ };
95
+
96
+ try {
97
+ // Parse lspci output for Intel GPUs
98
+ const lspci = execSync('lspci -v | grep -A 20 -i "VGA\\|3D\\|Display" | grep -i intel -A 20', {
99
+ encoding: 'utf8',
100
+ timeout: 10000
101
+ });
102
+
103
+ const gpuBlocks = lspci.split(/(?=\d{2}:\d{2}\.\d)/);
104
+
105
+ for (const block of gpuBlocks) {
106
+ if (!block.trim()) continue;
107
+
108
+ const nameMatch = block.match(/Intel.*?(Arc|Iris|UHD|HD Graphics)[^\n]*/i);
109
+ if (!nameMatch) continue;
110
+
111
+ const name = nameMatch[0].replace(/Corporation\s*/i, '').trim();
112
+ const isDedicated = name.toLowerCase().includes('arc');
113
+
114
+ // Get VRAM from sysfs or estimate
115
+ let vram = this.getVRAMFromSysfs(block) || this.estimateVRAM(name);
116
+
117
+ const gpu = {
118
+ index: result.gpus.length,
119
+ name: name,
120
+ type: isDedicated ? 'dedicated' : 'integrated',
121
+ memory: {
122
+ total: vram,
123
+ shared: isDedicated ? 0 : vram
124
+ },
125
+ capabilities: this.getGPUCapabilities(name),
126
+ speedCoefficient: this.calculateSpeedCoefficient(name, vram, isDedicated)
127
+ };
128
+
129
+ result.gpus.push(gpu);
130
+ if (isDedicated) {
131
+ result.totalVRAM += vram;
132
+ result.hasDedicated = true;
133
+ }
134
+ }
135
+ } catch (e) {
136
+ // Fallback: check sysfs directly
137
+ try {
138
+ const drmPath = '/sys/class/drm';
139
+ const cards = fs.readdirSync(drmPath).filter(f => f.startsWith('card') && !f.includes('-'));
140
+
141
+ for (const card of cards) {
142
+ const vendorPath = path.join(drmPath, card, 'device/vendor');
143
+ try {
144
+ const vendor = fs.readFileSync(vendorPath, 'utf8').trim();
145
+ if (vendor !== '0x8086') continue;
146
+
147
+ const devicePath = path.join(drmPath, card, 'device/device');
148
+ const deviceId = fs.readFileSync(devicePath, 'utf8').trim();
149
+
150
+ const gpuInfo = this.getGPUFromDeviceId(deviceId);
151
+ result.gpus.push({
152
+ index: result.gpus.length,
153
+ ...gpuInfo
154
+ });
155
+
156
+ if (gpuInfo.type === 'dedicated') {
157
+ result.totalVRAM += gpuInfo.memory.total;
158
+ result.hasDedicated = true;
159
+ }
160
+ } catch (e) {
161
+ continue;
162
+ }
163
+ }
164
+ } catch (e2) {
165
+ return null;
166
+ }
167
+ }
168
+
169
+ if (result.gpus.length === 0) {
170
+ return null;
171
+ }
172
+
173
+ result.isMultiGPU = result.gpus.filter(g => g.type === 'dedicated').length > 1;
174
+ result.speedCoefficient = result.gpus.length > 0
175
+ ? Math.max(...result.gpus.map(g => g.speedCoefficient))
176
+ : 0;
177
+
178
+ return result;
179
+ }
180
+
181
+ /**
182
+ * Get VRAM from sysfs
183
+ */
184
+ getVRAMFromSysfs(lspciBlock) {
185
+ // Look for memory region in lspci output
186
+ const memMatch = lspciBlock.match(/Memory.*?\[size=(\d+)(G|M)/i);
187
+ if (memMatch) {
188
+ const size = parseInt(memMatch[1]);
189
+ return memMatch[2].toUpperCase() === 'G' ? size : Math.round(size / 1024);
190
+ }
191
+ return null;
192
+ }
193
+
194
+ /**
195
+ * Estimate VRAM based on model name
196
+ */
197
+ estimateVRAM(name) {
198
+ const nameLower = (name || '').toLowerCase();
199
+
200
+ // Arc discrete GPUs
201
+ if (nameLower.includes('a770')) return 16;
202
+ if (nameLower.includes('a750')) return 8;
203
+ if (nameLower.includes('a580')) return 8;
204
+ if (nameLower.includes('a380')) return 6;
205
+ if (nameLower.includes('a310')) return 4;
206
+
207
+ // Arc Pro series
208
+ if (nameLower.includes('a60') || nameLower.includes('a50')) return 16;
209
+ if (nameLower.includes('a40')) return 12;
210
+ if (nameLower.includes('a30')) return 6;
211
+
212
+ // Integrated (shares system memory)
213
+ if (nameLower.includes('iris xe')) return 0; // Reports 0, uses system RAM
214
+ if (nameLower.includes('iris plus')) return 0;
215
+ if (nameLower.includes('uhd')) return 0;
216
+ if (nameLower.includes('hd graphics')) return 0;
217
+
218
+ return 0;
219
+ }
220
+
221
+ /**
222
+ * Get GPU info from device ID
223
+ */
224
+ getGPUFromDeviceId(deviceId) {
225
+ const id = deviceId.toLowerCase().replace('0x', '');
226
+
227
+ // Intel Arc discrete GPU device IDs
228
+ const arcGPUs = {
229
+ '56a0': { name: 'Intel Arc A770', vram: 16, dedicated: true },
230
+ '56a1': { name: 'Intel Arc A750', vram: 8, dedicated: true },
231
+ '56a5': { name: 'Intel Arc A580', vram: 8, dedicated: true },
232
+ '56a6': { name: 'Intel Arc A380', vram: 6, dedicated: true },
233
+ '5690': { name: 'Intel Arc A310', vram: 4, dedicated: true },
234
+ // Arc Pro
235
+ '56c0': { name: 'Intel Arc A60 Pro', vram: 16, dedicated: true },
236
+ '56c1': { name: 'Intel Arc A40 Pro', vram: 12, dedicated: true }
237
+ };
238
+
239
+ // Integrated GPU device IDs (partial list)
240
+ const iGPUs = {
241
+ '9a49': { name: 'Intel Iris Xe Graphics', vram: 0, dedicated: false },
242
+ '9a40': { name: 'Intel Iris Xe Graphics', vram: 0, dedicated: false },
243
+ '4626': { name: 'Intel Iris Xe Graphics (12th Gen)', vram: 0, dedicated: false },
244
+ '46a6': { name: 'Intel UHD Graphics (12th Gen)', vram: 0, dedicated: false },
245
+ 'a7a0': { name: 'Intel Iris Xe Graphics (13th Gen)', vram: 0, dedicated: false }
246
+ };
247
+
248
+ const gpuInfo = arcGPUs[id] || iGPUs[id] || {
249
+ name: `Intel GPU (${deviceId})`,
250
+ vram: 0,
251
+ dedicated: false
252
+ };
253
+
254
+ return {
255
+ name: gpuInfo.name,
256
+ type: gpuInfo.dedicated ? 'dedicated' : 'integrated',
257
+ memory: {
258
+ total: gpuInfo.vram,
259
+ shared: gpuInfo.dedicated ? 0 : gpuInfo.vram
260
+ },
261
+ capabilities: this.getGPUCapabilities(gpuInfo.name),
262
+ speedCoefficient: this.calculateSpeedCoefficient(gpuInfo.name, gpuInfo.vram, gpuInfo.dedicated)
263
+ };
264
+ }
265
+
266
+ /**
267
+ * Get GPU capabilities
268
+ */
269
+ getGPUCapabilities(name) {
270
+ const nameLower = (name || '').toLowerCase();
271
+
272
+ const capabilities = {
273
+ fp16: true,
274
+ bf16: false,
275
+ int8: true,
276
+ xmx: false, // Xe Matrix Extensions
277
+ architecture: 'Unknown',
278
+ xeVersion: null
279
+ };
280
+
281
+ // Arc GPUs (Alchemist - Xe HPG)
282
+ if (nameLower.includes('arc a7') || nameLower.includes('arc a5')) {
283
+ capabilities.bf16 = true;
284
+ capabilities.xmx = true;
285
+ capabilities.architecture = 'Xe HPG';
286
+ capabilities.xeVersion = 'Xe-HPG';
287
+ }
288
+ else if (nameLower.includes('arc a3')) {
289
+ capabilities.xmx = true;
290
+ capabilities.architecture = 'Xe HPG';
291
+ capabilities.xeVersion = 'Xe-HPG';
292
+ }
293
+ // Iris Xe (Xe LP)
294
+ else if (nameLower.includes('iris xe')) {
295
+ capabilities.architecture = 'Xe LP';
296
+ capabilities.xeVersion = 'Xe-LP';
297
+ }
298
+ // UHD/HD Graphics
299
+ else if (nameLower.includes('uhd') || nameLower.includes('hd graphics')) {
300
+ capabilities.architecture = 'Gen 12'
301
+ capabilities.xeVersion = 'Xe-LP';
302
+ }
303
+
304
+ return capabilities;
305
+ }
306
+
307
+ /**
308
+ * Calculate speed coefficient
309
+ */
310
+ calculateSpeedCoefficient(name, vramGB, isDedicated) {
311
+ const nameLower = (name || '').toLowerCase();
312
+
313
+ // Speed coefficients (tokens/sec per B params at Q4)
314
+ // Intel GPUs are generally slower than NVIDIA for LLM inference
315
+ const speedMap = {
316
+ // Arc discrete
317
+ 'a770': 120,
318
+ 'a750': 100,
319
+ 'a580': 80,
320
+ 'a380': 50,
321
+ 'a310': 35,
322
+ // Arc Pro
323
+ 'a60': 110,
324
+ 'a50': 90,
325
+ 'a40': 70,
326
+ 'a30': 45,
327
+ // Integrated
328
+ 'iris xe': 25,
329
+ 'iris plus': 15,
330
+ 'uhd': 12,
331
+ 'hd graphics': 8
332
+ };
333
+
334
+ for (const [model, speed] of Object.entries(speedMap)) {
335
+ if (nameLower.includes(model)) {
336
+ return speed;
337
+ }
338
+ }
339
+
340
+ // Estimate based on VRAM/type
341
+ if (isDedicated) {
342
+ if (vramGB >= 16) return 100;
343
+ if (vramGB >= 8) return 70;
344
+ if (vramGB >= 6) return 50;
345
+ return 30;
346
+ }
347
+
348
+ return 15; // Integrated default
349
+ }
350
+
351
+ /**
352
+ * Get primary GPU
353
+ */
354
+ getPrimaryGPU() {
355
+ const info = this.detect();
356
+ if (!info || info.gpus.length === 0) return null;
357
+
358
+ // Prefer dedicated over integrated
359
+ const dedicated = info.gpus.filter(g => g.type === 'dedicated');
360
+ if (dedicated.length > 0) {
361
+ return dedicated.reduce((best, gpu) => {
362
+ if (!best) return gpu;
363
+ if (gpu.memory.total > best.memory.total) return gpu;
364
+ return best;
365
+ }, null);
366
+ }
367
+
368
+ return info.gpus[0];
369
+ }
370
+
371
+ /**
372
+ * Get hardware fingerprint
373
+ */
374
+ getFingerprint() {
375
+ const info = this.detect();
376
+ if (!info || info.gpus.length === 0) return null;
377
+
378
+ const primary = this.getPrimaryGPU();
379
+ const gpuName = primary.name.toLowerCase()
380
+ .replace(/intel|graphics/gi, '')
381
+ .replace(/\s+/g, '-')
382
+ .trim();
383
+
384
+ return `intel-${gpuName}-${primary.memory.total || 'shared'}gb`;
385
+ }
386
+
387
+ /**
388
+ * Estimate inference speed
389
+ */
390
+ estimateTokensPerSecond(paramsB, quantization = 'Q4_K_M') {
391
+ const info = this.detect();
392
+ if (!info || info.gpus.length === 0) return 0;
393
+
394
+ const gpu = this.getPrimaryGPU();
395
+
396
+ // Intel GPUs have different quantization performance characteristics
397
+ const quantMult = {
398
+ 'FP16': 1.0,
399
+ 'Q8_0': 1.3,
400
+ 'Q6_K': 1.5,
401
+ 'Q5_K_M': 1.7,
402
+ 'Q5_0': 1.7,
403
+ 'Q4_K_M': 2.0,
404
+ 'Q4_0': 2.2,
405
+ 'Q3_K_M': 2.4,
406
+ 'Q2_K': 2.8,
407
+ 'IQ4_XS': 2.1,
408
+ 'IQ3_XXS': 2.5
409
+ };
410
+
411
+ const mult = quantMult[quantization] || 1.8;
412
+ const baseSpeed = gpu.speedCoefficient / paramsB * mult;
413
+
414
+ return Math.round(baseSpeed);
415
+ }
416
+
417
+ /**
418
+ * Check oneAPI/SYCL availability for LLM inference
419
+ */
420
+ checkOneAPISupport() {
421
+ try {
422
+ // Check for SYCL runtime
423
+ execSync('sycl-ls', {
424
+ encoding: 'utf8',
425
+ timeout: 5000,
426
+ stdio: ['pipe', 'pipe', 'pipe']
427
+ });
428
+ return true;
429
+ } catch (e) {
430
+ // Check for Intel oneAPI environment
431
+ return !!process.env.ONEAPI_ROOT || !!process.env.SYCL_DEVICE_FILTER;
432
+ }
433
+ }
434
+ }
435
+
436
+ module.exports = IntelDetector;