qAIR / models /encoder.py
Md. Arafat Islam
qAIR — Quantum-Inspired Multi-Hypothesis Reasoning, Gradio demo.
feaa032
Raw
History Blame Contribute Delete
1.83 kB
import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModel
from config import EMBEDDING_MODEL, EMBEDDING_DIM, resolve_device
class HypothesisEncoder:
def __init__(
self,
model_name=EMBEDDING_MODEL,
device=None
):
self.device = device or resolve_device()
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModel.from_pretrained(model_name).to(self.device)
self.model.eval()
for p in self.model.parameters():
p.requires_grad = False
self.dim = self.model.config.hidden_size
if model_name == EMBEDDING_MODEL:
# Everything downstream (dataset.py, sample_inference.py, ...)
# reads dim from config.EMBEDDING_DIM rather than this instance,
# so a silent mismatch here would surface as a shape error far
# away from its cause. Catch it at the source instead.
assert self.dim == EMBEDDING_DIM, (
f"{model_name} produces {self.dim}-dim embeddings but "
f"config.EMBEDDING_DIM is {EMBEDDING_DIM}. Update config.py."
)
print(f"[ENCODER] Using {model_name}")
print(f"[ENCODER] Embedding dimension: {self.dim}")
@torch.no_grad()
def encode(self, texts):
inputs = self.tokenizer(
texts, padding=True, truncation=True, max_length=128, return_tensors="pt"
).to(self.device)
outputs = self.model(**inputs)
hidden = outputs.last_hidden_state
mask = inputs["attention_mask"].unsqueeze(-1)
pooled = (hidden * mask).sum(dim=1)
counts = mask.sum(dim=1)
pooled = pooled / counts.clamp(min=1e-9)
pooled = F.normalize(pooled, dim=-1)
return pooled