Sentence Similarity
sentence-transformers
PyTorch
Safetensors
Thai
feature-extraction
File size: 18,275 Bytes
81b8aa7
 
 
 
 
 
 
7fc47c7
 
 
 
 
 
 
 
81b8aa7
 
bff0bd5
81b8aa7
920ec9b
 
7fc47c7
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
 
 
81b8aa7
7fc47c7
 
 
 
 
 
 
 
 
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
 
 
81b8aa7
7fc47c7
 
 
81b8aa7
 
 
 
7fc47c7
81b8aa7
7fc47c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81b8aa7
7fc47c7
 
 
81b8aa7
7fc47c7
81b8aa7
7fc47c7
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
 
81b8aa7
7fc47c7
 
81b8aa7
7fc47c7
 
 
 
81b8aa7
 
7fc47c7
 
 
 
81b8aa7
7fc47c7
 
 
81b8aa7
7fc47c7
 
 
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
 
81b8aa7
7fc47c7
 
81b8aa7
7fc47c7
 
 
 
 
81b8aa7
 
7fc47c7
 
 
 
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
 
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
81b8aa7
7fc47c7
 
 
 
 
 
 
 
81b8aa7
 
7fc47c7
3703b98
 
7fc47c7
81b8aa7
7fc47c7
81b8aa7
7fc47c7
 
 
 
 
 
 
 
 
 
 
 
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
---
library_name: sentence-transformers
pipeline_tag: sentence-similarity
tags:
- sentence-transformers
- sentence-similarity
- feature-extraction
license: mit
datasets:
- airesearch/WangchanX-Legal-ThaiCCL-RAG
- VISAI-AI/nitibench
language:
- th
base_model:
- BAAI/bge-m3
---

# Human-Finetuned BGE-M3 CCL

**[[📄 Technical Report](https://arxiv.org/pdf/2502.10868)]**

This is a finetuned [`BAAI/bge-m3`](https://huggingface.co/BAAI/bge-m3) model on [`airesearch/WangchanX-Legal-ThaiCCL-RAG`](https://huggingface.co/datasets/airesearch/WangchanX-Legal-ThaiCCL-RAG) queries.

## Finetuning Details

Apart from the original [`airesearch/WangchanX-Legal-ThaiCCL-RAG`](https://huggingface.co/datasets/airesearch/WangchanX-Legal-ThaiCCL-RAG) which requires human to rerank and remove irrelevant documents, the model was finetuned on a completely automated environment.
Specifically, given the query in the WangchanX-Legal-ThaiCCL-RAG dataset and a set of law sections to be retrieved, we follow the following procedure:
1. Use [`BAAI/bge-m3`](https://huggingface.co/BAAI/bge-m3) to retrieve N positive law sections based on thresholding score of 0.8
2. Among those N documents, we use [`BAAI/bge-reranker-v2-m3`](https://huggingface.co/BAAI/bge-reranker-v2-m3) to rerank documents and filtered any document that reranker scores less than 0.8 - achieving final positive law sections
3. Using positives from (2), we finetuned BGE-M3 model

## Model Performance
| **Dataset**      | **Top-K** | **HR@k** | **Multi HR@k** | **Recall@k** | **MRR@k** | **Multi MRR@k** |
|:----------------:|:---------:|:-------:|:-------------:|:-----------:|:--------:|:---------------:|
| **NitiBench-CCL**    | 1         | 0.735   | –             | 0.735       | 0.735    | –               |
| **NitiBench-CCL**    | 5         | 0.906   | –             | 0.906       | 0.805    | –               |
| **NitiBench-CCL**    | 10        | 0.938   | –             | 0.938       | 0.809    | –               |
| **NitiBench-Tax**| 1         | 0.480   | 0.140         | 0.255       | 0.480    | 0.255           |
| **NitiBench-Tax**| 5         | 0.740   | 0.220         | 0.411       | 0.565    | 0.320           |
| **NitiBench-Tax**| 10        | 0.800   | 0.280         | 0.499       | 0.574    | 0.333           |

## Usage

Install: 
```
git clone https://github.com/FlagOpen/FlagEmbedding.git
cd FlagEmbedding
pip install -e .
```
or: 
```
pip install -U FlagEmbedding
```



### Generate Embedding for text

- Dense Embedding
```python
from FlagEmbedding import BGEM3FlagModel

model = BGEM3FlagModel('VISAI-AI/nitibench-ccl-human-finetuned-bge-m3',  
                       use_fp16=True) # Setting use_fp16 to True speeds up computation with a slight performance degradation

sentences_1 = ["What is BGE M3?", "Defination of BM25"]
sentences_2 = ["BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction.", 
               "BM25 is a bag-of-words retrieval function that ranks a set of documents based on the query terms appearing in each document"]

embeddings_1 = model.encode(sentences_1, 
                            batch_size=12, 
                            max_length=8192, # If you don't need such a long length, you can set a smaller value to speed up the encoding process.
                            )['dense_vecs']
embeddings_2 = model.encode(sentences_2)['dense_vecs']
similarity = embeddings_1 @ embeddings_2.T
print(similarity)
# [[0.6265, 0.3477], [0.3499, 0.678 ]]
```
You also can use sentence-transformers and huggingface transformers to generate dense embeddings.
Refer to [baai_general_embedding](https://github.com/FlagOpen/FlagEmbedding/tree/master/FlagEmbedding/baai_general_embedding#usage) for details.


- Sparse Embedding (Lexical Weight)
```python
from FlagEmbedding import BGEM3FlagModel

model = BGEM3FlagModel('VISAI-AI/nitibench-ccl-human-finetuned-bge-m3',  use_fp16=True) # Setting use_fp16 to True speeds up computation with a slight performance degradation

sentences_1 = ["สถาบันทางการเงินสามารถลงทุนในหลักทรัพย์ เป็นอัตราส่วนร้อยละสิบของเงินกองทุนทั้งหมดของสถาบันการเงินนั้น สำหรับการถือหรือมีหุ้นในทุกบริษัทรวมกันได้หรือไม่?",
               "ในกรณีที่ธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการของสถาบันการเงิน เนื่องสถาบันการเงินดำรงเงินกองทุนต่ำกว่าร้อยละสามสิบห้าของอัตราตามที่กำหนด จะต้องนำเสนอต่อบุคคลใดหรือหน่วยงานใดเพื่อเพิกถอนใบอนุญาตของสถาบันการเงินนั้น"]
sentences_2 = ["พระราชบัญญัติธุรกิจสถาบันการเงิน พ.ศ. 2551 มาตรา 33 ภายใต้บังคับมาตรา 34 และมาตรา 35 ให้สถาบันการเงินลงทุนในหลักทรัพย์เพื่อเป็นกรรมสิทธิ์ของตนได้ ตามหลักเกณฑ์ที่ธนาคารแห่งประเทศไทยประกาศกำหนด", 
               "พระราชบัญญัติธุรกิจสถาบันการเงิน พ.ศ. 2551 มาตรา 97 ในกรณีที่สถาบันการเงินดำรงเงินกองทุนต่ำกว่าร้อยละสามสิบห้าของอัตราตามที่กำหนดในมาตรา 30 ให้ธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการของสถาบันการเงินนั้น เว้นแต่ในกรณีที่ธนาคารแห่งประเทศไทยเห็นว่าการมีคำสั่งปิดกิจการจะก่อให้เกิดผลกระทบ หรือความเสียหายต่อระบบเศรษฐกิจโดยรวมอย่างรุนแรง ธนาคารแห่งประเทศไทยอาจยังไม่สั่งปิดกิจการของสถาบันการเงินก็ได้\nเมื่อธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการตามวรรคหนึ่งแล้ว ให้เสนอรัฐมนตรีเพิกถอนใบอนุญาตของสถาบันการเงินนั้น"]

output_1 = model.encode(sentences_1, return_dense=True, return_sparse=True, return_colbert_vecs=False)
output_2 = model.encode(sentences_2, return_dense=True, return_sparse=True, return_colbert_vecs=False)

# you can see the weight for each token:
print(model.convert_id_to_token(output_1['lexical_weights']))
# [{'สถาบัน': 0.126, 'การเงิน': 0.10956, 'สามารถ': 0.07, 'ลงทุน': 0.1417, 'ใน': 0.01715, 'หลัก': 0.0758, 'ทรัพย์': 0.1702, 'อัตรา': 0.04926, 'ส่วน': 0.06107, 'ร้อยละ': 0.09, 'สิบ': 0.14, 'เงิน': 0.05026, 'กองทุน': 0.1205, 'ทั้งหมด': 0.03644, 'ถือ': 0.0987, 'หุ้น': 0.0928, 'ในทุก': 0.04883, 'บริษัท': 0.0999, 'รวม': 0.0835, 'กันได้': 0.09814, 'หรือไม่': 0.0398},
#  {'กรณี': 0.0323, 'ธนาคาร': 0.08136, 'แห่งประเทศไทย': 0.151, 'คําสั่ง': 0.161, 'ปิด': 0.1583, 'กิจการ': 0.1199, 'สถาบัน': 0.08545, 'การเงิน': 0.1334, 'เนื่อง': 0.006992, 'ดํารง': 0.1523, 'เงิน': 0.12146, 'กองทุน': 0.1776, 'ต่ํากว่า': 0.1335, 'ร้อยละ': 0.10126, 'สาม': 0.02498, 'ห้า': 0.1158, 'อัตรา': 0.12256, 'กําหนด': 0.0572, 'จะต้อง': 0.07074, 'นําเสนอ': 0.1752, 'ต่อ': 0.0696, 'บุคคล': 0.0817, 'ใด': 0.0577, 'หรือ': 0.0248, 'หน่วยงาน': 0.076, 'เพ': 0.02034, 'ิก': 0.0921, 'ถอน': 0.1582, 'ใบ': 0.04617, 'อนุญาต': 0.179}]


# compute the scores via lexical mathcing
lexical_scores = model.compute_lexical_matching_score(output_1['lexical_weights'][0], output_2['lexical_weights'][0])
print(lexical_scores)
# 0.10838508605957031

print(model.compute_lexical_matching_score(output_1['lexical_weights'][0], output_1['lexical_weights'][1]))
# 0.06803131103515625
```

- Multi-Vector (ColBERT)
```python
from FlagEmbedding import BGEM3FlagModel

model = BGEM3FlagModel('VISAI-AI/nitibench-ccl-human-finetuned-bge-m3',  use_fp16=True) 

sentences_1 = ["สถาบันทางการเงินสามารถลงทุนในหลักทรัพย์ เป็นอัตราส่วนร้อยละสิบของเงินกองทุนทั้งหมดของสถาบันการเงินนั้น สำหรับการถือหรือมีหุ้นในทุกบริษัทรวมกันได้หรือไม่?",
               "ในกรณีที่ธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการของสถาบันการเงิน เนื่องสถาบันการเงินดำรงเงินกองทุนต่ำกว่าร้อยละสามสิบห้าของอัตราตามที่กำหนด จะต้องนำเสนอต่อบุคคลใดหรือหน่วยงานใดเพื่อเพิกถอนใบอนุญาตของสถาบันการเงินนั้น"]
sentences_2 = ["พระราชบัญญัติธุรกิจสถาบันการเงิน พ.ศ. 2551 มาตรา 33 ภายใต้บังคับมาตรา 34 และมาตรา 35 ให้สถาบันการเงินลงทุนในหลักทรัพย์เพื่อเป็นกรรมสิทธิ์ของตนได้ ตามหลักเกณฑ์ที่ธนาคารแห่งประเทศไทยประกาศกำหนด", 
               "พระราชบัญญัติธุรกิจสถาบันการเงิน พ.ศ. 2551 มาตรา 97 ในกรณีที่สถาบันการเงินดำรงเงินกองทุนต่ำกว่าร้อยละสามสิบห้าของอัตราตามที่กำหนดในมาตรา 30 ให้ธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการของสถาบันการเงินนั้น เว้นแต่ในกรณีที่ธนาคารแห่งประเทศไทยเห็นว่าการมีคำสั่งปิดกิจการจะก่อให้เกิดผลกระทบ หรือความเสียหายต่อระบบเศรษฐกิจโดยรวมอย่างรุนแรง ธนาคารแห่งประเทศไทยอาจยังไม่สั่งปิดกิจการของสถาบันการเงินก็ได้\nเมื่อธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการตามวรรคหนึ่งแล้ว ให้เสนอรัฐมนตรีเพิกถอนใบอนุญาตของสถาบันการเงินนั้น"]

output_1 = model.encode(sentences_1, return_dense=True, return_sparse=True, return_colbert_vecs=True)
output_2 = model.encode(sentences_2, return_dense=True, return_sparse=True, return_colbert_vecs=True)

print(model.colbert_score(output_1['colbert_vecs'][0], output_2['colbert_vecs'][0]))
print(model.colbert_score(output_1['colbert_vecs'][0], output_2['colbert_vecs'][1]))
# tensor(0.5813)
# tensor(0.5718)
```


### Compute score for text pairs
Input a list of text pairs, you can get the scores computed by different methods.
```python
from FlagEmbedding import BGEM3FlagModel

model = BGEM3FlagModel('VISAI-AI/nitibench-ccl-human-finetuned-bge-m3',  use_fp16=True) 

sentences_1 = ["สถาบันทางการเงินสามารถลงทุนในหลักทรัพย์ เป็นอัตราส่วนร้อยละสิบของเงินกองทุนทั้งหมดของสถาบันการเงินนั้น สำหรับการถือหรือมีหุ้นในทุกบริษัทรวมกันได้หรือไม่?",
               "ในกรณีที่ธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการของสถาบันการเงิน เนื่องสถาบันการเงินดำรงเงินกองทุนต่ำกว่าร้อยละสามสิบห้าของอัตราตามที่กำหนด จะต้องนำเสนอต่อบุคคลใดหรือหน่วยงานใดเพื่อเพิกถอนใบอนุญาตของสถาบันการเงินนั้น"]
sentences_2 = ["พระราชบัญญัติธุรกิจสถาบันการเงิน พ.ศ. 2551 มาตรา 33 ภายใต้บังคับมาตรา 34 และมาตรา 35 ให้สถาบันการเงินลงทุนในหลักทรัพย์เพื่อเป็นกรรมสิทธิ์ของตนได้ ตามหลักเกณฑ์ที่ธนาคารแห่งประเทศไทยประกาศกำหนด", 
               "พระราชบัญญัติธุรกิจสถาบันการเงิน พ.ศ. 2551 มาตรา 97 ในกรณีที่สถาบันการเงินดำรงเงินกองทุนต่ำกว่าร้อยละสามสิบห้าของอัตราตามที่กำหนดในมาตรา 30 ให้ธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการของสถาบันการเงินนั้น เว้นแต่ในกรณีที่ธนาคารแห่งประเทศไทยเห็นว่าการมีคำสั่งปิดกิจการจะก่อให้เกิดผลกระทบ หรือความเสียหายต่อระบบเศรษฐกิจโดยรวมอย่างรุนแรง ธนาคารแห่งประเทศไทยอาจยังไม่สั่งปิดกิจการของสถาบันการเงินก็ได้\nเมื่อธนาคารแห่งประเทศไทยมีคำสั่งปิดกิจการตามวรรคหนึ่งแล้ว ให้เสนอรัฐมนตรีเพิกถอนใบอนุญาตของสถาบันการเงินนั้น"]

sentence_pairs = [[i,j] for i in sentences_1 for j in sentences_2]

print(model.compute_score(sentence_pairs, 
                          max_passage_length=128, # a smaller max length leads to a lower latency
                          weights_for_different_modes=[0.4, 0.2, 0.4])) # weights_for_different_modes(w) is used to do weighted sum: w[0]*dense_score + w[1]*sparse_score + w[2]*colbert_score

# {
#   'colbert': [0.5812647342681885, 0.5717734098434448, 0.6460118889808655, 0.8784525990486145],
#   'sparse': [0.1083984375, 0.07684326171875, 0.07061767578125, 0.314208984375],
#   'dense': [0.61865234375, 0.58935546875, 0.666015625, 0.8916015625],
#   'sparse+dense': [0.4485676884651184, 0.41851806640625, 0.4675496518611908, 0.6991373896598816],
#   'colbert+sparse+dense': [0.5016465187072754, 0.47982022166252136, 0.538934588432312, 0.7708634734153748]
# }
```


## Acknowledgement
We sincerely appreciate the generous support from the WangchanX program sponsors—PTT, SCB, and SCBX—whose funding made this project possible. We are also grateful for the invaluable collaboration with VISTEC, which was crucial in bringing this project to fruition. 

Thanks to Pirat Pothavorn for evaluating the model performance on NitiBench, Supavish Punchun for finetuning the model. Additionally, we thank you all authors of this open-sourced project.

## Citation

### BibTeX
```
@misc{akarajaradwong2025nitibenchcomprehensivestudiesllm,
      title={NitiBench: A Comprehensive Studies of LLM Frameworks Capabilities for Thai Legal Question Answering}, 
      author={Pawitsapak Akarajaradwong and Pirat Pothavorn and Chompakorn Chaksangchaichot and Panuthep Tasawong and Thitiwat Nopparatbundit and Sarana Nutanong},
      year={2025},
      eprint={2502.10868},
      archivePrefix={arXiv},
      primaryClass={cs.CL},
      url={https://arxiv.org/abs/2502.10868}, 
}
```