phuongntc commited on
Commit
e1c2520
·
verified ·
1 Parent(s): 64f0a96

Initial release: backbone (videberta), trunk+3 heads, configs, loader, README

Browse files
README.md ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Vietnamese Summary Evaluator (videberta-base + trunk + 3 heads)
2
+
3
+ **What is this?** A multi-criteria evaluator that predicts three scores in **[0,1]**:
4
+ **faithfulness**, **coherence**, **relevance** for a *(document, summary)* pair.
5
+
6
+ **Architecture.** Vietnamese encoder backbone → mean pooling → shared MLP trunk → three linear heads.
7
+
8
+ **Training (short).**
9
+ - Multi-task regression (MSE) + in-document pairwise hinge ranking (doc_id grouping).
10
+ - Tokenization: pair (doc, summary), truncation='only_first', pre-trim summary to 256, max_len=512.
11
+ - See `training_args.json`, `loss_config.json`, and `arch_config.json` for details.
12
+
13
+ **Files**
14
+ - `config.json`, `model.safetensors` (+ tokenizer files): backbone encoder
15
+ - `trunk.pt`, `head_faith.pt`, `head_coh.pt`, `head_rel.pt`: lightweight heads
16
+ - `arch_config.json`, `training_args.json`, `loss_config.json`, `package_versions.json`
17
+ - `modeling_summary_evaluator.py`: loader & pair-encoding helpers
18
+
19
+ **Quickstart**
20
+ ```python
21
+ from huggingface_hub import snapshot_download
22
+ import importlib.util, os
23
+ repo = snapshot_download("summary-evaluator-export", repo_type="model")
24
+ spec = importlib.util.spec_from_file_location("mse", os.path.join(repo, "modeling_summary_evaluator.py"))
25
+ mse = importlib.util.module_from_spec(spec); spec.loader.exec_module(mse)
26
+ model, tok, device = mse.load_for_inference(repo)
27
+ enc = mse.encode_pair(tok, ["Văn bản gốc..."], ["Bản tóm tắt..."])
28
+ import torch
29
+ with torch.inference_mode():
30
+ y = model(torch.tensor(enc["input_ids"]), torch.tensor(enc["attention_mask"]))
31
+ print(y) # [1, 3] in [0,1]
32
+
arch_config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backbone": "Fsoft-AIC/videberta-base",
3
+ "pooling": "mean",
4
+ "trunk": {
5
+ "type": "mlp",
6
+ "hidden_in": 768,
7
+ "hidden_mid": 256,
8
+ "activation": "gelu",
9
+ "dropout": 0.1
10
+ },
11
+ "heads": [
12
+ {
13
+ "name": "faith",
14
+ "type": "linear",
15
+ "in": 256,
16
+ "out": 1
17
+ },
18
+ {
19
+ "name": "coherence",
20
+ "type": "linear",
21
+ "in": 256,
22
+ "out": 1
23
+ },
24
+ {
25
+ "name": "relevance",
26
+ "type": "linear",
27
+ "in": 256,
28
+ "out": 1
29
+ }
30
+ ],
31
+ "labels": [
32
+ "faith",
33
+ "coherence",
34
+ "relevance"
35
+ ],
36
+ "output_range": [
37
+ 0.0,
38
+ 1.0
39
+ ]
40
+ }
config.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "DebertaV2Model"
4
+ ],
5
+ "attention_head_size": 64,
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "hidden_act": "gelu",
8
+ "hidden_dropout_prob": 0.1,
9
+ "hidden_size": 768,
10
+ "initializer_range": 0.02,
11
+ "intermediate_size": 3072,
12
+ "layer_norm_eps": 1e-07,
13
+ "legacy": true,
14
+ "max_position_embeddings": 512,
15
+ "max_relative_positions": -1,
16
+ "model_type": "deberta-v2",
17
+ "norm_rel_ebd": "layer_norm",
18
+ "num_attention_heads": 12,
19
+ "num_hidden_layers": 12,
20
+ "pad_token_id": 0,
21
+ "pooler_dropout": 0,
22
+ "pooler_hidden_act": "gelu",
23
+ "pooler_hidden_size": 768,
24
+ "pos_att_type": [
25
+ "p2c",
26
+ "c2p"
27
+ ],
28
+ "position_biased_input": false,
29
+ "position_buckets": 256,
30
+ "relative_attention": true,
31
+ "share_att_key": true,
32
+ "torch_dtype": "float32",
33
+ "transformers_version": "4.55.2",
34
+ "type_vocab_size": 0,
35
+ "vocab_size": 128000
36
+ }
head_coh.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:51a1469f613813174f3d946d19f9647af96c27d3a5fa58af8ef85e965f3e60a1
3
+ size 2925
head_faith.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2722ed6202c5109dafe6c041466292dcf94e8ad28a95c1279da763852e8518d0
3
+ size 2941
head_rel.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:836d2862414e4d666a14dc0a38745ddca3db4c252e31245220da6cfc9ba5aadd
3
+ size 2925
loss_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "regression": "MSE (3 heads)",
3
+ "ranking": "pairwise hinge in-document",
4
+ "rank_margin": 0.05,
5
+ "rank_weight": 0.3,
6
+ "task_weights_note": "equal per-criterion in rank aggregation"
7
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82a365606dcb1e125a9718a0840702c0f319da17f1cc9015cf43d753f0f691bc
3
+ size 735041640
modeling_summary_evaluator.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os, json, torch
3
+ from torch import nn
4
+ from transformers import AutoModel, AutoTokenizer
5
+
6
+ def mean_pool(last_hidden_state, attention_mask):
7
+ mask = attention_mask.unsqueeze(-1).type_as(last_hidden_state)
8
+ summed = (last_hidden_state * mask).sum(dim=1)
9
+ counts = mask.sum(dim=1).clamp(min=1e-9)
10
+ return summed / counts
11
+
12
+ class SummaryEvaluatorModule(nn.Module):
13
+ def __init__(self, base_model_dir):
14
+ super().__init__()
15
+ self.backbone = AutoModel.from_pretrained(base_model_dir)
16
+ with open(os.path.join(base_model_dir, "arch_config.json"), "r", encoding="utf-8") as f:
17
+ cfg = json.load(f)
18
+ hidden = cfg["trunk"]["hidden_in"]
19
+ self.trunk = nn.Sequential(
20
+ nn.Linear(hidden, cfg["trunk"]["hidden_mid"]),
21
+ nn.GELU(),
22
+ nn.Dropout(cfg["trunk"]["dropout"])
23
+ )
24
+ H = cfg["trunk"]["hidden_mid"]
25
+ self.head_faith = nn.Linear(H, 1)
26
+ self.head_coh = nn.Linear(H, 1)
27
+ self.head_rel = nn.Linear(H, 1)
28
+
29
+ # load weights
30
+ self.trunk.load_state_dict(torch.load(os.path.join(base_model_dir, "trunk.pt"), map_location="cpu"))
31
+ self.head_faith.load_state_dict(torch.load(os.path.join(base_model_dir, "head_faith.pt"), map_location="cpu"))
32
+ self.head_coh.load_state_dict(torch.load(os.path.join(base_model_dir, "head_coh.pt"), map_location="cpu"))
33
+ self.head_rel.load_state_dict(torch.load(os.path.join(base_model_dir, "head_rel.pt"), map_location="cpu"))
34
+ self.eval()
35
+
36
+ @torch.no_grad()
37
+ def forward(self, input_ids, attention_mask):
38
+ out = self.backbone(input_ids=input_ids, attention_mask=attention_mask)
39
+ pooled = mean_pool(out.last_hidden_state, attention_mask)
40
+ z = self.trunk(pooled)
41
+ y = torch.cat([self.head_faith(z), self.head_coh(z), self.head_rel(z)], dim=1)
42
+ return y # [B, 3] in [0,1]
43
+
44
+ def load_for_inference(base_model_dir, device=None):
45
+ tok = AutoTokenizer.from_pretrained(base_model_dir, use_fast=True)
46
+ mdl = SummaryEvaluatorModule(base_model_dir)
47
+ if device is None:
48
+ device = "cuda" if torch.cuda.is_available() else "cpu"
49
+ mdl.to(device).eval()
50
+ return mdl, tok, device
51
+
52
+ def encode_pair(tokenizer, docs, sums, max_len=512, sum_max_len=256):
53
+ # 1) pre-trim summary
54
+ tok_sum = tokenizer(
55
+ sums, truncation=True, max_length=sum_max_len,
56
+ add_special_tokens=False, return_attention_mask=False
57
+ )
58
+ trimmed = tokenizer.batch_decode(
59
+ tok_sum["input_ids"], skip_special_tokens=True, clean_up_tokenization_spaces=True
60
+ )
61
+ # 2) pair-encode: cắt doc, giữ summary
62
+ enc = tokenizer(
63
+ docs, trimmed, truncation="only_first", max_length=max_len,
64
+ add_special_tokens=True, return_attention_mask=True
65
+ )
66
+ return enc
package_versions.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "python": "3.12.11 (main, Jun 4 2025, 08:56:18) [GCC 11.4.0]",
3
+ "platform": "Linux-6.1.123+-x86_64-with-glibc2.35",
4
+ "torch": "2.8.0+cu126"
5
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
training_args.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "datetime": "2025-08-27T03:12:03.073215Z",
3
+ "seed": 42,
4
+ "max_len": 512,
5
+ "sum_max_len": 256,
6
+ "truncation": "only_first",
7
+ "pad_to_multiple_of": 8,
8
+ "batch_size": 8,
9
+ "accumulate_grad_batches": 2,
10
+ "precision": "16-mixed",
11
+ "optimizer": "AdamW",
12
+ "lr": 2e-05,
13
+ "weight_decay": 0.01,
14
+ "scheduler": "linear_warmup",
15
+ "warmup_ratio": 0.05,
16
+ "gradient_clip_val": 1.0
17
+ }
trunk.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3d866acd99cade7e84b7f99a2bd705d20f92d00bad73f45bc6607a9c60f9e8b4
3
+ size 789269