Modal Dojo
"# Modal Dojo\n\nModal Dojo is an open-source library to get started with production-grade LLM training on [Modal](https://modal.com).\n\nTo get started, you can go through the [Quickstart](#quickstart) section below, or paste the prompt below into your favorite agent:\n\n```txt\nInstall the `modal-dojo` library. Then, install the skill bundle into the local project with `modal-dojo skills install`. Finally, tell the user that they can ask you to do something like: \"Walk through tutorials/rl_basics.py and train Qwen3.5-4B to write 5-7-5 haikus from statworx/haiku.\"\n```\n\n## Quickstart\n\nRequirements:\n\n- Python 3.12\n\nInstall the package directly:\n\n```bash\nuv pip install -q git+https://github.com/modal-projects/modal-dojo.git@main\n```\n\nOr pin it in `pyproject.toml`:\n\n```toml\nmodal-dojo = { git = \"https://github.com/modal-projects/modal-dojo.git\", branch = \"main\" }\n```\n\nSet up [Modal](https://modal.com/docs/cli/latest/setup) and the [dashboard](https://dojo.modal.dev/guides/dashboard):\n\n```bash\nmodal-dojo setup\n```\n\n<div class=\"tg-dashboard-previews\">\n <video autoplay muted loop playsinline width=\"100%\">\n <source src=\"https://modal-cdn.com/cdnbot/substep1_a17bacdc.webm\" type=\"video/webm\">\n <a href=\"https://modal-cdn.com/cdnbot/substep1_a17bacdc.webm\">Watch the Modal Dojo dashboard substep view.</a>\n </video>\n <video autoplay muted loop playsinline width=\"100%\">\n <source src=\"https://modal-cdn.com/cdnbot/rollout1_15a56ce1.webm\" type=\"video/webm\">\n <a href=\"https://modal-cdn.com/cdnbot/rollout1_15a56ce1.webm\">Watch the Modal Dojo dashboard rollout view.</a>\n </video>\n</div>\n\nAnd empower your agents with the Modal Dojo's skill bundle:\n\n```bash\nmodal-dojo skills install\n```\n\nThen, it's as easy as:\n\n<!-- BEGIN QUICKSTART -->\n```python\nimport re\n\nfrom modal_dojo import (\n HuggingFaceDataset,\n Qwen3_5_4B,\n Qwen3_5_4B_Recipe,\n TrainConfig,\n)\n\nmodel = Qwen3_5_4B()\n\n\nasync def gsm8k_rm(args, sample, **kwargs) -> float:\n text = model.parse_response(sample.response or \"\").content\n boxed = re.findall(r\"\\\\boxed\\{([^}]+)\\}\", text)\n pred = boxed[-1] if boxed else (re.findall(r\"-?[\\d,]+(?:\\.\\d+)?\", text) or [\"\"])[-1]\n try:\n return float(float(pred.replace(\",\", \"\")) == float(sample.label))\n except ValueError:\n return 0.0\n\n\nconfig = TrainConfig(\n model=model,\n dataset=HuggingFaceDataset(\n hf_repo=\"skrishna/gsm8k_only_answer\",\n hf_split=\"train[:120]\",\n input_column=\"text\",\n output_column=\"label\",\n input_format=\"text\",\n ),\n recipe=Qwen3_5_4B_Recipe(\n custom_rm_function=gsm8k_rm,\n ),\n)\n\nif __name__ == \"__main__\":\n run = config.launch()\n print(run.training_run_id)\n```\n<!-- END QUICKSTART -->\n\nFor a step-by-step walkthrough, see the [Getting started tutorial](https://dojo.modal.dev/tutorials/rl_basics).\n\n## Supported models\n\n<!-- BEGIN MODELS LIST -->\n<!-- Auto-generated by scripts/generate_models_table.py from the recipe registries in modal_dojo/train_recipes/*/__init__.py. -->\n\n| Family | Models |\n|---|---|\n| DeepSeek | <ul><li>[DeepSeek-V4.1-Flash](https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash)</li></ul> |\n| GLM | <ul><li>[GLM-4.7](https://huggingface.co/zai-org/GLM-4.7)</li><li>[GLM-5.3-Flash](https://huggingface.co/zai-org/GLM-5.3-Flash)</li></ul> |\n| Gemma | <ul><li>[gemma-4-26B-A4B-it](https://huggingface.co/google/gemma-4-26B-A4B-it)</li></ul> |\n| Inkling | <ul><li>[Inkling-Small](https://huggingface.co/thinkingmachines/Inkling-Small)</li></ul> |\n| Kimi | <ul><li>[Kimi-K3](https://huggingface.co/moonshotai/Kimi-K3)</li></ul> |\n| Moonlight | <ul><li>[Moonlight-16B-A3B-Instruct](https://huggingface.co/moonshotai/Moonlight-16B-A3B-Instruct)</li></ul> |\n| Qwen3 | <ul><li>[Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B)</li><li>[Qwen3-1.7B](https://huggingface.co/Qwen/Qwen3-1.7B)</li><li>[Qwen3-4B](https://huggingface.co/Qwen/Qwen3-4B)</li><li>[Qwen3-8B](https://huggingface.co/Qwen/Qwen3-8B)</li><li>[Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B)</li><li>[Qwen3-VL-8B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct)</li></ul> |\n| Qwen3.5 | <ul><li>[Qwen3.5-0.8B](https://huggingface.co/Qwen/Qwen3.5-0.8B)</li><li>[Qwen3.5-2B](https://huggingface.co/Qwen/Qwen3.5-2B)</li><li>[Qwen3.5-4B](https://huggingface.co/Qwen/Qwen3.5-4B)</li><li>[Qwen3.5-9B](https://huggingface.co/Qwen/Qwen3.5-9B)</li></ul> |\n| Qwen3.6 | <ul><li>[Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B)</li><li>[Qwen3.6-35B-A3B](https://huggingface.co/Qwen/Qwen3.6-35B-A3B)</li></ul> |\n| Qwen3.8 | <ul><li>[Qwen3.8-27B](https://huggingface.co/Qwen/Qwen3.8-27B)</li></ul> |\n<!-- END MODELS LIST -->\n"
Modal Dojo is an open-source library to get started with production-grade LLM training on Modal.
To get started, you can go through the Quickstart section below, or paste the prompt below into your favorite agent:
Install the `modal-dojo` library. Then, install the skill bundle into the local project with `modal-dojo skills install`. Finally, tell the user that they can ask you to do something like: "Walk through tutorials/rl_basics.py and train Qwen3.5-4B to write 5-7-5 haikus from statworx/haiku."Quickstart
Section titled “Quickstart”Requirements:
- Python 3.12
Install the package directly:
uv pip install -q git+https://github.com/modal-projects/modal-dojo.git@mainOr pin it in pyproject.toml:
modal-dojo = { git = "https://github.com/modal-projects/modal-dojo.git", branch = "main" }Set up Modal and the dashboard:
modal-dojo setupAnd empower your agents with the Modal Dojo’s skill bundle:
modal-dojo skills installThen, it’s as easy as:
import re
from modal_dojo import ( HuggingFaceDataset, Qwen3_5_4B, Qwen3_5_4B_Recipe, TrainConfig,)
model = Qwen3_5_4B()
async def gsm8k_rm(args, sample, **kwargs) -> float: text = model.parse_response(sample.response or "").content boxed = re.findall(r"\\boxed\{([^}]+)\}", text) pred = boxed[-1] if boxed else (re.findall(r"-?[\d,]+(?:\.\d+)?", text) or [""])[-1] try: return float(float(pred.replace(",", "")) == float(sample.label)) except ValueError: return 0.0
config = TrainConfig( model=model, dataset=HuggingFaceDataset( hf_repo="skrishna/gsm8k_only_answer", hf_split="train[:120]", input_column="text", output_column="label", input_format="text", ), recipe=Qwen3_5_4B_Recipe( custom_rm_function=gsm8k_rm, ),)
if __name__ == "__main__": run = config.launch() print(run.training_run_id)For a step-by-step walkthrough, see the Getting started tutorial.
Supported models
Section titled “Supported models”| Family | Models |
|---|---|
| DeepSeek | |
| GLM | |
| Gemma | |
| Inkling | |
| Kimi | |
| Moonlight | |
| Qwen3 | |
| Qwen3.5 | |
| Qwen3.6 | |
| Qwen3.8 |