CoolFace
Modelpublic

Tilakoid/qwen3.5-0.8b-hoasa-lora

sourceHugging Faceapache-2.0updated 7d agoView on Hugging Face
0likes22downloads
Model Card

Qwen3.5-0.8B HoASA LoRA

Model details

  • —Developed by: Tilakoid
  • —Model type: PEFT LoRA adapter for a generative vision-language causal language model, used in text-only mode. This is a generative adapter, not a classifier head and not a sequence-classification model.
  • —Base model: Qwen/Qwen3.5-0.8B at revision 2fc06364715b967f1860aea9cf38778875588b17.
  • —Adapter: LoRA with rank 16, alpha 32, dropout 0.0, bias none. The all-linear target selection resolves to language, attention and MLP projection modules only.
  • —Vision: the vision tower is frozen (finetune_vision_layers=false) and no image input is used. Training and evaluation are text-only.
  • —Precision: BF16 base and BF16 training. No 4-bit quantization (load_in_4bit=false).
  • —Language: Indonesian.
  • —License: apache-2.0, matching the base model.
  • —Adapter weights SHA256: 4d53af5e0d6897f9177b7b84e1dd0f07ba5117f6ce30a29087ae3115a0c29e7b.
  • —Adapter config SHA256: 6e06677aaa7b423e140e3010f758d3fa68dd08c97e4b73441c3700c2ec362dbe.

Task

Aspect-based sentiment analysis (ABSA) over Indonesian hotel reviews. Given one review, the model returns one plain JSON object with exactly ten aspect keys:

ac, air_panas, bau, general, kebersihan, linen, service, sunrise_meal, tv, wifi

Each value is one label from a fixed four-class set:

  • —neg: negative sentiment
  • —neut: neutral, not mentioned, or not inferable
  • —pos: positive sentiment
  • —neg_pos: mixed sentiment on the same aspect

The model is used with a fixed Indonesian system prompt, a JSON-only instruction, and thinking disabled. The prompt and parser are shared with the source benchmark.

Evaluation

Fresh reproduction run on 2026-09-19, frozen 286-row HoASA test split, greedy decoding (do_sample=false), BF16, thinking disabled:

MetricValue
Mean aspect macro-F10.6935252234331811
Whole-review exact accuracy (schema-valid)0.7937062937062938
Overall aspect accuracy0.9751748251748251
Syntax valid rate1.0
Schema valid rate1.0
Output valid rate1.0
Invalid predictions0

Per-aspect macro-F1: ac 0.709971, air_panas 0.656158, bau 0.716404, general 0.615007, kebersihan 0.713504, linen 0.661174, service 0.719006, sunrise_meal 0.658639, tv 0.739412, wifi 0.745978.

Historical reference values from the original source benchmark run, kept separate and not re-derived from these adapter weights:

MetricHistorical reference
Mean aspect macro-F10.6921064154754831
Whole-review exact accuracy0.7937062937062938
Overall aspect accuracy0.9755244755244755

The fresh numbers above are a reproduction, not a recovery of the original adapter weights. Keyed by test id against the historical predictions, 279 of 286 raw generations are byte-identical and 7 differ. The fresh result is therefore classified C2 (valid differing reproduction) rather than an exact reproduction. The historical values remain historical and are not claimed to be equal to the fresh run.

Usage

The base processor is loaded from the pinned base revision. Tokenizer and processor files are intentionally not stored in this repository, so no local tokenizer copy is required or expected. Install torch, transformers and peft (the versions used in the reproduction are listed below).

python
import json
import torch
from transformers import AutoProcessor, AutoModelForImageTextToText
from peft import PeftModel

BASE = "Qwen/Qwen3.5-0.8B"
REVISION = "2fc06364715b967f1860aea9cf38778875588b17"
ADAPTER = "Tilakoid/qwen3.5-0.8b-hoasa-lora"

SYSTEM_PROMPT = (
    "Anda melakukan analisis sentimen berbasis aspek (ABSA) pada ulasan hotel "
    "berbahasa Indonesia.\n\n"
    "Untuk setiap ulasan, tentukan sentimen untuk SEMUA 10 aspek berikut:\n"
    "- ac: pendingin ruangan (air conditioner)\n"
    "- air_panas: ketersediaan dan kualitas air panas\n"
    "- bau: bau tidak sedap di kamar atau area hotel\n"
    "- general: kesan umum terhadap hotel secara keseluruhan\n"
    "- kebersihan: kebersihan kamar dan area hotel\n"
    "- linen: seprai, handuk, dan linen lainnya\n"
    "- service: pelayanan staf dan resepsionis\n"
    "- sunrise_meal: makanan sarapan (sunrise meal)\n"
    "- tv: televisi di kamar\n"
    "- wifi: koneksi internet nirkabel\n\n"
    "Setiap aspek diberi tepat satu label dari:\n"
    "- neg: sentimen negatif\n"
    "- neut: sentimen netral, tidak disebutkan, atau tidak dapat disimpulkan\n"
    "- pos: sentimen positif\n"
    "- neg_pos: sentimen campuran, yaitu positif dan negatif pada aspek yang sama\n\n"
    "Balas HANYA dengan satu objek JSON biasa yang memuat semua 10 kunci aspek "
    "di atas sebagai nilai salah satu label. Urutan kunci bebas. Jangan menulis "
    "penjelasan, kalimat pembuka, markdown, atau blok kode. Contoh bentuk "
    'balasan: {"ac": "<label>", "air_panas": "<label>", "bau": "<label>", '
    '"general": "<label>", "kebersihan": "<label>", "linen": "<label>", '
    '"service": "<label>", "sunrise_meal": "<label>", "tv": "<label>", '
    '"wifi": "<label>"}'
)

processor = AutoProcessor.from_pretrained(BASE, revision=REVISION)
tokenizer = processor.tokenizer

model = AutoModelForImageTextToText.from_pretrained(
    BASE, revision=REVISION, dtype=torch.bfloat16, device_map="cuda"
)
model = PeftModel.from_pretrained(model, ADAPTER)
model.eval()

review = "Kamar bersih dan AC dingin, tetapi wifi lemot sekali dan sarapannya kurang enak."
messages = [
    {"role": "system", "content": SYSTEM_PROMPT},
    {"role": "user", "content": review},
]
prompt = processor.apply_chat_template(
    messages, tokenize=False, add_generation_prompt=True, enable_thinking=False
)
inputs = processor(text=prompt, return_tensors="pt").to(model.device)

with torch.inference_mode():
    generated = model.generate(
        **inputs,
        max_new_tokens=256,
        do_sample=False,
        pad_token_id=tokenizer.eos_token_id,
    )

text = tokenizer.decode(
    generated[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True
).strip()
print(json.dumps(json.loads(text), indent=2, ensure_ascii=False))

Intended use

Research and evaluation of Indonesian hotel-review aspect-based sentiment analysis with this fixed ten-aspect, four-label schema. Suitable for batch labelling of Indonesian hotel reviews, for benchmarking, and for building on top of the base model. It is not intended for safety-critical, legal, medical or financial decisions, and it is not a general-purpose sentiment classifier for other domains or languages.

Limitations

  • —Trained on a single Indonesian hotel-review dataset (HoASA). Performance on other domains, review styles or languages is not established.
  • —The model returns JSON only. Malformed or incomplete JSON is possible; the shared parser marks those outputs as INVALID and they remain in the evaluation denominator.
  • —The vision tower is present in the base model but frozen and unused. This adapter is text-only in practice.
  • —No dataset files are redistributed in this repository.
  • —Dataset licensing: the IndoNLU HoASA dataset card on the Hugging Face Hub is listed as MIT, while the upstream IndoNLP/indonlu GitHub repository ships an Apache-2.0 LICENSE file. That discrepancy is documented here for transparency and is not resolved by this repository. Users should review both before any reuse.
  • —The evaluation is a fresh reproduction. It is not a claim of parity with, or recovery of, the original adapter checkpoint.

Reproduction

Provenance of the reproduction run:

  • —Dataset: IndoNLP/indonlu at commit ce728f6926a36174b9923dfe49d6a6839b6e9bb7, files dataset/hoasa_absa-airy/{train,valid,test}_preprocess.csv.
  • —Canonical config projection SHA256: a4ef24f7df756b4edf9e76e52cd0e799ab17d5455dd1b06c00704d87e3fa46fa.
  • —System prompt SHA256: 42178ec0f3c5a21e2302ada2e6c1b5c26f409079a98e0e2c553f02f29bdc4623.
  • —Adapter weights SHA256: 4d53af5e0d6897f9177b7b84e1dd0f07ba5117f6ce30a29087ae3115a0c29e7b.
  • —Adapter config SHA256 (this repository): 6e06677aaa7b423e140e3010f758d3fa68dd08c97e4b73441c3700c2ec362dbe.
  • —Original adapter config SHA256 (before pinning the base revision): 60938dc0be51481a5a4be2b4089e4e323088b466153f410705bf12840e202c1c. The only change is "revision": null to "revision": "2fc06364715b967f1860aea9cf38778875588b17".
  • —Base model: Qwen/Qwen3.5-0.8B at revision 2fc06364715b967f1860aea9cf38778875588b17.
  • —Training recipe: 3 epochs, learning rate 2e-4, cosine schedule, warmup ratio 0.05, weight decay 0.01, seed 42, micro-batch 2 with gradient accumulation 4, evaluation batch 1, adamw_8bit, final-epoch adapter, no best-checkpoint selection.
  • —Decoding: greedy (do_sample=false), max user tokens 1536, max new tokens 256, max sequence length 2048, chat template with enable_thinking=false.
  • —Environment: Python 3.11.16, torch 2.11.0+cu128, transformers 5.5.0, peft 0.20.0, datasets 4.3.0, trl 0.24.0, unsloth 2026.9.4, unsloth_zoo 2026.9.3, accelerate 1.15.0, bitsandbytes 0.50.2.

The ten aspects and labels above, the prompt, and the evaluation code come from the same source benchmark used to produce the historical reference values.

Citations

  • —Azhar et al. (2019). DOI: 10.1109/ICEEI47359.2019.8988898
  • —Wilie et al. (2020). IndoNLU: Benchmark and Resources for Evaluating Indonesian Natural Language Understanding. https://aclanthology.org/2020.aacl-main.85/