Team Ai
Modelpublic

SandyVeliz/acervo-extractor-v2

sourceHugging Faceapache-2.0updated 6mo agoView on Hugging Face
0likes809downloads
Model Card

Acervo Extractor v2

A fine-tuned version of Qwen3.5-9B specialized in knowledge graph extraction from conversations. Given a conversation turn and existing graph context, the model outputs structured JSON with intent classification, topic detection, retrieval decision, entities, relations, and facts.

Base model: Qwen3.5-9B | Method: QLoRA (4-bit, r=16, alpha=32) | Training: ~1,000 examples, 3 epochs

Built for Acervo — a semantic compression layer for AI agents that replaces raw conversation history with compressed knowledge graph nodes.

Supersedes: acervo-extractor-qwen3.5-9b (v1, deprecated)

What's new in v2

v1 only handled topic detection and entity extraction. v2 adds intent classification and retrieval decision — two fields that were previously handled by regex/keyword heuristics outside the model.

Featurev1v2
Topic detectionsame / subtopic / changedsame / subtopic / changed
Intent classification-overview / specific / chat / followup
Retrieval decision-summaryonly / withchunks
Entity extraction8 types, 15 relations8 types, 15 relations
Code extraction-Extract entities from code snippets
Document extraction-Extract from READMEs, changelogs, docs
Prose extraction-Extract characters, locations from literature
Training examples612~1,000
S1 Intent accuracy78%92%+ (target)

Why intent matters

v1 benchmarks showed 78% intent accuracy — the model classified overview questions as specific (6 out of 9 failures). This cascaded: wrong intent led to wrong retrieval strategy (56% S2 accuracy) and wrong budget allocation (32% S3 accuracy).

v2 trains the model to classify intent directly, replacing the external regex classifier.

Why retrieval matters

The retrieval field tells the system whether to fetch full document chunks or just use node summaries:

  • —summary_only — for overview questions, chat, conceptual queries (cheaper, faster)
  • —with_chunks — for code lookups, specific facts, detailed analysis (needs raw content)

Output schema

v1 output (deprecated)

json
{
  "topic": {"action": "same|changed|subtopic", "label": "..."},
  "entities": [...],
  "relations": [...],
  "facts": [...]
}

v2 output (new fields highlighted)

json
{
  "intent": "overview|specific|chat|followup",     // NEW
  "topic": {"action": "same|changed|subtopic", "label": "..."},
  "retrieval": "summary_only|with_chunks",          // NEW
  "entities": [...],
  "relations": [...],
  "facts": [...]
}

Intent types

IntentDescriptionExamples
overviewHigh-level summary, counts, listings, general info"What is this project?", "How many files?", "Give me a summary"
specificPrecise detail, specific code, particular fact"How does auth work?", "Show me the controller", "What's the deadline?"
chatCasual conversation, acknowledgments, opinions"Thanks", "That's interesting", "Ok", "Good job"
followupContinuing previous topic with more depth"Tell me more", "What about the other one?", "Expand on that"

Examples

Intent: overview

USER: What is this project about?
json
{
  "intent": "overview",
  "topic": {"action": "same", "label": null},
  "retrieval": "summary_only",
  "entities": [],
  "relations": [],
  "facts": []
}

Intent: specific (with extraction)

USER: Beacon ya tiene 50 mil usuarios y estamos migrando a Kubernetes.
json
{
  "intent": "specific",
  "topic": {"action": "same", "label": null},
  "retrieval": "with_chunks",
  "entities": [
    {
      "id": "kubernetes",
      "label": "Kubernetes",
      "type": "technology",
      "layer": "UNIVERSAL",
      "attributes": {},
      "facts": [],
      "existing_id": null
    }
  ],
  "relations": [
    {"source": "beacon", "target": "kubernetes", "relation": "uses_technology"}
  ],
  "facts": [
    {"entity": "beacon", "text": "Has 50,000 users", "speaker": "user"}
  ]
}

Intent: chat (empty output)

USER: That's interesting, thanks!
json
{
  "intent": "chat",
  "topic": {"action": "same", "label": null},
  "retrieval": "summary_only",
  "entities": [],
  "relations": [],
  "facts": []
}

Intent: followup

PREVIOUS ASSISTANT: The auth module uses JWT tokens with 24-hour expiry.
USER: Tell me more about that.
json
{
  "intent": "followup",
  "topic": {"action": "same", "label": null},
  "retrieval": "with_chunks",
  "entities": [],
  "relations": [],
  "facts": []
}

Key capabilities

CapabilityDescription
Intent classificationClassifies user intent to drive retrieval strategy
Retrieval decisionDecides summaryonly vs withchunks for downstream pipeline
BilingualHandles English and Spanish input natively
Empty outputReturns empty arrays for small talk and pure queries (no hallucinated entities)
Dedup awarenessReferences existing nodes via existing_id instead of creating duplicates
Code extractionExtracts technologies, patterns, and dependencies from code snippets
Document extractionExtracts entities from READMEs, changelogs, sprint reviews, API docs
Prose extractionExtracts characters, locations, events from literature and narratives
Controlled vocabularyUses strict enums for types (8) and relations (15)
Topic detectionClassifies same/subtopic/changed with optional hint from upstream classifiers

Training details

ParameterValue
Base modelQwen/Qwen3.5-9B
MethodLoRA (QLoRA 4-bit, r=16, alpha=32)
FrameworkUnsloth + Transformers + TRL
Dataset size~1,000 examples
Trainingv1 base (3 epochs, lr=2e-4) + v2 incremental (2 epochs, lr=5e-5) + v3 intent+retrieval (3 epochs, lr=5e-5)
Max sequence length2048
LanguagesEnglish (~65%), Spanish (~35%)
HardwareNVIDIA RTX 5070 Ti (16GB VRAM)

Dataset composition

CategoryCountDescription
Conversation extraction (v1)350Facts, entities, relations from conversations
Topic detection (v1)120Topic changes, subtopics
Empty output (v1)90Small talk, queries with no extraction
Corrections / dedup (v1)52"We switched from React to Vue", existing references
Stress / edge cases (v1)22Edge cases from v1 testing
Intent classification (v2)100Overview, specific, chat, followup examples
Retrieval decision (v2)80summaryonly vs withchunks
Code extraction (v2)50TypeScript, Python, YAML, Docker, SQL
Literature extraction (v2)40Characters, locations, events from prose
Documentation extraction (v2)40READMEs, changelogs, sprint reviews, API docs
S1.5 improvement (v2)30Extracting from assistant responses
S1 failure variations (v2)50Variations of 9 v0.4 benchmark failures

Schema

Entity types (enum)

person, organization, project, technology, place, event, document, concept

Relation types (enum)

part_of, created_by, maintains, works_at, member_of,
uses_technology, depends_on, alternative_to,
located_in, deployed_on, produces, serves, documented_in,
participated_in, triggered_by, resulted_in

Layers

  • —PERSONAL — user owns, created, or directly uses it
  • —UNIVERSAL — public knowledge (technologies, fictional characters, cities)

Usage

With LM Studio / Ollama (GGUF)

Download the GGUF file from the gguf/ folder and load in LM Studio. The model appears as acervo-extractor-v2.

With Transformers + LoRA

python
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.5-9B", device_map="auto")
model = PeftModel.from_pretrained(base_model, "SandyVeliz/acervo-extractor-v2")
tokenizer = AutoTokenizer.from_pretrained("SandyVeliz/acervo-extractor-v2")

messages = [
    {"role": "system", "content": "You are a knowledge extractor for a personal knowledge graph. Analyze the conversation and return a single JSON object with: intent, topic, retrieval, entities, relations, and facts.\n\nIntent — classify the user's intent:\n- \"overview\": user wants a high-level summary, project description, general information, counts, or listings.\n- \"specific\": user wants a precise detail, specific code, a particular fact, or a specific section.\n- \"chat\": casual conversation, greetings, acknowledgments, opinions, or thanks.\n- \"followup\": continuing the previous topic with more depth, \"tell me more\", or referencing something just discussed.\n\nRetrieval — decide what data the system should fetch:\n- \"summary_only\": the node summary is enough (overview, chat, conceptual questions).\n- \"with_chunks\": the user needs specific content from documents (code lookups, specific facts, detailed analysis).\n\nOutput valid JSON only, no markdown, no explanation."},
    {"role": "user", "content": "EXISTING NODES:\n[]\n\nTOPIC HINT: unresolved\nCURRENT TOPIC: null\n\nPREVIOUS ASSISTANT: null\nUSER: I work at Acme Corp building a React app called Beacon with PostgreSQL."}
]

inputs = tokenizer.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True)
outputs = model.generate(inputs.to(model.device), max_new_tokens=1024, temperature=0.1)
print(tokenizer.decode(outputs[0][inputs.shape[-1]:], skip_special_tokens=True))

With Unsloth (recommended for inference)

python
from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    "SandyVeliz/acervo-extractor-v2",
    max_seq_length=2048, load_in_4bit=True,
)
FastLanguageModel.for_inference(model)

With Acervo (intended use)

python
from acervo import Acervo, OpenAIClient

llm = OpenAIClient(base_url="http://localhost:1234/v1", model="acervo-extractor-v2")
memory = Acervo(llm=llm, owner="user")

Intended use

This model is designed as the extraction component inside Acervo, a semantic compression layer for AI agents. It replaces general-purpose LLM calls for topic detection, intent classification, and entity extraction with a specialized, faster model.

It can also be used standalone for:

  • —Building knowledge graphs from conversations
  • —Structured entity/relation extraction from text
  • —Topic detection in multi-turn dialogues
  • —Intent classification for conversational AI
  • —Retrieval strategy decisions (RAG pipelines)

Version history

VersionRepoExamplesKey changes
v1acervo-extractor-qwen3.5-9b612Topic detection + entity extraction
v2acervo-extractor-v2~1,000+ Intent classification, retrieval decision, code/doc/prose extraction

License

Apache 2.0 — same as the base model.