HugoGiddins commited on
Commit
fe5f8ee
·
verified ·
1 Parent(s): c1784b1

Release REM matcher (v10b checkpoint used as the RL reward)

Browse files
Files changed (6) hide show
  1. README.md +99 -0
  2. calibration.json +10 -0
  3. config.json +47 -0
  4. model.safetensors +3 -0
  5. tokenizer.json +0 -0
  6. tokenizer_config.json +24 -0
README.md ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ library_name: transformers
4
+ pipeline_tag: text-classification
5
+ base_model: microsoft/deberta-v3-large
6
+ language:
7
+ - en
8
+ tags:
9
+ - cross-encoder
10
+ - reward-model
11
+ - forecasting
12
+ ---
13
+
14
+ # REM matcher
15
+
16
+ A DeBERTa-v3-large cross-encoder that decides whether a predicted move by a named actor is the same
17
+ response-equivalent move (REM) as a realized one. It is the learned matcher used as the reinforcement
18
+ learning reward in *Toward Simulating Real-World Actors: Training Small Language Models to Predict
19
+ Their Next Moves*.
20
+
21
+ ## Input
22
+
23
+ The model reads a text pair. Each side is the actor's name followed by a move:
24
+
25
+ ```
26
+ Actor context: {actor}
27
+ Action: {move}
28
+ ```
29
+
30
+ During training, actors with known aliases were written as `{actor}; aliases: {alias1}; {alias2}`.
31
+ The predicted move goes first and the realized (target) move second. Pairs are truncated to 512 tokens.
32
+ Labels are `no` (0) and `yes` (1).
33
+
34
+ ## Calibrated probability
35
+
36
+ Raw softmax scores are not calibrated. Use the Platt scaling in `calibration.json` on the logit margin:
37
+
38
+ ```
39
+ p_match = sigmoid((logit_yes - logit_no) / temperature + bias)
40
+ ```
41
+
42
+ ```python
43
+ import json, torch
44
+ from huggingface_hub import hf_hub_download
45
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
46
+
47
+ repo = "HiddenSystemsAI/rem-matcher"
48
+ tokenizer = AutoTokenizer.from_pretrained(repo)
49
+ model = AutoModelForSequenceClassification.from_pretrained(repo).eval()
50
+ cal = json.load(open(hf_hub_download(repo, "calibration.json")))
51
+
52
+ def side(actor, move):
53
+ return f"Actor context: {actor}\nAction: {move}"
54
+
55
+ actor = "Bitget"
56
+ pairs = [
57
+ (side(actor, "Bitget resumes withdrawals"), side(actor, "Bitget reopens withdrawals for users")),
58
+ (side(actor, "Bitget offers a bounty for the stolen funds"), side(actor, "Bitget reopens withdrawals for users")),
59
+ ]
60
+ batch = tokenizer([a for a, _ in pairs], [b for _, b in pairs], padding=True,
61
+ truncation=True, max_length=512, return_tensors="pt")
62
+ with torch.inference_mode():
63
+ logits = model(**batch).logits.float()
64
+ p = torch.sigmoid((logits[:, 1] - logits[:, 0]) / cal["temperature"] + cal["bias"])
65
+ print(p.tolist())
66
+ ```
67
+
68
+ In the paper's reward a predicted move credits a target when `p_match >= 0.75`, and two predicted moves
69
+ count as duplicates when `p_match >= 0.8`.
70
+
71
+ ## Training
72
+
73
+ The model was initialized from an earlier ordinal matcher of the same architecture, with a new two-class
74
+ head trained by cross-entropy for one epoch (learning rate 1e-5, effective batch 32). All pair labels
75
+ come from Claude models (Sonnet labels, a blind second pass on borderline pairs, Opus adjudication).
76
+ Splits are disjoint by scenario; the test split holds only real pairs of model-predicted and realized
77
+ moves from held-out stories.
78
+
79
+ | Split | Pairs | Positives | Scenarios |
80
+ |---|---:|---:|---:|
81
+ | Train | 81,439 | 43,904 | 397 |
82
+ | Development | 7,148 | 3,709 | 37 |
83
+ | Calibration | 7,937 | 4,367 | 45 |
84
+ | Test (real pairs) | 4,048 | 667 | 54 |
85
+
86
+ ## Evaluation
87
+
88
+ On the 4,048 held-out real test pairs, with calibrated probabilities at a 0.5 threshold:
89
+ accuracy 94.4%, precision 83.4%, recall 82.6%, expected calibration error 0.017.
90
+ The paper reports precision and recall at the 0.75 training gate and compares the matcher's credits
91
+ with a three-judge panel on the benchmark lists.
92
+
93
+ ## Limitations
94
+
95
+ The matcher was trained and evaluated on news-derived moves of governments, companies and other public
96
+ actors, written at the REM level. It undercounts matches that human-style judges accept (it misses
97
+ about a fifth to a third of judged matches on the paper's benchmark), and optimizing a policy against
98
+ it can raise its score faster than judged recall. Use it as a training signal or for grouping moves,
99
+ not as an evaluation metric on its own.
calibration.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "temperature": 1.7073526474706913,
3
+ "bias": -0.4470148298452159,
4
+ "decision_threshold": 0.5,
5
+ "confidence_threshold": 0.8,
6
+ "method": "platt_on_logit_margin",
7
+ "positive_label": "yes",
8
+ "probability_scope": "L2 matching on the held-out pair distribution",
9
+ "max_length": 512
10
+ }
config.json ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "DebertaV2ForSequenceClassification"
4
+ ],
5
+ "attention_probs_dropout_prob": 0.1,
6
+ "bos_token_id": 1,
7
+ "dtype": "float32",
8
+ "eos_token_id": 2,
9
+ "hidden_act": "gelu",
10
+ "hidden_dropout_prob": 0.1,
11
+ "hidden_size": 1024,
12
+ "id2label": {
13
+ "0": "no",
14
+ "1": "yes"
15
+ },
16
+ "initializer_range": 0.02,
17
+ "intermediate_size": 4096,
18
+ "label2id": {
19
+ "no": 0,
20
+ "yes": 1
21
+ },
22
+ "layer_norm_eps": 1e-07,
23
+ "legacy": true,
24
+ "max_position_embeddings": 512,
25
+ "max_relative_positions": -1,
26
+ "model_type": "deberta-v2",
27
+ "norm_rel_ebd": "layer_norm",
28
+ "num_attention_heads": 16,
29
+ "num_hidden_layers": 24,
30
+ "pad_token_id": 0,
31
+ "pooler_dropout": 0,
32
+ "pooler_hidden_act": "gelu",
33
+ "pooler_hidden_size": 1024,
34
+ "pos_att_type": [
35
+ "p2c",
36
+ "c2p"
37
+ ],
38
+ "position_biased_input": false,
39
+ "position_buckets": 256,
40
+ "relative_attention": true,
41
+ "share_att_key": true,
42
+ "tie_word_embeddings": true,
43
+ "transformers_version": "5.13.1",
44
+ "type_vocab_size": 0,
45
+ "use_cache": false,
46
+ "vocab_size": 128100
47
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:89a34874abc5ac6842ff3227925cc5e6886f94841a2dc8aa17007cd607610aa0
3
+ size 1740304440
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": true,
3
+ "backend": "tokenizers",
4
+ "bos_token": "[CLS]",
5
+ "cls_token": "[CLS]",
6
+ "do_lower_case": false,
7
+ "eos_token": "[SEP]",
8
+ "is_local": false,
9
+ "local_files_only": false,
10
+ "mask_token": "[MASK]",
11
+ "max_length": 512,
12
+ "model_max_length": 512,
13
+ "pad_token": "[PAD]",
14
+ "sep_token": "[SEP]",
15
+ "sp_model_kwargs": {},
16
+ "split_by_punct": false,
17
+ "stride": 0,
18
+ "tokenizer_class": "DebertaV2Tokenizer",
19
+ "truncation_side": "right",
20
+ "truncation_strategy": "longest_first",
21
+ "unk_id": 3,
22
+ "unk_token": "[UNK]",
23
+ "vocab_type": "spm"
24
+ }