AlaBoussoffara's picture
organized code and set up chainlit for demos
2d52135
Raw
History Blame Contribute Delete
1.76 kB
"""Lightweight language-model head projecting hidden states to vocab logits."""
from __future__ import annotations
import torch
import torch.nn as nn
from torch import Tensor
__all__ = ["LMHead"]
class LMHead(nn.Module):
"""
Language modeling head: projects hidden states to vocabulary logits.
Args:
d_model (int): Model hidden dimension (>0).
vocab_size (int): Vocabulary size (>0).
Input:
x (Tensor): shape (B, S, D) with D == d_model.
Output:
logits (Tensor): shape (B, S, V) with V == vocab_size.
"""
def __init__(self, d_model: int, vocab_size: int):
super().__init__()
if not isinstance(vocab_size, int):
raise TypeError(f"vocab_size must be an int, got {type(vocab_size)}")
if not isinstance(d_model, int):
raise TypeError(f"d_model must be an int, got {type(d_model)}")
if vocab_size <= 0:
raise ValueError(f"vocab_size must be strictly greater than 0, got {vocab_size}")
if d_model <= 0:
raise ValueError(f"d_model must be strictly greater than 0, got {d_model}")
self.d_model = d_model
self.vocab_size = vocab_size
self.fc = nn.Linear(d_model, vocab_size, bias=False)
def forward(self, x: Tensor) -> Tensor:
if not isinstance(x, torch.Tensor):
raise TypeError(f"x must be a torch.Tensor, got {type(x)}")
if x.dim() != 3:
raise ValueError(
f"x must be a 3D torch.Tensor of shape (B, S, D); got shape {tuple(x.shape)}"
)
B, S, D = x.shape
if D != self.d_model:
raise ValueError(f"Last dim {D} must match d_model {self.d_model}")
return self.fc(x) # (B, S, V)