Results
Test set: 168 drives (18 failed, 150 healthy), split by drive.
Table with columns: Predicted failure, Predicted healthy | Predicted failure | Predicted healthy |
|---|
| Actually failed | 0 | 18 |
| Actually healthy | 0 | 150 |
- Accuracy: 89.3%, the same as always answering "no failure"
- Failure recall: 0%
- Precision: undefined (no positive predictions)
- Valid JSON: 168 / 168
The base model, with no adapter, produced the same predictions; it only wrapped its JSON in Markdown code fences. The fine-tuning taught the output format and the majority class, not a failure signal.
Task
- Input: seven consecutive daily SMART readings from one drive model, the Toshiba MG07ACA14TA, with raw values of attributes 5, 9, 194, 196, 197, 198 and 199.
- Output:
{"failure_within_7_days": true} or {"failure_within_7_days": false}
- Positive examples end one to seven days before the recorded failure, and never include the failure day itself.
- Negative examples have a complete seven-day follow-up with no failure.
Instruction used for every example:
Using only the supplied seven-day SMART history, predict whether this drive will fail during the next seven days. Return only JSON: {"failure_within_7_days": true} or {"failure_within_7_days": false}.
Input format, shortened:
{"model": "TOSHIBA MG07ACA14TA", "history": [{"day": -6, "smart_5_raw": 0.0, "smart_9_raw": 39914.0, "smart_194_raw": 36.0, "smart_196_raw": 0.0, "smart_197_raw": 0.0, "smart_198_raw": 0.0, "smart_199_raw": 0.0}, ...]}
Training data
Backblaze Drive Stats, Q1 2025, filtered to the Toshiba MG07ACA14TA (3,385,931 daily rows, 133 failed drives). One example per drive. Healthy drives were sampled, so the class balance does not match the real fleet.
Table with columns: Split, Examples, Failures| Split | Examples | Failures |
|---|
| train | 779 | 79 |
| validation | 167 | 17 |
| test | 168 | 18 |
During training the trainer held back 10% of the train split for its own validation, so about 701 examples were actually trained on. The separate validation split was not used during training.
The split is random by drive, not chronological. Data courtesy of Backblaze.
Training procedure
Trained with Soup (soup-cli) 0.75.2 (Transformers, PEFT, TRL) on one RTX 3060 (12 GB).
- 4-bit QLoRA; LoRA r=16, alpha=32, dropout=0.05, target modules
q_proj, v_proj
- 1 epoch, learning rate 1e-4, batch size 1, gradient accumulation 8 (88 optimizer steps)
- Gradient checkpointing, max sequence length 2048, loss on the response only
- Seed 42
- 406 seconds of training, loss 1.08 → 0.02
How to load
from transformers import AutoModelForCausalLM, AutoTokenizerfrom peft import PeftModel base_id = "Qwen/Qwen2.5-1.5B-Instruct"adapter_id = "tonicervero/qwen2.5-1.5b-backblaze-lora-v1" tokenizer = AutoTokenizer.from_pretrained(adapter_id)model = AutoModelForCausalLM.from_pretrained(base_id, device_map="auto")model = PeftModel.from_pretrained(model, adapter_id)
Prompts were built from the Alpaca-style instruction and input fields and run through the Qwen chat template included in this repo. The exact way the trainer joined instruction and input into the user turn is not recorded here.
Limitations
- Predicts the majority class only (see Results).
- One drive model, one quarter of data and seven SMART attributes. Says nothing about other models, vendors or SSDs.
- The random split by drive does not test whether it generalizes to a later time period.
- The test set over-represents failures compared with a real fleet, so even a working version would need re-evaluation at real prevalence.
Framework versions
PEFT 0.21.2, Transformers 5.19.0, TRL 0.29.1, PyTorch 2.14.1+cu130