Feature Extraction
Transformers
Safetensors
Italian
radgraph_it
radiology
information-extraction
named-entity-recognition
relation-extraction
medical
radgraph
custom_code
Instructions to use radgraphIT/Radgraph-IT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use radgraphIT/Radgraph-IT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="radgraphIT/Radgraph-IT", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("radgraphIT/Radgraph-IT", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 2,733 Bytes
0c48771 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | """Span representations: concat(start word embedding, end word embedding, [mean-pooled interior
embedding], width embedding).
Port of AllenNLP's `EndpointSpanExtractor(combination="x,y", bucket_widths=False)`, the only
configuration v1 used. v2 adds an optional mean-pooled block -- the average of every word
embedding inside [start, end] inclusive -- gated by `mean_pool` (see notes/v2_plan.md item 3,
`configs/medbit_span_pooling/`). Simplified for the batch_size=1 case (see dataset.py): no batch
dimension, no span masking -- every document has an exact, un-padded list of spans.
"""
import torch
from torch import nn
class EndpointSpanExtractor(nn.Module):
def __init__(self, input_dim: int, num_width_embeddings: int, span_width_embedding_dim: int,
mean_pool: bool = False):
super().__init__()
self.width_embedding = nn.Embedding(num_width_embeddings, span_width_embedding_dim)
self.mean_pool = mean_pool
self.output_dim = (3 if mean_pool else 2) * input_dim + span_width_embedding_dim
def get_output_dim(self) -> int:
return self.output_dim
def forward(self, word_embeddings: torch.Tensor, spans: torch.LongTensor) -> torch.Tensor:
"""word_embeddings: (num_words, input_dim). spans: (num_spans, 2) inclusive [start, end]."""
starts, ends = spans[:, 0], spans[:, 1]
start_emb = word_embeddings[starts]
end_emb = word_embeddings[ends]
width_emb = self.width_embedding(ends - starts) # 0-indexed width (widths 1..N -> 0..N-1)
if not self.mean_pool:
return torch.cat([start_emb, end_emb, width_emb], dim=-1)
mean_emb = self._interior_mean(word_embeddings, starts, ends)
return torch.cat([start_emb, end_emb, mean_emb, width_emb], dim=-1)
@staticmethod
def _interior_mean(word_embeddings: torch.Tensor, starts: torch.LongTensor,
ends: torch.LongTensor) -> torch.Tensor:
"""Mean of word_embeddings[start:end+1] per span, vectorized over the whole (bounded-
width) span list: gather a (num_spans, max_width) index grid and masked-average it. No
cumsum needed -- widths are capped by max_span_width (e.g. 12)."""
widths = ends - starts + 1 # (num_spans,)
max_width = int(widths.max().item())
offsets = torch.arange(max_width, device=word_embeddings.device).unsqueeze(0) # (1, W)
mask = offsets < widths.unsqueeze(1) # (num_spans, W)
idx = (starts.unsqueeze(1) + offsets).clamp(max=word_embeddings.size(0) - 1)
gathered = word_embeddings[idx] * mask.unsqueeze(-1) # (num_spans, W, input_dim)
return gathered.sum(dim=1) / widths.unsqueeze(1).to(word_embeddings.dtype)
|