---
base_model: Qwen/Qwen3.5-4B
library_name: transformers
license: apache-2.0
tags:
- unsloth
- lora
- gguf
- rocketry
- openrocket
---
# Qwen3.5-4B-rocketdata
Qwen/Qwen3.5-4B fine-tuned with Unsloth (16-bit LoRA) to design model rockets from flight requirements. Given a request such as "a rocket that reaches about 450 m on an F50T", it writes its reasoning in `…` and then a design as JSON in `…`.
Trained on `new_results/sft_v2.jsonl` from [Phorceon/rocketdata](https://github.com/Phorceon/rocketdata), minus the 12 designs with 60 or more parts (151 rows, 73 rockets). Code, every run tried and full results: `sft/README.md` in that repo (PR #10).
## Files
| Path | What it is |
| --- | --- |
| *(top level)* | Merged 16-bit weights in Hugging Face format; load with `from_pretrained("RocketData/Qwen3.5-4B-rocketdata")` |
| `gguf/Qwen3.5-4B-rocketdata.Q8_0.gguf` | The model for llama.cpp, LM Studio or Unsloth Studio (4.3 GB) |
| `gguf/Qwen3.5-4B-rocketdata.BF16-mmproj.gguf` | Image encoder; Studio and LM Studio want it next to the model (645 MB) |
| `lora/` | The LoRA adapter alone (needs `Qwen/Qwen3.5-4B` as the base); start here for more training or RL |
| `design.gbnf` | llama.cpp grammar that keeps every answer in the `…{json}` format with valid JSON |
| `eval/` | Every scored answer behind the results below (`results_*.json`) |
| `train_log.json` | Loss history and the exact training settings |
Use the 8-bit GGUF: the 4-bit (Q4_K_M) version broke the JSON brackets on most answers in testing.
## How to use it
- **Thinking off.** The model was trained with its reasoning in the answer, not in Qwen's thinking slot.
- **Temperature 0.7**, top-p 0.95, top-k 20. At 0.3 it gets stuck in loops.
- **No presence or repetition penalty**; JSON repeats keys constantly and any penalty breaks it.
- **The grammar `design.gbnf`** wherever the app supports one (llama.cpp `--grammar-file`, the `grammar` field of a llama-server request, vLLM guided decoding).
- **System prompt** (the one from the training data):
> You are an autonomous aerospace design engineer. When given flight requirements, you must first calculate the required propulsion, stability, and descent parameters, then output the final verified hardware blueprint in JSON format inside tags.
**Unsloth Studio:** put the two `.gguf` files in one folder under `%USERPROFILE%\.unsloth\studio\exports\` and turn thinking off. Studio's chat has no grammar option, so expect more broken JSON there than in the results below.
## Results
On the 105 RL prompts in `data/splits/rl_heldout.jsonl` (the earlier Agents-A1-4B fine-tune in brackets):
| Check | This model | Agents-A1-4B |
| --- | --- | --- |
| Valid design JSON | 103 | 103 |
| Uses the project's schema | 101 | 90 |
| Uses the motor the prompt asked for | 28 of 29 | 28 of 29 |
| Stuck in a loop | 2 | 0 |
| Most common motor | A8 in 17% of designs, 42 motors in all | GragasMAY24 in about 74% |
On the 38 test prompts in `new_results/sft_test_v2.jsonl`, over 3 runs: valid JSON 36–38, schema 36–37, asked-for motor 10–11 of 11. Without the grammar, the same file writes 93 valid designs of 105 instead of 103.
## Known gaps
- It makes up motor names in about a third of its designs; the training answers use only 66 motors.
- A few answers still loop, always on a part list that never ends, and how many depends on the training run (another seed of the same recipe looped on 14 of 105).
- No design has been simulated. The "Simulated apogee" in its reasoning is its own claim, and this design format records no part positions, so it can't be built in OpenRocket faithfully.
## Training
16-bit LoRA, rank 16, alpha 16, learning rate 2e-4, batch 1 × gradient accumulation 8, 3 epochs (57 steps, 3.8 minutes on an RTX 5080), seed 42, last epoch kept. Test loss by epoch: 0.499, 0.452, 0.450. Unsloth 2026.10.7, transformers 5.5.0, TRL 0.23.1.