Text Generation
Safetensors
GGUF
PyTorch
English
generic
custom
function-calling
tiny-model
edge-ai
tool-use
router
Instructions to use Safeeq/FCtiny with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use Safeeq/FCtiny with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf Safeeq/FCtiny # Run inference directly in the terminal: llama cli -hf Safeeq/FCtiny
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf Safeeq/FCtiny # Run inference directly in the terminal: llama cli -hf Safeeq/FCtiny
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf Safeeq/FCtiny # Run inference directly in the terminal: ./llama-cli -hf Safeeq/FCtiny
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf Safeeq/FCtiny # Run inference directly in the terminal: ./build/bin/llama-cli -hf Safeeq/FCtiny
Use Docker
docker model run hf.co/Safeeq/FCtiny
- LM Studio
- Jan
- vLLM
How to use Safeeq/FCtiny with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Safeeq/FCtiny" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Safeeq/FCtiny", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Safeeq/FCtiny
- Ollama
How to use Safeeq/FCtiny with Ollama:
ollama run hf.co/Safeeq/FCtiny
- Unsloth Desktop
- Docker Model Runner
How to use Safeeq/FCtiny with Docker Model Runner:
docker model run hf.co/Safeeq/FCtiny
- Lemonade
How to use Safeeq/FCtiny with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull Safeeq/FCtiny
Run and chat with the model
lemonade run user.FCtiny-{{QUANT_TAG}}List all available models
lemonade list
- Atomic Chat
|
Download README.md from Safeeq/FCtiny: direct link, hf CLI and curl.
- Browser
- Download file 10.8 kB
-
https://huggingface.co/Safeeq/FCtiny/resolve/main/README.md
- Command line
-
hf download hf://Safeeq/FCtiny/README.md
-
curl -L -o README.md https://huggingface.co/Safeeq/FCtiny/resolve/main/README.md
10.8 kB
| license: mit | |
| language: | |
| - en | |
| tags: | |
| - function-calling | |
| - tiny-model | |
| - edge-ai | |
| - tool-use | |
| - router | |
| - pytorch | |
| - gguf | |
| pipeline_tag: text-generation | |
| library_name: generic | |
| widget: | |
| - text: "weather in tokyo today" | |
| example_title: "Web Search Intent" | |
| - text: "tell me a joke" | |
| example_title: "Abstain (none)" | |
| - text: "who is marie curie" | |
| example_title: "Person Search" | |
| - text: "latest iphone 16 price in india" | |
| example_title: "Price Search" | |
| datasets: | |
| - Safeeq/FCtiny | |
| <div align="center"> | |
| # π TinyLM-FC β Tiny Function-Calling Router | |
| ### ~0.47M Parameters | CPU < 4ms | MIT License | |
| [](https://github.com/Safeeq008/tiny-fc-lm) | |
| [](https://opensource.org/licenses/MIT) | |
| [](https://www.python.org/) | |
| [](#architecture) | |
| [](#benchmarks) | |
| [](#gguf--ollama) | |
| </div> | |
| A **sub-half-million-parameter decoder-only transformer** trained completely from scratch to act as a lightweight, low-latency **function-calling router**. Given a user utterance, TinyLM decides whether to invoke an external tool (`web_search`) with structured arguments, or abstain (`none`) for chit-chat and greetings. | |
| Built as an educational and empirical case study: *how small can a specialized router be while still maintaining high precision?* | |
| --- | |
| ## π Quick Links | |
| | Resource | Link | | |
| | :--- | :--- | | |
| | π¦ **Full Source Code, Training & Eval Pipeline** | [github.com/Safeeq008/tiny-fc-lm](https://github.com/Safeeq008/tiny-fc-lm) | | |
| | π€ **Model Weights (this page)** | [huggingface.co/Safeeq/FCtiny](https://huggingface.co/Safeeq/FCtiny) | | |
| | π **Detailed README & Architecture Docs** | [README.md on GitHub](https://github.com/Safeeq008/tiny-fc-lm/blob/main/README.md) | | |
| | π³ **Docker Deployment** | [Dockerfile](https://github.com/Safeeq008/tiny-fc-lm/blob/main/Dockerfile) Β· [DEPLOY.md](https://github.com/Safeeq008/tiny-fc-lm/blob/main/DEPLOY.md) | | |
| | π¦ **Ollama / llama.cpp Guide** | [OLLAMA.md](https://github.com/Safeeq008/tiny-fc-lm/blob/main/OLLAMA.md) | | |
| --- | |
| ## π¦ Files in This Repository | |
| | File | Size | Description | | |
| | :--- | :--- | :--- | | |
| | `model.safetensors` | ~1.8 MB | PyTorch weights in safe zero-copy format | | |
| | `config.json` | ~1 KB | Architecture hyperparameters | | |
| | `tokenizer.json` | ~121 KB | Custom 2048-vocab ByteLevel BPE tokenizer | | |
| | `tinyfc.gguf` | ~1.0 MB | Quantized model for Ollama & llama.cpp | | |
| --- | |
| ## β‘ Quickstart | |
| ### Option A β Python (from this Hub) | |
| ```bash | |
| git clone https://github.com/Safeeq008/tiny-fc-lm.git | |
| cd tiny-fc-lm | |
| pip install -r requirements.txt | |
| python infer.py | |
| ``` | |
| ### Option B β GGUF via Ollama (zero-install inference) | |
| ```bash | |
| # Download the GGUF and Modelfile from GitHub | |
| curl -LO https://github.com/Safeeq008/tiny-fc-lm/raw/main/Modelfile | |
| # Pull the GGUF from Hugging Face and register it | |
| ollama pull hf.co/Safeeq/FCtiny:latest | |
| ollama run hf.co/Safeeq/FCtiny | |
| ``` | |
| Or using the local GGUF: | |
| ```bash | |
| # Download tinyfc.gguf from the Files tab above, then: | |
| ollama create tinyfc -f Modelfile | |
| ollama run tinyfc "weather in new york today" | |
| ``` | |
| ### Option C β FastAPI REST Server (from GitHub) | |
| ```bash | |
| git clone https://github.com/Safeeq008/tiny-fc-lm.git | |
| cd tiny-fc-lm && pip install -r requirements.txt | |
| python serve.py 8000 | |
| ``` | |
| - Web UI: `http://localhost:8000` | |
| - Swagger docs: `http://localhost:8000/docs` | |
| ### Option D β Docker | |
| ```bash | |
| docker pull ghcr.io/safeeq008/tiny-fc-lm:latest # or build locally: | |
| git clone https://github.com/Safeeq008/tiny-fc-lm.git | |
| docker build -t tiny-fc-lm . && docker run -p 8000:8000 tiny-fc-lm | |
| ``` | |
| --- | |
| ## π Python Inference (Manual) | |
| ```python | |
| import torch | |
| from safetensors.torch import load_file | |
| from tokenizers import Tokenizer | |
| # ββ Clone the repo for model.py ββ | |
| # git clone https://github.com/Safeeq008/tiny-fc-lm.git | |
| import sys; sys.path.insert(0, "tiny-fc-lm") | |
| from model import TinyLM | |
| # 1. Load weights + tokenizer (download from Files tab above) | |
| state_dict = load_file("model.safetensors") | |
| tok = Tokenizer.from_file("tokenizer.json") | |
| # 2. Instantiate model | |
| model = TinyLM(vocab=2048, d=80, n_layers=4, n_heads=4, ffn_mult=4, max_len=80) | |
| model.load_state_dict(state_dict) | |
| model.eval() | |
| # 3. Encode prompt with special tokens (<user>=1, <call>=2) | |
| user_input = "weather in chennai today" | |
| prompt_ids = [1] + tok.encode(user_input).ids + [2] | |
| # 4. Greedily decode | |
| with torch.no_grad(): | |
| ids = torch.tensor([prompt_ids]) | |
| for _ in range(30): | |
| logits = model(ids)[0] | |
| next_id = logits[0, -1].argmax().item() | |
| if next_id == 3: # <end> token | |
| break | |
| ids = torch.cat([ids, torch.tensor([[next_id]])], dim=-1) | |
| output_ids = ids[0, len(prompt_ids):].tolist() | |
| print(tok.decode(output_ids)) | |
| # β web_search|query=chennai weather today|recency=day | |
| # For full constrained decoding + live DuckDuckGo dispatch, see: | |
| # https://github.com/Safeeq008/tiny-fc-lm/blob/main/infer.py | |
| ``` | |
| --- | |
| ## π Architecture | |
| | Hyperparameter | Value | Notes | | |
| | :--- | :---: | :--- | | |
| | **Total Parameters** | 471,760 (~0.47M) | Trainable weight count | | |
| | **Layers** | 4 | Transformer decoder blocks | | |
| | **Hidden Dim** | 80 | Embedding & layer dimensionality | | |
| | **Attention Heads** | 4 | Head dim = 20 (even for RoPE) | | |
| | **Positional Encoding** | RoPE | ΞΈ = 10000.0 | | |
| | **Normalization** | RMSNorm | Ξ΅ = 1e-6, pre-norm | | |
| | **FFN** | GELU (4Γ width) | Hidden dim = 320 | | |
| | **Weight Tying** | β Yes | Input embeddings = output head | | |
| | **Vocabulary Size** | 2,048 | Custom ByteLevel BPE | | |
| | **Context Length** | 80 tokens | Max prompt + generation | | |
| --- | |
| ## π Benchmarks | |
| Evaluated on 2,000 in-distribution samples (`val.jsonl`), 1,000 held-out phrasing samples (`test_ood.jsonl`), and 1,000 domain-shift samples (`test_ood_domain.jsonl`): | |
| | Metric | Val (In-Distribution) | Phrasing OOD (Held-Out Phrasings) | Domain Shift OOD (Novel Entities & Global) | | |
| | :--- | :---: | :---: | :---: | | |
| | **Exact Match Accuracy** | **99.90%** | **82.90%** | **0.40%** *(entity vocabulary bounded)* | | |
| | **Routing Decision Accuracy** | **99.95%** | **89.50%** | **95.40%** | | |
| | **Routing Precision (Tool)** | **100.00%** | **89.15%** | **100.00%** | | |
| | **Routing Recall (Tool)** | **99.95%** | **99.40%** | **95.40%** | | |
| | **Query Slot Exact Match** | **99.90%** | **82.90%** | **0.40%** | | |
| | **Recency Slot Accuracy** | **99.90%** | **84.90%** | **54.60%** | | |
| | **Syntactic Validity Rate** | **100.0%** | **99.80%** | **99.30%** | | |
| | **CPU Inference Latency** | **~23.8 ms** | **~24.0 ms** | **~27.8 ms** | | |
| ### Per-Intent Performance (Phrasing OOD) | |
| Key utility intents have been fortified against phrasing shifts and temporal ambiguity: | |
| | Intent Category | Val Exact % | OOD Exact % | OOD Routing % | Status | | |
| | :--- | :---: | :---: | :---: | :--- | | |
| | **How-to / Guides** | 100.0% | **100.0%** | 100.0% | **Resolved (was 86.4%)** | | |
| | **Sports Scores** | 100.0% | **100.0%** | 100.0% | **Resolved (was 88.5%)** | | |
| | **Product Prices** | 100.0% | **96.2%** | 100.0% | **Resolved (was 84.8%)** | | |
| | **General Concept** | 100.0% | **98.8%** | 98.8% | High fidelity | | |
| | **Weather** | 99.4% | **97.4%** | 100.0% | High fidelity | | |
| | **Stock Quotes** | 100.0% | **96.2%** | 100.0% | High fidelity | | |
| | **Web Search** | 100.0% | **100.0%** | 100.0% | High fidelity | | |
| | **Weekly Recap** | 100.0% | **80.3%** | 100.0% | 100% routing fidelity | | |
| | **News** | 99.7% | **56.4%** | 97.0% | 97% routing fidelity | | |
| | **Chit-Chat (Abstain)** | 100.0% | **41.0%** | 42.2% | Abstract banter vs tool call | | |
| --- | |
| ## π Output Protocol | |
| TinyLM outputs a strict, pipe-delimited schema: | |
| ``` | |
| web_search|query=<search query>|recency=<day|week|any> | |
| none | |
| ``` | |
| **Examples:** | |
| | User Input | Model Output | | |
| | :--- | :--- | | |
| | `weather in tokyo today` | `web_search\|query=tokyo weather today\|recency=day` | | |
| | `latest AI news` | `web_search\|query=latest ai news\|recency=day` | | |
| | `iphone 16 price in india` | `web_search\|query=iphone 16 price india\|recency=week` | | |
| | `hi how are you` | `none` | | |
| | `tell me a joke` | `none` | | |
| | `what is 2 + 2` | `none` | | |
| --- | |
| ## π¦ GGUF & Ollama | |
| A `tinyfc.gguf` artifact (~1.09 MB, fp16) is available in the **Files** tab above. This is a canonical Llama-architecture twin (~512k params, SwiGLU MLP) trained on the same task and tokenizer, exported for llama.cpp-compatible runtimes. | |
| **Quick usage:** | |
| ```bash | |
| # Download tinyfc.gguf from the Files tab, then: | |
| ollama create tinyfc -f Modelfile | |
| ollama run tinyfc "latest ethereum price" | |
| # β web_search|query=ethereum price today|recency=day | |
| ``` | |
| See the full guide in [OLLAMA.md](https://github.com/Safeeq008/tiny-fc-lm/blob/main/OLLAMA.md). | |
| --- | |
| ## ποΈ Reproduce from Scratch | |
| Full pipeline available at [github.com/Safeeq008/tiny-fc-lm](https://github.com/Safeeq008/tiny-fc-lm): | |
| ```bash | |
| git clone https://github.com/Safeeq008/tiny-fc-lm.git | |
| cd tiny-fc-lm && pip install -r requirements.txt | |
| python gen_data.py # 1. Generate 80k synthetic training samples (train, val, phrasing OOD, domain OOD) | |
| python train_tok.py # 2. Train custom 2048-vocab BPE tokenizer | |
| python train.py # 3. Train TinyLM-FC model (~5-10 min, CPU) | |
| python eval.py # 4. Full benchmark suite across all splits | |
| python infer.py # 5. Interactive CLI with live DuckDuckGo search | |
| python serve.py 8000 # 6. FastAPI server + web UI | |
| # Optional: GGUF/Ollama path | |
| python train_llama.py # 7. Train Llama-arch twin | |
| python export_gguf.py # 8. Convert to GGUF | |
| ollama create tinyfc -f Modelfile && ollama run tinyfc | |
| ``` | |
| --- | |
| ## β οΈ Known Limitations | |
| 1. **Single-tool**: Strictly routes `web_search` only β no multi-tool schemas. | |
| 2. **English only**: Custom BPE tokenizer trained on English synthetic corpus. | |
| 3. **80-token context window**: Inputs > ~60 user tokens are silently truncated. | |
| 4. **Synthetic training data & domain shift boundary**: Real-world query distributions are far noisier. While **tool routing transfers at 95.40%** to novel domains and unobserved tasks, **exact entity string extraction is bounded by the 0.47M parameter vocabulary** for unseen entities. | |
| 5. **Constrained decoding required**: Raw greedy decoding may produce malformed outputs; use `infer.py`'s constrained decoder for production. | |
| --- | |
| ## π License | |
| Released under the **MIT License** β free for research, benchmarking, commercial use, and edge deployment. | |
| **Repository:** [github.com/Safeeq008/tiny-fc-lm](https://github.com/Safeeq008/tiny-fc-lm) | |