|
Download README.md from CLS-Lab/narrative-event-relation-roberta: direct link, hf CLI and curl.
- Browser
- Download file 3.42 kB
-
https://huggingface.co/CLS-Lab/narrative-event-relation-roberta/resolve/main/README.md
- Command line
-
hf download hf://CLS-Lab/narrative-event-relation-roberta/README.md
-
curl -L -o README.md https://huggingface.co/CLS-Lab/narrative-event-relation-roberta/resolve/main/README.md
3.42 kB
| base_model: roberta-base | |
| language: en | |
| tags: | |
| - narrative | |
| - text-classification | |
| - pytorch | |
| # narrative-event-relation-roberta | |
| RoBERTa-base fine-tuned for event relation identification: binary temporal (sequential vs non-sequential) and causal classification. Uses entity markers [E1]/[E2] inserted at character offsets. Trained on LLM pseudo-labels with held-out human gold evaluation. | |
| > **Note:** Full model card with training details coming soon. | |
| ## Loading | |
| Download `model.pt` and `tokenizer/` from this repo, then: | |
| ```python | |
| import torch | |
| from transformers import AutoModel, AutoTokenizer | |
| from torch import nn | |
| ENTITY_MARKERS = ["[E1]", "[/E1]", "[E2]", "[/E2]"] | |
| class EventRelationRoBERTa(nn.Module): | |
| def __init__(self, model_name, n_new_tokens): | |
| super().__init__() | |
| self.backbone = AutoModel.from_pretrained(model_name) | |
| # Required: training resized the vocab for the 4 entity markers. | |
| # Without this, load_state_dict fails on an embedding size mismatch. | |
| self.backbone.resize_token_embeddings(self.backbone.config.vocab_size + n_new_tokens) | |
| hidden = self.backbone.config.hidden_size | |
| self.temporal_head = nn.Linear(hidden, 1) | |
| self.causal_head = nn.Linear(hidden, 1) | |
| def forward(self, input_ids, attention_mask): | |
| cls = self.backbone(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state[:, 0, :] | |
| return self.temporal_head(cls).squeeze(-1), self.causal_head(cls).squeeze(-1) | |
| tokenizer = AutoTokenizer.from_pretrained("tokenizer/") | |
| model = EventRelationRoBERTa("roberta-base", len(ENTITY_MARKERS)) | |
| model.load_state_dict(torch.load("model.pt", map_location="cpu", weights_only=True)) | |
| model.eval() | |
| ``` | |
| ## Input format | |
| The model takes a single string with the two candidate event triggers wrapped in | |
| entity markers at their character offsets. It never sees spans as structured input. | |
| ```python | |
| def insert_markers(text, span1, span2): | |
| """span1/span2 are [char_start, char_end, ...]; span1 must precede span2.""" | |
| insertions = sorted([ | |
| (span1[0], "[E1]"), (span1[1], "[/E1]"), | |
| (span2[0], "[E2]"), (span2[1], "[/E2]"), | |
| ], key=lambda x: -x[0]) | |
| for pos, marker in insertions: | |
| text = text[:pos] + marker + text[pos:] | |
| return text | |
| text = "She opened the door and the cat escaped." | |
| marked = insert_markers(text, [4, 10], [32, 39]) | |
| # 'She [E1]opened[/E1] the door and the cat [E2]escaped[/E2].' | |
| enc = tokenizer(marked, max_length=256, padding="max_length", | |
| truncation=True, return_tensors="pt") | |
| with torch.no_grad(): | |
| t_logit, c_logit = model(enc["input_ids"], enc["attention_mask"]) | |
| # Raw logits; threshold at 0 (equivalently, sigmoid > 0.5). | |
| is_sequential = bool(t_logit > 0) # temporal: sequential vs not | |
| is_causal = bool(c_logit > 0) # causal: causally related vs not | |
| ``` | |
| Note `max_length=256`: markers pushed past that limit are truncated away and the | |
| prediction becomes meaningless. Check that both markers survive tokenization for | |
| long inputs. | |
| ## Config | |
| ```json | |
| { | |
| "model_name": "roberta-base", | |
| "max_len": 256, | |
| "dims": [ | |
| "temporal_sequential", | |
| "causal" | |
| ], | |
| "data_source": "/projects/tejo9855/Projects/llm-narrative-annotations/event_relation/outputs/google_gemma-4-31B-it/20260518_143249", | |
| "n_train": 6219, | |
| "n_val": 690, | |
| "val_frac": 0.1, | |
| "best_epoch": 4, | |
| "seed": 42, | |
| "test_f1_gold": 0.805 | |
| } | |
| ``` | |