Instructions to use Shpigford/cron-mini with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use Shpigford/cron-mini with MLX:
# Make sure mlx-lm is installed # pip install --upgrade mlx-lm # Generate text with mlx-lm from mlx_lm import load, generate model, tokenizer = load("Shpigford/cron-mini") prompt = "Write a story about Einstein" messages = [{"role": "user", "content": prompt}] prompt = tokenizer.apply_chat_template( messages, add_generation_prompt=True ) text = generate(model, tokenizer, prompt=prompt, verbose=True) - Inference
- Notebooks
- Google Colab
- Kaggle
- Local Apps
- LM Studio
- Pi new
How to use Shpigford/cron-mini with Pi:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "Shpigford/cron-mini"
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "mlx-lm": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "Shpigford/cron-mini" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent new
How to use Shpigford/cron-mini with Hermes Agent:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "Shpigford/cron-mini"
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default Shpigford/cron-mini
Run Hermes
hermes
- MLX LM
How to use Shpigford/cron-mini with MLX LM:
Generate or start a chat session
# Install MLX LM uv tool install mlx-lm # Interactive chat REPL mlx_lm.chat --model "Shpigford/cron-mini"
Run an OpenAI-compatible server
# Install MLX LM uv tool install mlx-lm # Start the server mlx_lm.server --model "Shpigford/cron-mini" # Calling the OpenAI-compatible server with curl curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Shpigford/cron-mini", "messages": [ {"role": "user", "content": "Hello"} ] }'
| license: apache-2.0 | |
| language: | |
| - en | |
| library_name: mlx | |
| pipeline_tag: text-generation | |
| base_model: Qwen/Qwen2.5-1.5B-Instruct | |
| tags: | |
| - cron | |
| - systemd | |
| - devops | |
| - schedule | |
| - text-generation | |
| - mlx | |
| - lora | |
| datasets: | |
| - Shpigford/cron-schedule-conversion | |
| # Shpigford/cron-mini | |
| A small fine-tuned language model that converts natural-language schedules into cron expressions and systemd `OnCalendar` strings. | |
| ## What it does | |
| ``` | |
| Input: every Tuesday at 3am except December | |
| Output: {"cron": "0 3 * 1-11 2", | |
| "systemd": "Tue *-01..11-* 03:00:00", | |
| "note": "Months 1-11 only excludes December."} | |
| ``` | |
| It handles: | |
| - Standard schedules (daily, weekly, monthly, every N minutes/hours) | |
| - Holidays (Christmas, Thanksgiving, Black Friday, Halloween, etc.) | |
| - Casual time references ("lunchtime", "before bed", "first thing in the morning") | |
| - Ordinal weekdays ("second Tuesday of the month", "last Friday") | |
| - Negative specifications ("every day except Sunday", "all months except December") | |
| - Sub-minute intervals (cron can't, systemd can — model annotates the limitation) | |
| - Awkward intervals (every 90 minutes — cron can't, expanded across the day) | |
| - Compound schedules requiring multiple cron lines | |
| - systemd-specific features (`OnBootSec=`, `Persistent=`, `RandomizedDelaySec=`) | |
| - Time zones (sets `TZ=` for cron, uses `Asia/Tokyo`-style for systemd) | |
| - Typos and informal phrasings ("evry tues @ 3am") | |
| ## Usage | |
| ### MLX (Apple Silicon) | |
| ```python | |
| from mlx_lm import load, generate | |
| model, tokenizer = load("Shpigford/cron-mini") | |
| SYSTEM = ("You convert natural-language schedules into cron expressions and " | |
| "systemd OnCalendar strings. Output JSON with keys: cron, systemd, " | |
| "note. If cron cannot exactly express the schedule, put the closest " | |
| "valid cron and explain in note. Do not output anything else.") | |
| messages = [ | |
| {"role": "system", "content": SYSTEM}, | |
| {"role": "user", "content": "Convert this schedule to cron and systemd OnCalendar: every weekday at 9am"}, | |
| ] | |
| prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False) | |
| print(generate(model, tokenizer, prompt=prompt, max_tokens=200, temp=0.0)) | |
| ``` | |
| ### Transformers (any platform) | |
| ```python | |
| from transformers import AutoModelForCausalLM, AutoTokenizer | |
| model = AutoModelForCausalLM.from_pretrained("Shpigford/cron-mini", torch_dtype="auto", device_map="auto") | |
| tokenizer = AutoTokenizer.from_pretrained("Shpigford/cron-mini") | |
| SYSTEM = "..." # same as above | |
| messages = [ | |
| {"role": "system", "content": SYSTEM}, | |
| {"role": "user", "content": "Convert this schedule to cron and systemd OnCalendar: every weekday at 9am"}, | |
| ] | |
| inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device) | |
| out = model.generate(inputs, max_new_tokens=200, do_sample=False) | |
| print(tokenizer.decode(out[0][inputs.shape[1]:], skip_special_tokens=True)) | |
| ``` | |
| ### llama.cpp / Ollama (GGUF) | |
| A GGUF version is available — see the Files tab for `.gguf` files. Load with llama.cpp or import into Ollama: | |
| ```bash | |
| ollama create cron-mini -f Modelfile | |
| ``` | |
| ## Evaluation | |
| Held-out test set of 91 cases including all the trick categories above: | |
| - **Overall (cron+systemd both correct):** 63/91 (69.2%) | |
| - **Cron exact match:** 73/91 (80.2%) | |
| - **Cron syntactically valid:** 87/91 (95.6%) | |
| - **systemd exact match:** 71/91 (78.0%) | |
| See `eval_results.json` in this repo for per-case results. | |
| ## Training | |
| - **Base model:** `Qwen/Qwen2.5-1.5B-Instruct` (Apache 2.0) | |
| - **Method:** LoRA fine-tune via [mlx-lm](https://github.com/ml-explore/mlx-examples/tree/main/llms) | |
| - **Hardware:** M4 Mac mini, 16GB unified memory | |
| - **Dataset:** ~3000 examples — hand-crafted hard cases + templated generation + Claude-API paraphrases and synthetic novel cases (verified with a self-check pass) | |
| - **Dataset on HF:** [Shpigford/cron-schedule-conversion](https://huggingface.co/datasets/Shpigford/cron-schedule-conversion) | |
| ## Limitations | |
| - The model emits a single best-guess for ambiguous fuzzy times (e.g., "morning" → 7am). It will not ask clarifying questions. | |
| - For "every other Monday" / "biweekly" / "fortnightly" patterns, cron cannot express them natively — the model emits "every Monday" and notes the limitation. Gate in your script with a week-of-year check. | |
| - For "last day of month" / "last Friday", cron has no native expression — the model approximates with day-of-month ranges and flags the limitation. | |
| - Vixie cron OR-matches DOM and DOW when both are restricted; the model emits expressions that work under the more common AND-matching interpretation. Verify on your specific cron implementation. | |
| - Time zone handling: cron has no built-in TZ field; the model emits the schedule in the system's local time and notes when a `TZ=` env var is needed. | |
| - Trained on English. Other languages will likely degrade significantly. | |
| ## License | |
| Apache 2.0, same as the base model. | |
| ## Citation | |
| If you find this useful: | |
| ```bibtex | |
| @misc{cron-mini, | |
| author = {Pigford, Josh}, | |
| title = {Cron-Mini: A Small Model for Schedule Conversion}, | |
| year = {2026}, | |
| howpublished = {Hugging Face}, | |
| url = {https://huggingface.co/Shpigford/cron-mini} | |
| } | |
| ``` | |