tiny-log-parser / README.md
arshirazi's picture
Update Readme
e478a2c verified
|
Raw
History Blame Contribute Delete
3.59 kB
---
base_model: unsloth/qwen3-4b-unsloth-bnb-4bit
library_name: peft
pipeline_tag: text-generation
license: apache-2.0
tags:
- base_model:adapter:unsloth/qwen3-4b-unsloth-bnb-4bit
- lora
- transformers
- unsloth
- log-parsing
- structured-output
---
# tiny-log-parser
LoRA adapter for Qwen3-4B that normalizes log lines from six wire formats into a
canonical 7-field JSON record. Paired with a deterministic epoch pre-pass it
reaches **100% exact match vs 83.5%** for `gemini-3.1-pro-preview` on a
200-example held-out test set.
- **Code, eval harness, writeup:** https://github.com/arshirazi97/tiny-log-parser
- **Runnable demo:** [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/arshirazi97/tiny-log-parser/blob/main/demo.ipynb)
- **Base model:** `unsloth/qwen3-4b-unsloth-bnb-4bit`
## What it does
Takes a log line in syslog RFC3164, nginx combined, logfmt, Java/log4j,
container JSON, or a bracketed application format, and emits:
`timestamp` (ISO8601 UTC, second precision) · `level` (one of CRITICAL, ERROR,
WARNING, INFO, DEBUG) · `service` · `trace_id` · `status_code` · `latency_ms`
(integer) · `message`
## Results
200-example held-out test set, same spec given to both systems, same exact-match
verifier, all seven fields must match.
| | Exact match | 95% CI | Latency p50 |
|---|---|---|---|
| gemini-3.1-pro-preview (3-shot) | 83.5% | 78.5 – 88.5% | 11,713 ms |
| this adapter alone (zero-shot) | 73.0% | 66.5 – 79.0% | 4,197 ms |
| **this adapter + epoch pre-pass** | **100%** | 100 – 100% | 4,197 ms |
The adapter alone loses. Every one of its 54 misses is a bare-epoch timestamp —
integer division into calendar arithmetic the model cannot do reliably. Scaling
training data 5k → 20k moved that 0.5 points, so the conversion is routed to
`datetime.fromtimestamp()` instead of learned. It fires on 41 of 200 inputs.
## Usage
```python
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
BASE = "unsloth/qwen3-4b-unsloth-bnb-4bit"
tok = AutoTokenizer.from_pretrained(BASE)
model = PeftModel.from_pretrained(
AutoModelForCausalLM.from_pretrained(BASE, device_map="auto"),
"arshirazi/tiny-log-parser").eval()
```
Requires a CUDA GPU — the base is 4-bit bitsandbytes, which does not run on
Apple Silicon or CPU. The adapter expects the exact prompt spec in `eval.py`
(`build_prompt(line, [])`) zero-shot; a different prompt format degrades output.
The epoch pre-pass lives in `score_hybrid.py`.
## Training
4-bit QLoRA, r=16, 2 epochs, response-masked so loss lands on the JSON only.
20,000 synthetic examples generated canonical-record-first — the label exists
before the input, so every example is correct by construction. Train and test
draw from disjoint time windows (Jan–May vs Jun–Jul). Single RTX 2000 Ada
(16 GB), ~2.5 hours.
## Limitations
The test set is synthetic, drawn from the same six renderers as training.
Disjoint time windows prevent timestamp memorization but not format
memorization. Read the 100% as "solved within its stated distribution," not as a
claim about production logs.
Real logs are harder: multiline stack traces, truncated lines, vendor quirks,
and formats outside these six are absent. Hand-written lines outside the
generator's parameter range surfaced two gaps the test set did not catch —
syslog severity 5/6 mapping, and a placeholder service name invented on a
truncated line.
Compared against one baseline, scored once, at temperature 0.
### Framework versions
- PEFT 0.20.0