Views
No views yet
answerdotai/ModernBERT-large] for sequence classification on pairs of (trial space, patient summary).Important: This is a research prototype for model development, not a medical device and not intended for clinical decision-making.
['patient_summary', 'this_space']
text = this_space + "\nNow here is the patient summary:" + patient_summary
eligibility_result as the binary label (0/1)answerdotai/ModernBERT-largelearning_rate=2e-5, weight_decay=0.01per_device_train_batch_size=82epochAutoTokenizer.from_pretrained("answerdotai/ModernBERT-large")DataCollatorWithPadding1import torch
2from transformers import AutoTokenizer, AutoModelForSequenceClassification
3
4device = "cuda" if torch.cuda.is_available() else "cpu"
5MODEL_REPO = "ksg-dfci/TrialChecker-1225"
6
7tok = AutoTokenizer.from_pretrained(MODEL_REPO)
8model = AutoModelForSequenceClassification.from_pretrained(MODEL_REPO).to(device)
9model.eval()
10
11this_space = (
12 "Age allowed: Any. "
13 "Sex allowed: Male or female. "
14 "Cancer type allowed: non-small cell lung cancer. "
15 "Histology allowed: adenocarcinoma. "
16 "Cancer burden allowed: metastatic disease. "
17 "Prior treatment required: prior platinum-based chemo-immunotherapy allowed. "
18 "Biomarkers required: ALK fusion."
19)
20
21patient_summary = (
22 "Age: 65"
23 "Sex: Male"
24 "Cancer type: Non-small cell lung cancer"
25 "Histology: Adenocarcinoma"
26 "Cancer burden: Metastatic"
27 "Biomarkers: ALK fusion detected by NGS"
28 "Treatment history: Alectinib since 2023"
29)
30
31text = this_space + "\nNow here is the patient summary:" + patient_summary
32
33# Raw Transformers model
34enc = tok(text, return_tensors="pt", truncation=True, max_length=4096).to(device)
35with torch.no_grad():
36 logits = model(**enc).logits
37probs = logits.softmax(-1).squeeze(0)
38
39# Label mapping was set in training: {0: "NEGATIVE", 1: "POSITIVE"}
40p_positive = float(probs[1])
41print(f"Reasonable consideration probability: {p_positive:.3f}")
42
43# Or pipeline API to get similar outputs
44from trasnformers import pipeline
45pipe = pipeline('text-classification', 'ksg-dfci/TrialChecker-1225')
46pipe([text])
471from typing import List
2import torch
3
4def score_pairs(spaces: List[str], summaries: List[str], tokenizer, model, max_length=4096, batch_size=8):
5 assert len(spaces) == len(summaries)
6 device = next(model.parameters()).device
7 scores = []
8
9 for i in range(0, len(spaces), batch_size):
10 batch_spaces = spaces[i:i+batch_size]
11 batch_summaries = summaries[i:i+batch_size]
12 texts = [s + "\nNow here is the patient summary:" + p for s, p in zip(batch_spaces, batch_summaries)]
13 enc = tokenizer(texts, return_tensors="pt", padding=True, truncation=True, max_length=max_length).to(device)
14 with torch.no_grad():
15 logits = model(**enc).logits
16 probs = logits.softmax(-1)[:, 1] # POSITIVE
17 scores.extend(probs.detach().cpu().tolist())
18 return scores
19
20# Example
21spaces = [this_space] * 3
22summaries = [patient_summary, "Different summary 1...", "Different summary 2..."]
23scores = score_pairs(spaces, summaries, tok, model)
24print(scores)OncoReasoning-3B-1225 model for summarization and space extraction), but the classifier accepts any plain strings in the format shown above.1# 1) Load and merge three labeled sources
2# - space_specific_eligibility_checks.parquet
3# - top_ten_cohorts_checked_round{1,2,3}.csv
4# - top_twenty_patients_checked_round{1,2,3}.csv
5
6# 2) Deduplicate by ['patient_summary','this_space'] and keep:
7# - split, patient_summary, this_space, eligibility_result
8
9# 3) Compose input text and label:
10text = this_space + "\nNow here is the patient summary:" + patient_summary
11label = int(eligibility_result) # 0 or 1
12
13# 4) Tokenize with ModernBERT tokenizer (max_length=4096, truncation=True)
14# 5) Train AutoModelForSequenceClassification, which then produces probabilities for the "POSITIVE" class (trial is a reasonable consideration) and for the "NEGATIVE" class (trial is not a reasonable consideration)