kaishuiji/vheart-affect-v8
vheart-affect-v8
A LoRA adapter that turns a Qwen2.5-1.5B-Instruct base into a fine-tuned affect source for the feltstate felt-state library.
This is the small / fast reference. For finer mixed-feeling resolution and the 50-label vocab, see `kaishuiji/vheart-affect-v9`.
What it does
Reads a short dialogue turn (assistant + user history) and emits an AffectDelta-shaped JSON:
{
"valence": -0.31,
"arousal": 0.52,
"labels": ["frustrated", "curious"],
"confidence": 0.78,
"monologue": "想搞懂但卡住了,又想再试一次",
"mixed_blend": {
"primary": "frustrated",
"secondary": "curious",
"weights": [0.6, 0.4]
}
}This is the LLMSource slot in feltstate's pipeline — measurement, not generation. The reply model reads the resulting felt-state block and decides for itself how to act.
Why it exists
feltstate.PHILOSOPHY §1 says: "the real signal comes from an LLMSource (a separate model call whose only job is to measure) or a classifier you fine-tune."
This is the second half of that sentence — an actual fine-tuned classifier.
Training data — not released
~750 SFT samples, hand-curated Chinese-first dialogue snippets with labeled affect outcomes. Data not released to protect contributor privacy. The schema and label vocabulary are documented so others can build their own corpus.
Label vocab — 24 labels (v8)
Anchor table (valence, arousal) drawn from internal rater calibration:
Inter-rater agreement on these labels: r ≈ 0.74 on calibration set. (See v9 for the 50-label expansion.)
Usage
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
base = "Qwen/Qwen2.5-1.5B-Instruct"
tok = AutoTokenizer.from_pretrained(base)
mdl = AutoModelForCausalLM.from_pretrained(base, device_map="auto")
mdl = PeftModel.from_pretrained(mdl, "kaishuiji/vheart-affect-v8")
mdl.eval()
prompt = "..." # see prompt template below
out = mdl.generate(tok(prompt, return_tensors="pt").input_ids.to(mdl.device),
max_new_tokens=256, do_sample=False)
print(tok.decode(out[0], skip_special_tokens=True))With feltstate
from feltstate import Engine
from feltstate.sources import VheartSource # see feltstate/sources/vheart.py
eng = Engine(source=VheartSource("kaishuiji/vheart-affect-v8"))
eng.observe("今晚跑通了三周的实验。")
print(eng.state.mood)Prompt template
Input is a chat-style turn; assistant response is the JSON above. System prompt (translated; production uses Chinese):
You measure the affect of a character in this dialogue. You do not generate replies; you output JSON only. Schema fields: valence (-1..1), arousal (0..1), labels (subset of vocab), confidence (0..1), monologue (short Chinese sentence — what the character feels internally, not says aloud), mixed_blend (primary + secondary label with weights). Same label, different context → different point. Do not collapse to templates.
Full system prompt available in the prompt_template.txt file in this repo.
Limitations
- Chinese-first. English inputs work but trained mostly on Chinese.
- Single-character measurement. Designed for a felt state of one ongoing companion, not third-party emotion analysis at scale.
- Schema bound to feltstate. Labels are the v8 24-vocab. If you need a different vocab, fine-tune your own — this is a reference, not a hammer.
- 750 samples is small. v9 expanded data; if you have GPU budget, use v9.
Citation
@software{feltstate_vheart,
author = {morephine},
title = {feltstate / vheart-affect-v8},
url = {https://huggingface.co/kaishuiji/vheart-affect-v8},
year = {2026}
}License
Apache 2.0 (matches Qwen2.5 base).
Acknowledgments
- Qwen team for the base model
- feltstate philosophy authors (same hands)
