File size: 5,675 Bytes
b043f30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import gradio as gr
import json

def generate_model_card(model_id: str, base_model: str = "", quantization: str = "Q4_K_M", 
                       params: str = "", task: str = "Text Generation", phone_tested: bool = True,
                       tokens_per_sec: float = 0.0, ram_mb: int = 0, file_size_mb: int = 0) -> str:
    """Generate a HuggingFace model card (README.md) for a mobile-optimized model.
    
    Use this tool when you need to create or update a model card for a dispatchAI
    mobile model. Produces properly formatted markdown with YAML frontmatter,
    benchmark results, and usage examples.
    
    Args:
        model_id: The HuggingFace repo ID (e.g., "dispatchAI/MyModel-mobile")
        base_model: The original/base model name (e.g., "Qwen/Qwen2.5-0.5B-Instruct")
        quantization: Quantization method used (Q4_K_M, Q5_K_M, Q8_0, INT4, FP16)
        params: Parameter count as string (e.g., "500M", "1B", "3B")
        task: Primary task (Text Generation, Code Generation, etc.)
        phone_tested: Whether the model was tested on real phone hardware
        tokens_per_sec: Measured tokens/sec on Snapdragon 865 (0 if untested)
        ram_mb: RAM required in MB
        file_size_mb: Model file size in MB
    
    Returns:
        JSON string with the generated model card markdown
    """
    org_name = model_id.split("/")[0] if "/" in model_id else "dispatchAI"
    model_name = model_id.split("/")[-1] if "/" in model_id else model_id
    
    tags = ["mobile", "on-device", "quantized", quantization.lower(), "dispatchai"]
    if task == "Code Generation":
        tags.extend(["code", "coder"])
    elif "arabic" in model_name.lower():
        tags.extend(["arabic", "multilingual"])
    elif "function" in model_name.lower():
        tags.extend(["function-calling", "agent"])
    elif "vision" in model_name.lower():
        tags.extend(["vision", "multimodal"])
    
    card = f"""---
license: apache-2.0
language:
  - en
library_name: transformers
tags:
{chr(10).join(f"  - {t}" for t in tags)}
pipeline_tag: {task.lower().replace(" ", "-") if " " in task else task}
---

# {model_name}

{("Mobile-optimized version of " + base_model) if base_model else "A mobile-optimized language model"} β€” quantized to {quantization}, designed to run on phones and edge devices.

## Model Details

| Attribute | Value |
|-----------|-------|
| **Base Model** | {base_model or "N/A"} |
| **Parameters** | {params or "Unknown"} |
| **Quantization** | {quantization} |
| **File Size** | {file_size_mb} MB |
| **RAM Required** | {ram_mb} MB |
| **Task** | {task} |
| **License** | Apache-2.0 |
| **Organization** | [{org_name}](https://huggingface.co/{org_name}) |

## Mobile Performance

{"βœ… **Tested on real hardware**" if phone_tested else "⚠️ Not yet tested on phone hardware"}

| Hardware | Tokens/sec | RAM Usage | Status |
|----------|-----------|-----------|--------|
| Snapdragon 865 (S20 FE) | {tokens_per_sec} t/s | {ram_mb} MB | {"βœ… Pass" if tokens_per_sec > 2 else "❌ Fail" if phone_tested else "⏳ Pending"} |

## Usage

### Python (transformers)

```python
from transformers import AutoTokenizer, AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("{model_id}")
tokenizer = AutoTokenizer.from_pretrained("{model_id}")

messages = [{{"role": "user", "content": "Hello!"}}]
input_text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(input_text, return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))
```

### llama.cpp (GGUF)

```bash
# Download
hf download {model_id} model.gguf

# Run on phone/desktop
llama-cli -m model.gguf -p "Hello!" -n 100 -t 4
```

## Quantization Details

This model uses **{quantization}** quantization:

- File size: {file_size_mb} MB ({round(file_size_mb / 1024, 2)} GB)
- Quality retention: ~92% of FP16
- Optimized for: Mobile and edge devices with < 4GB RAM

## About dispatchAI

[dispatchAI](https://huggingface.co/dispatchAI) re-engineers open-source LLMs for mobile and edge devices. Every model is tested on real Snapdragon hardware.

**Small. Mobile. Free. UAE-built.**

---

*I think, therefore I ship.*
"""
    
    return json.dumps({
        "model_id": model_id,
        "card_content": card,
        "tags": tags,
        "instructions": f"Upload this as README.md to {model_id} repo"
    }, indent=2)

with gr.Blocks(title="dispatchAI Model Card Writer MCP") as demo:
    gr.Markdown("## πŸ“ dispatchAI Model Card Writer (MCP Tool)")
    
    with gr.Row():
        mid = gr.Textbox(label="Model ID", placeholder="dispatchAI/MyModel-mobile")
        base = gr.Textbox(label="Base Model", placeholder="Qwen/Qwen2.5-0.5B-Instruct")
    
    with gr.Row():
        quant = gr.Dropdown(["FP16", "INT4", "Q4_K_M", "Q5_K_M", "Q6_K", "Q8_0"], value="Q4_K_M", label="Quantization")
        params = gr.Textbox(label="Params", placeholder="500M, 1B, 3B...")
        task = gr.Dropdown(["Text Generation", "Code Generation", "Function Calling", "Image-to-Text"], value="Text Generation", label="Task")
    
    with gr.Row():
        tested = gr.Checkbox(value=True, label="Phone Tested")
        tps = gr.Number(value=18.0, label="Tokens/sec (Snapdragon 865)")
        ram = gr.Number(value=1100, label="RAM (MB)")
        size = gr.Number(value=700, label="File Size (MB)")
    
    btn = gr.Button("Generate Model Card", variant="primary")
    out = gr.Textbox(label="Generated Card (JSON)", lines=25)
    btn.click(fn=generate_model_card, inputs=[mid, base, quant, params, task, tested, tps, ram, size], outputs=out)

demo.launch(mcp_server=True)