# How to Fine-Tune a Small Language Model Without Writing a Single Line of Python Code on Modal Cloud

> Source: <https://pub.towardsai.net/how-to-fine-tune-a-small-language-model-without-writing-a-single-line-of-python-code-on-modal-cloud-aba98bd0220d?source=rss----98111c9905da---4>
> Published: 2026-09-17 06:08:06+00:00

This is a short article that demonstrates how to fine-tune a small language model without writing a single line of Python code. The fine-tuning job is dispatched on the Modal Cloud platform and uses a **T4 GPU.** The fine-tuned adapters are then pushed to Hugging Face, and metrics are pushed to **W&B**. We use a library called [** TRLoom**](https://github.com/saqlain2204/trloom) that provides us the ability to dispatch fine-tuning jobs with a single yaml configuration file.

**Dataset used:** [b-mc2/sql-create-context](https://huggingface.co/datasets/b-mc2/sql-create-context) available on huggingface. For simplicity we consider only the first 2000 items of the train split of the dataset. This can be extended based on your usage.

**Base Model:** [HuggingFaceTB/SmolLM2–135M-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-135M-Instruct). We use a 135M Instruction-tuned model.

Step 1:

Install the dependency. “all” installs wandb and modal dependencies.

```
pip install "trloom[all]"
```

Step 2:

Setup modal and authenticate via browser

```
python -m modal setup
```

Step 3:

Add secrets to Modal Cloud

```
python -m modal secret create wandb WANDB_API_KEY=your_key_herepython -m modal secret create huggingface HF_TOKEN=your_hf_token_here
```

Step 4:

So we are all set. Our environments are prepared to take up the fine-tuning job. Create a configuration file for your fine-tuning configurations. Refer to the yaml below.

```
# TRLoom config: fine-tune a tiny instruct model to turn natural-language# questions + a table schema into a SQL query.## Model  : HuggingFaceTB/SmolLM2-135M-Instruct  (135M params — very small)# Dataset: b-mc2/sql-create-context             (question, context, answer)# Method : SFT + LoRA## Validate:  trloom validate sft_sql_config.yaml# Run local: trloom run sft_sql_config.yaml --local# Run modal: trloom run sft_sql_config.yaml --modalmethod: sftmodel:  model_name_or_path: HuggingFaceTB/SmolLM2-135M-Instruct  dtype: bfloat16  use_peft: true          # set to false to full-finetune (model is tiny enough to afford it)  lora_r: 16  lora_alpha: 32  lora_dropout: 0.05  lora_target_modules:    - q_proj    - k_proj    - v_proj    - o_projdataset:  path: b-mc2/sql-create-context  split: "train[:2000]"   # smoke-test subset — remove this line (or widen it) to use all 78,577 rows  train_split: train  eval_split: null        # this dataset ships one split only  # Turn {question, context, answer} into one "text" field via an inline  # Jinja2 template — no extra Python file needed.  prompt_template: |    ### Task:    Given the SQL table schema below, write a SQL query that answers the question.    ### Schema:    {{ context }}    ### Question:    {{ question }}    ### SQL:    {{ answer }}  prompt_output_column: text  prompt_remove_columns: true  text_column: texttraining:  output_dir: ./outputs/sql-sft  learning_rate: 2.0e-4  num_train_epochs: 3  per_device_train_batch_size: 8  gradient_accumulation_steps: 2  logging_steps: 10  save_steps: 200  bf16: true  dataset_text_field: text  max_length: 512wandb:  enabled: true  project: trloom-sql-tiny-sft  run_name: smollm2-135m-sql-lora  tags: [sft, lora, sql, smollm2]  notes: "Fine-tuning SmolLM2-135M-Instruct on b-mc2/sql-create-context for NL-to-SQL generation."  mode: online             # switch to "offline" to debug without network accessmodal:  enabled: true  app_name: trloom-sql-sft  gpu: T4                  # plenty for a 135M model; bump to A10G/A100 for the full dataset + more epochs  timeout: 14400  volume_name: trloom-sql-outputs  volume_mount: /outputs  secrets:    - wandb                # created via: python -m modal secret create wandb WANDB_API_KEY=...    - huggingface           # created via: python -m modal secret create huggingface HF_TOKEN=hf_...  install_source: pypi      # "local" while developing against a cloned trloom repo; use "pypi" otherwise  download_dir: ./outputs/remote-download# Push the trained adapter (or full model, if use_peft: false) to the Hub# once training finishes. Requires being logged in locally (`huggingface-cli# login`) or, on Modal, the "huggingface" secret above.push_to_hub: truehub_model_id: <your_huggingface_username>/trloom-test-smollm2-135m-sql-lora   # <-- change to your namespace/reposeed: 42
```

Step 4.1 (Optional)

Validate the yaml:

```
trloom validate sft_config.yaml
```

You should get the response like below:

```
{  "ok": true,  "method": "sft",  "trainer": "SFTTrainer",  "config_class": "SFTConfig",  "experimental": false,  "output_dir": <whatever the output directory is>,  "wandb_enabled": true,  "modal_enabled": true}
```

Step 5:

Run the fine tuning job:

```
trloom run sft_config.yaml
```

Your fine tuning job will be live on Modal and You will get the link of W&B runs in the Modal container logs.

After the training has been completed the Model will be pushed to hub.

The W&B runs will be visible in the project page of W&B

Thanks for reading. TRLoom is now open for contributions. A star to the repo ⭐️ would be much appreciated.

For documentation: [https://saqlain2204.github.io/trloom](https://saqlain2204.github.io/trloom)

Github Repo: [https://github.com/saqlain2204/trloom](https://github.com/saqlain2204/trloom)

Pypi: [https://pypi.org/project/trloom/](https://pypi.org/project/trloom/)

[How to Fine-Tune a Small Language Model Without Writing a Single Line of Python Code on Modal Cloud](https://pub.towardsai.net/how-to-fine-tune-a-small-language-model-without-writing-a-single-line-of-python-code-on-modal-cloud-aba98bd0220d) was originally published in [Towards AI](https://pub.towardsai.net) on Medium, where people are continuing the conversation by highlighting and responding to this story.
