# Hugging Face Model Research for Fleet Addition

## Core Principle: Do NOT Delegate Model Research to Subagents

Subagents (**delegate_task**) **hallucinate** HF model specs consistently:
- Wrong parameter counts (claimed 2.81B for a 35B model)
- Wrong architecture types (claimed `gptneox` for `qwen35moe`)
- Wrong repo names (claimed GGUF repo that returned 404)
- File sizes all report 0 (from xet storage) without resolving actual sizes
- Falsely claim quantization variants exist when they don't or vice versa

**Always research HF models directly** — curl/API calls to HF, not delegation.

## Method 1: Model Architecture & Params via config.json

```bash
# Get the raw config.json from the model's root
curl -s https://huggingface.co/<org>/<model>/raw/main/config.json
```

Key fields to check:
- `model_type` — tells you the architecture (e.g., `qwen3_5_moe`, `llama`, `gemma2`, `phi3`, `deepseek2`)
- `architectures` — Python class used by transformers
- `num_hidden_layers` — depth
- `hidden_size` — width
- `num_attention_heads` / `num_key_value_heads` — GQA ratio
- `num_experts` / `num_experts_per_tok` — MoE config (total experts vs active)
- `max_position_embeddings` — native context length
- `dtype` — precision (bf16/fp16)
- `text_config` — for multimodal models, the text MoE config is nested here
- `vision_config` — if present, model has vision encoder (needs mmproj for GGUF)

## Method 2: File Tree via HF API

```bash
# Get all sibling files with metadata
curl -s https://huggingface.co/api/models/<org>/<model>

# Parse with jq or Python to list files
curl -s https://huggingface.co/api/models/<org>/<model> | \
  python3 -c "import json,sys;d=json.load(sys.stdin);[print(s['rfilename']) for s in d.get('siblings',[])]"
```

## Method 3: Real GGUF File Sizes

HF's API reports 0 bytes for xet-stored files. The **real size** is in the `x-linked-size` HTTP header:

```bash
# Get REAL file size (not the 0 from API)
curl -sIL "https://huggingface.co/<org>/<model>/resolve/main/<filename>.gguf" 2>&1 | \
  grep -i x-linked-size
# Returns: x-linked-size: 21166757568
```

Use this to build a sizing table for VRAM budgeting:

```python
import subprocess, re

quant = 'Q4_K_M'
result = subprocess.run(
    ['curl', '-sIL', f'https://huggingface.co/bartowski/nex-agi_Nex-N2-mini-GGUF/resolve/main/nex-agi_Nex-N2-mini-Q4_K_M.gguf'],
    capture_output=True, text=True, timeout=15
)
for line in result.stdout.split('\n'):
    if 'x-linked-size:' in line.lower():
        size = int(line.split(':')[1].strip())
        print(f'{size / 1024**3:.2f} GB')  # e.g., 19.92 GB
```

## Method 4: Find Community GGUF Repos

The original model repo rarely has GGUF files. Search for community GGUF repos:

```bash
# Search HF API for GGUF variants of a model
curl -s "https://huggingface.co/api/models?search=<model-name>-gguf&sort=downloads&direction=-1&limit=10" | \
  python3 -c "import json,sys;d=json.load(sys.stdin);[print(f'{m[\"id\"]} ({m.get(\"downloads\",0):,} downs)') for m in d]"
```

Known community GGUF uploaders (check these orgs first):
- `bartowski/<model-name>-GGUF` — best variety (Q2_K through Q8_0, IQ quants), well-named files
- `s-batman/<model-name>-GGUF` — solid quants, sometimes has mmproj for multimodal
- `sjakek/<model-name>-GGUF` — UD (Uniform Decomposition) quants, mmproj files
- `eramax/<model-name>-gguf` — smaller selection
- `Chanito91/<model-name>-GGUF` — occasional options
- `hendrik289/<model-name>-Q8_0-GGUF` — Q8_0 specific

## VRAM Budgeting from Real File Sizes

For a model with file size `F` and setting `-ngl N` (layers on GPU):

```
Full GPU: VRAM = F + KV_cache + overhead (~500MB)
Partial offload: VRAM = F × (N / total_layers) + KV_cache + overhead
```

KV cache estimation:
```
KV_per_token = num_kv_heads × head_dim × num_hidden_layers × bytes_per_elem
- f16 KV: 2 bytes/elem
- turbo4 (q4_0): 0.5 bytes/elem
- q8_0: 1 byte/elem

For Qwen3.5 MoE (2 KV heads, 128 dim, 40 layers):
  turbo4: 2 × 128 × 40 × 0.5 = 5,120 bytes/token = 5 KB/token
  At 256K ctx: 1.3 GB
  
For a standard 8B llama (8 KV heads, 128 dim, 32 layers):
  turbo4: 8 × 128 × 32 × 0.5 = 16,384 bytes/token = 16 KB/token
  At 32K ctx: 512 MB
```

## Pitfalls

1. **Subagent hallucination is severe with HF data.** Verified in June 2026: a subagent claimed 2.81B total params / 1.51B active for a model that was actually 35B total / 3B active. It also got the architecture `gptneox` vs actual `qwen35moe`, and the GGUF repo 404'd. Never trust subagent model specs without verifying.
2. **HF non-API file sizes are 0 for xet repos.** The API response shows `"size": 0` for all files in repos using xet storage (increasingly common). Always resolve via `x-linked-size` HEAD header.
3. **Not every quantization actually exists.** Community uploaders list files in the API but may not have uploaded them all. The x-linked-size HEAD request is the best way to confirm.
4. **bnb/nf4 quants on HF are NOT the same as GGUF.** Don't confuse bitsandbytes 4-bit (safetensors, needs transformers) with GGUF Q4_K_M (llama.cpp compatible).
5. **Model card param counts are often wrong or refer to different variants.** Always calculate from config.json + file size.
