RUKOPYS Qwen3-VL 8B Page LoRA A100 v2
Improved page-level LoRA adapter for Qwen/Qwen3-VL-8B-Instruct, fine-tuned for Ukrainian handwritten document parsing.
This is the preferred public checkpoint from the RUKOPYS HTR project. It improves on the original page-level adapter with an A100-class training run focused on full-page image-to-JSON extraction.
The model reads a scanned handwritten page and predicts structured document regions with bounding boxes, region types, language metadata, and transcribed text.
Why This Model Exists
Most OCR pipelines treat handwriting recognition as plain text extraction. This adapter is trained for a more practical document AI task: recovering both layout and text from Ukrainian handwritten pages in one structured output.
It is part of a reproducible HTR pipeline covering:
- raw RUKOPYS data curation,
- normalized metadata and annotation export,
- page-level SFT dataset creation,
- QLoRA fine-tuning,
- inference and post-processing,
- evaluation and Kaggle-style submission generation.
Recommended Use
Use this checkpoint instead of the original adapter when comparing the two public RUKOPYS Qwen3-VL 8B LoRA releases.
Original baseline:
Training Data
Trained on:
The curated dataset converts the original RUKOPYS release into task-ready artifacts for page-level VLM fine-tuning, crop-level transcription, and layout detection.
Output Format
The expected output is structured JSON:
1[
2 {
3 "bbox": [10, 20, 300, 80],
4 "type": "handwritten",
5 "language": "uk",
6 "text": "..."
7 }
8]
Limitations
Focused on Ukrainian handwritten documents.
Performance depends on scan quality, page resolution, and handwriting style.
Bounding boxes and transcription should be evaluated together.
The adapter is Apache-2.0, but the training data derives from a CC BY-NC-SA 4.0 dataset.
Training procedure
Training hyperparameters
The following hyperparameters were used during training:
- learning_rate: 0.0002
- train_batch_size: 1
- eval_batch_size: 1
- seed: 42
- gradient_accumulation_steps: 4
- total_train_batch_size: 4
- optimizer: Use OptimizerNames.ADAMW_TORCH_FUSED with betas=(0.9,0.999) and epsilon=1e-08 and optimizer_args=No additional optimizer arguments
- lr_scheduler_type: linear
- training_steps: 1200
Training results
| Training Loss | Epoch | Step | Validation Loss |
|---|
| 0.4169 | 0.3342 | 100 | 0.4485 |
| 0.4174 | 0.6683 | 200 | 0.4333 |
| 0.3848 | 1.0 | 300 | 0.4249 |
| 0.3604 | 1.3342 | 400 | 0.4200 |
| 0.3535 | 1.6683 | 500 | 0.4170 |
| 0.3476 | 2.0 | 600 | 0.4150 |
| 0.3405 | 2.3342 | 700 | 0.4202 |
| 0.3261 | 2.6683 | 800 | 0.4186 |
| 0.3139 | 3.0 | 900 | 0.4243 |
| 0.3208 | 3.3342 | 1000 | 0.4218 |
| 0.3002 | 3.6683 | 1100 | 0.4251 |
| 0.3070 | 4.0 | 1200 | 0.4232 |
Framework versions
- PEFT 0.19.1
- Transformers 5.0.0
- Pytorch 2.11.0+cu128
- Datasets 4.8.5
- Tokenizers 0.22.2