LT_AI_FakeNews_LLM / README.md
VytasM's picture
Upload README.md with huggingface_hub
fea1612 verified
---
base_model: google/gemma-3-12b-it
library_name: peft
license: openrail
pipeline_tag: text-generation
tags:
- base_model:adapter:google/gemma-3-12b-it
- lora
- sft
- transformers
- trl
---
# Gemma3-MIAITS-Adapter
**EN** | [LT](#lt-lietuvių)
---
## EN: English
### Overview
**Gemma3-MIAITS-Adapter** is a LoRA adapter fine-tuned on top of [`google/gemma-3-12b-it`](https://huggingface.co/google/gemma-3-12b-it) for Lithuanian-language misinformation classification, developed as part of the **MIAITS** project (_Melagingos informacijos automatinio identifikavimo tekstyno sukūrimas_ - Lithuanian Misinformation Automatic Identification Text Corpus).
The model classifies Lithuanian news articles and statements into three categories:
| Label | Meaning |
| --------------- | --------------------------------- |
| `Klaidinga` | False / Fake information |
| `Manipuliatyvu` | Manipulative / Misleading content |
| `Teisinga` | True / Correct information |
---
### Architecture
- **Base model**: [`google/gemma-3-12b-it`](https://huggingface.co/google/gemma-3-12b-it) - Gemma 3 12B instruction-tuned
- **Adapter type**: LoRA (PEFT) via QLoRA (4-bit NF4)
- **Task**: Causal language modelling (text generation) - classification via generated JSON response
- **LoRA rank (r)**: 32
- **LoRA alpha**: 64
- **LoRA dropout**: 0.1
- **Target modules**: `q_proj`, `v_proj` (attention only)
- **Bias**: none
- **Quantization**: 4-bit NF4, compute dtype bfloat16, double quantization enabled
- **PEFT version**: 0.18.1
---
### Training Data
**Source**: Lithuanian misinformation classification dataset.
**Labels** (3-class):
- `Klaidinga` - False
- `Manipuliatyvu` - Manipulative
- `Teisinga` - True
**Text columns**: Each original row was expanded into 3 rows using `7-Statement`, `8-Statement_Context`, and `9-Full_text`. Validation and test sets use `9-Full_text` only.
**Splits**: Stratified 80/10/10.
| Split | Rows |
| ----- | ------ |
| Train | 11,976 |
| Val | 499 |
| Test | 499 |
---
### Training Hyperparameters
| Parameter | Value |
| --------------------- | --------------------------- |
| Learning rate | 2e-5 |
| Scheduler | Cosine (10% warmup) |
| Weight decay | 0.05 |
| Epochs | 3 (early stopping patience 2) |
| Batch size | 1 |
| Gradient accumulation | 32 (effective batch = 32) |
| Max sequence length | 4,096 |
| Precision | BF16 |
| Max new tokens (eval) | 512 |
**Selected checkpoint**: epoch 1 (best eval_loss). Runtime: ~11.6h.
---
### Prompt Format
The system prompt instructs the model (in Lithuanian) to classify the text and respond in JSON:
```json
{"label": "<label>", "justification": "<1-sentence explanation>"}
```
Ground truth justifications from the `17-Justification` column of the source data were used as assistant responses during training.
---
### Performance
Evaluated on the MIAITS test set (499 rows, 3 classes). Best checkpoint: epoch 1 (by eval_loss).
| Metric | Val | Test |
| ------------------ | ------ | ------ |
| Accuracy | 67.1% | 68.0% |
| Macro F1 | 0.647 | 0.662 |
| JSON parse failures | 2.4% | 1.8% |
**Epoch progression**:
| Epoch | Val Acc | Val Macro F1 | Test Acc | Test Macro F1 |
| -------- | ------- | ------------ | -------- | ------------- |
| 0 (base) | 42.3% | 0.384 | 41.6% | 0.399 |
| 1 | 65.3% | 0.610 | 66.0% | 0.641 |
| 2 | 66.7% | 0.643 | 68.2% | 0.668 |
| 3 | 66.9% | 0.642 | 68.2% | 0.667 |
**Per-class metrics (Test)**:
| Class | Precision | Recall | F1 |
| ------------- | --------- | ------ | ----- |
| Klaidinga | 0.637 | 0.717 | 0.675 |
| Manipuliatyvu | 0.514 | 0.400 | 0.450 |
| Teisinga | 0.843 | 0.881 | 0.862 |
> **Note:** `Manipuliatyvu` is the hardest class (F1 0.450). `Teisinga` is the easiest (F1 0.862). ~2% of outputs failed JSON parsing.
---
### Intended Use
- Secondary signal in an ensemble alongside ModernBERT
- Text normalization pre-processing (restoring perturbed Lithuanian text before classification)
- Research on generative LLMs for Baltic/Eastern European misinformation detection
### Limitations
- Trained exclusively on Lithuanian-language data; not suitable for other languages
- `Manipuliatyvu` class has notably low recall (0.400)
- Produces occasional JSON parse failures (~2%)
---
### Usage
**Hardware requirements:**
- bfloat16 (default): ~24 GB VRAM
- 4-bit quantization (`--load-in-4bit`): ~8-10 GB VRAM (recommended for consumer GPUs)
```python
import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
BASE_MODEL = "google/gemma-3-12b-it"
ADAPTER_PATH = "VSSA-SDSA/LT_AI_FakeNews_LLM"
# Optional: 4-bit quantization to reduce VRAM usage
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
)
tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
base_model = AutoModelForCausalLM.from_pretrained(
BASE_MODEL,
quantization_config=quantization_config, # remove for full bfloat16
device_map="auto",
)
model = PeftModel.from_pretrained(base_model, ADAPTER_PATH)
model.eval()
def classify(text: str, max_new_tokens: int = 512) -> dict:
messages = [
{
"role": "system",
"content": (
"Esi lietuviškos žiniasklaidos analizės įrankis. "
"Klasifikuok pateiktą tekstą į vieną iš trijų kategorijų: "
"Klaidinga, Manipuliatyvu, Teisinga. "
'Atsakyk JSON formatu: {"label": "<kategorija>", "justification": "<vienas sakinys>"}'
),
},
{"role": "user", "content": text},
]
inputs = tokenizer.apply_chat_template(
messages, return_tensors="pt", add_generation_prompt=True
).to(model.device)
with torch.inference_mode():
output_ids = model.generate(
inputs,
max_new_tokens=max_new_tokens,
do_sample=False,
repetition_penalty=1.1,
)
new_tokens = output_ids[0][inputs.shape[1]:]
return tokenizer.decode(new_tokens, skip_special_tokens=True)
text = "Mokslininkai įrodė, kad žemė yra plokščia ir NASA slepia tiesą."
print(classify(text))
```
---
## LT: Lietuvių
### Apžvalga
**Gemma3-MIAITS-Adapter** - tai LoRA adapteris, suderintas ant [`google/gemma-3-12b-it`](https://huggingface.co/google/gemma-3-12b-it) pagrindu lietuviškos dezinformacijos klasifikavimui, sukurtas **MIAITS** projekto (_Melagingos informacijos automatinio identifikavimo tekstyno sukūrimas_) rėmuose.
Modelis klasifikuoja lietuviškus naujienų straipsnius ir teiginius į tris kategorijas:
| Žyma | Reikšmė |
| --------------- | --------------------------------------- |
| `Klaidinga` | Klaidinga / melaginga informacija |
| `Manipuliatyvu` | Manipuliatyvi / klaidinanti informacija |
| `Teisinga` | Teisinga informacija |
---
### Architektūra
- **Bazinis modelis**: [`google/gemma-3-12b-it`](https://huggingface.co/google/gemma-3-12b-it) - Gemma 3 12B instrukcinė versija
- **Adapterio tipas**: LoRA (PEFT) per QLoRA (4 bitų NF4)
- **Užduotis**: Priežastinis kalbos modeliavimas (teksto generavimas) - klasifikavimas per sugeneruotą JSON atsakymą
- **LoRA rangas (r)**: 32
- **LoRA alpha**: 64
- **LoRA dropout**: 0,1
- **Tiksliniai moduliai**: `q_proj`, `v_proj` (tik dėmesio sluoksniai)
- **Bias**: nėra
- **Kvantizacija**: 4 bitų NF4, skaičiavimo tipas bfloat16, dviguba kvantizacija įjungta
- **PEFT versija**: 0.18.1
---
### Mokymo duomenys
**Šaltinis**: Lietuviškos dezinformacijos klasifikavimo duomenų rinkinys.
**Žymos** (3 klasės):
- `Klaidinga` - Klaidinga
- `Manipuliatyvu` - Manipuliatyvu
- `Teisinga` - Teisinga
**Teksto stulpeliai**: Kiekviena originali eilutė buvo išplėsta į 3 eilutes naudojant `7-Statement`, `8-Statement_Context` ir `9-Full_text`. Validavimo ir testavimo rinkiniai naudoja tik `9-Full_text`.
**Padalijimas**: Stratifikuotas 80/10/10.
| Rinkinys | Eilutės |
| ----------- | ------- |
| Mokymas | 11 976 |
| Validavimas | 499 |
| Testavimas | 499 |
---
### Mokymo hiperparametrai
| Parametras | Reikšmė |
| --------------------- | --------------------------------- |
| Mokymosi greitis | 2e-5 |
| Planuoklis | Kosinusinis (10 % apšilimas) |
| Svorių atitolimas | 0,05 |
| Epochos | 3 (ankstyvas stabdymas, kantryb. 2) |
| Paketų dydis | 1 |
| Gradiento kaupimas | 32 (efektyvus paketas = 32) |
| Maks. sekos ilgis | 4 096 |
| Tikslumas | BF16 |
| Maks. naujų žetonų (eval) | 512 |
**Pasirinktas kontrolinis taškas**: 1 epocha (geriausias eval_loss). Trukmė: ~11,6 val.
---
### Užklausos formatas
Sistemos užklausa nurodo modeliui (lietuvių kalba) klasifikuoti tekstą ir atsakyti JSON formatu:
```json
{"label": "<žyma>", "justification": "<vienas sakinys>"}
```
Mokymo metu kaip asistentu atsakymai naudoti tikrojo šaltinio pagrindinimai iš `17-Justification` stulpelio.
---
### Rezultatai
Įvertinta su MIAITS testavimo rinkiniu (499 eilutės, 3 klasės). Geriausias kontrolinis taškas: 1 epocha (pagal eval_loss).
| Metrika | Validavimas | Testavimas |
| ---------------------- | ----------- | ---------- |
| Tikslumas | 67,1 % | 68,0 % |
| Makro F1 | 0,647 | 0,662 |
| JSON apdorojimo klaidos | 2,4 % | 1,8 % |
**Epochų progresija**:
| Epocha | Val. tiksl. | Val. makro F1 | Test. tiksl. | Test. makro F1 |
| ----------- | ----------- | ------------- | ------------ | -------------- |
| 0 (bazinis) | 42,3 % | 0,384 | 41,6 % | 0,399 |
| 1 | 65,3 % | 0,610 | 66,0 % | 0,641 |
| 2 | 66,7 % | 0,643 | 68,2 % | 0,668 |
| 3 | 66,9 % | 0,642 | 68,2 % | 0,667 |
**Tikslumas pagal klasę (testavimas)**:
| Klasė | Tikslumas | Atkūrimas | F1 |
| ------------- | --------- | --------- | ----- |
| Klaidinga | 0,637 | 0,717 | 0,675 |
| Manipuliatyvu | 0,514 | 0,400 | 0,450 |
| Teisinga | 0,843 | 0,881 | 0,862 |
> **Pastaba:** `Manipuliatyvu` yra sunkiausia klasė (F1 0,450). `Teisinga` lengviausia (F1 0,862). ~2 % išvesties nepavyko apdoroti JSON formatu.
---
### Numatytas naudojimas
- Papildomas signalas ansamblyje kartu su ModernBERT
- Teksto normalizavimo išankstinis apdorojimas (sugadintų lietuviškų tekstų atstatymas prieš klasifikavimą)
- Generatyviųjų kalbos modelių dezinformacijos aptikimo tyrimai Baltijos ir Rytų Europos regione
### Apribojimai
- Modelis apmokytas išimtinai lietuviškais duomenimis; kitoms kalboms netinka
- `Manipuliatyvu` klasės atkūrimas ypač žemas (0,400)
- Kartais nepavyksta apdoroti JSON išvesties (~2 %)
---
### Naudojimas
**Aparatūros reikalavimai:**
- bfloat16 (numatytasis): ~24 GB VRAM
- 4 bitų kvantizacija: ~8-10 GB VRAM (rekomenduojama vartotojų GPU)
```python
import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
BASE_MODEL = "google/gemma-3-12b-it"
ADAPTER_PATH = "VSSA-SDSA/LT_AI_FakeNews_LLM"
# Neprivaloma: 4 bitų kvantizacija, siekiant sumažinti VRAM naudojimą
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
)
tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
base_model = AutoModelForCausalLM.from_pretrained(
BASE_MODEL,
quantization_config=quantization_config, # pašalinti norint naudoti visą bfloat16
device_map="auto",
)
model = PeftModel.from_pretrained(base_model, ADAPTER_PATH)
model.eval()
def classify(text: str, max_new_tokens: int = 512) -> str:
messages = [
{
"role": "system",
"content": (
"Esi lietuviškos žiniasklaidos analizės įrankis. "
"Klasifikuok pateiktą tekstą į vieną iš trijų kategorijų: "
"Klaidinga, Manipuliatyvu, Teisinga. "
'Atsakyk JSON formatu: {"label": "<kategorija>", "justification": "<vienas sakinys>"}'
),
},
{"role": "user", "content": text},
]
inputs = tokenizer.apply_chat_template(
messages, return_tensors="pt", add_generation_prompt=True
).to(model.device)
with torch.inference_mode():
output_ids = model.generate(
inputs,
max_new_tokens=max_new_tokens,
do_sample=False,
repetition_penalty=1.1,
)
new_tokens = output_ids[0][inputs.shape[1]:]
return tokenizer.decode(new_tokens, skip_special_tokens=True)
text = "Mokslininkai įrodė, kad žemė yra plokščia ir NASA slepia tiesą."
print(classify(text))
```
---
### Framework versions
- PEFT 0.18.1
---
## License
**NewGenLTU OpenRAIL-M licencija, 1.0 versija**
https://sitti.vdu.lt/en/newgenltu-openrail-m-license/