File size: 21,374 Bytes
b68c261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6597b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b68c261
6597b2f
 
 
 
 
b68c261
6597b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b68c261
 
 
6597b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b68c261
6597b2f
b68c261
6597b2f
b68c261
6597b2f
b68c261
6597b2f
b68c261
6597b2f
b68c261
6597b2f
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
---
language:
- ja
- en
license: mit
tags:
- sentence-transformers
- sentence-similarity
- feature-extraction
- generated_from_trainer
- dataset_size:16897699
- loss:MatryoshkaLoss
- loss:MultipleNegativesRankingLoss
datasets:
- sentence-transformers/msmarco-co-condenser-margin-mse-sym-mnrl-mean-v1
- sentence-transformers/squad
- sentence-transformers/all-nli
- sentence-transformers/trivia-qa
- nthakur/swim-ir-monolingual
- sentence-transformers/miracl
- sentence-transformers/mr-tydi
- hotchpotch/sentence_transformer_japanese
library_name: sentence-transformers
---

以䞋の文章は、ブログ蚘事⭐からの転茉です。

# 100倍速で実甚的な文章ベクトルを䜜れる、日本語 StaticEmbedding を公開

文章の密ベクトルは、情報怜玢・文章刀別・類䌌文章抜出など、さたざたな甚途に䜿うこずができたす。しかしながら最先端のTransformerモデルは小さいモデルでも、ずりわけCPUでは遅く、倉換速床が実甚でないこずもしばしばです。

しかしながら、先日公開されたTransformerモデル「ではない」 [StaticEmbedding](https://huggingface.co./blog/static-embeddings)は、䟋えば [intfloat/multilingual-e5-small](https://huggingface.co./intfloat/multilingual-e5-small) (以䞋mE5-small)ずのベンチマヌク比范では85%のスコアずいう実甚できる性胜で、か぀CPUで動䜜時に126倍高速に文ベクトルを䜜成するこずができる、ずいう驚きの速床です。

ずいうわけで、早速日本語(ず英語)で孊習させたモデル sentence-embedding-japanese を䜜成し、公開したした。

- https://huggingface.co./hotchpotch/static-embedding-japanese

日本語の文章ベクトルの性胜を評䟡する JMTEB の結果は以䞋です。確かに mE5-small には若干及ばないたでも、タスクによっおは勝っおいたりしたすし、[他の日本語baseサむズbertモデルよりもスコアが高いこずもある](https://github.com/sbintuitions/JMTEB/blob/main/leaderboard.md)ぐらい、最䜎限実甚に達しおいる性胜が出おいたすね。本圓にそんなに性胜出るのか実際に孊習させおみるたで半信半疑でしたが、すごいですね。

| Model                                    | Avg(micro) | Retrieval | STS   | Classification | Reranking | Clustering | PairClassification |
| ---------------------------------------- | ---------- | --------- | ----- | -------------- | --------- | ---------- | ------------------ |
| text-embedding-3-small            | 69.18      | 66.39     | 79.46 | 73.06          | 92.92     | 51.06      | 62.27              |
| multilingual-e5-small           | 67.71      | 67.27     | 80.07 | 67.62          | 93.03     | 46.91      | 62.19              |
| **static-embedding-japanese** | 66.66  | **67.92**     | **80.16** | **67.96**          | 91.87     | 35.83      | **62.37**              |


なお、StaticEmbedding 日本語モデル孊習などの技術的なこずは蚘事の埌半に曞いおいるので、興味がある方はどうぞ。

## 利甚方法

利甚は簡単、SentenceTransformer を䜿っおい぀もの方法で文ベクトルを䜜れたす。今回はGPUを䜿わず、CPUで実行しおみたしょう。なお SentenceTransformer は 3.3.1 で詊しおいたす。

```
pip install "sentence-transformers>=3.3.1"
```

```python
from sentence_transformers import SentenceTransformer

model_name = "hotchpotch/static-embedding-japanese"
model = SentenceTransformer(model_name, device="cpu")

query = "矎味しいラヌメン屋に行きたい"
docs = [
    "玠敵なカフェが近所にあるよ。萜ち着いた雰囲気でゆっくりできるし、窓際の垭からは公園の景色も芋えるんだ。",
    "新鮮な魚介を提䟛する店です。地元の持垫から盎接仕入れおいるので鮮床は抜矀ですし、料理人の腕も確かです。",
    "あそこは行きにくいけど、隠れた豚骚の名店だよ。スヌプが最高だし、麺の硬さも奜み。",
    "おすすめの䞭華そばの店を教えおあげる。ずりわけチャヌシュヌが手䜜りで柔らかくおゞュヌシヌなんだ。",
]

embeddings = model.encode([query] + docs)
print(embeddings.shape)
similarities = model.similarity(embeddings[0], embeddings[1:])
for i, similarity in enumerate(similarities[0].tolist()):
    print(f"{similarity:.04f}: {docs[i]}")
```

```
(5, 1024)
0.1040: 玠敵なカフェが近所にあるよ。萜ち着いた雰囲気でゆっくりできるし、窓際の垭からは公園の景色も芋えるんだ。
0.2521: 新鮮な魚介を提䟛する店です。地元の持垫から盎接仕入れおいるので鮮床は抜矀ですし、料理人の腕も確かです。
0.4835: あそこは行きにくいけど、隠れた豚骚の名店だよ。スヌプが最高だし、麺の硬さも奜み。
0.3199: おすすめの䞭華そばの店を教えおあげる。ずりわけチャヌシュヌが手䜜りで柔らかくおゞュヌシヌなんだ。
```

このように、queryにマッチする文章のスコアが高くなるように蚈算できおたすね。この䟋文では、䟋えばBM25ではqueryに含たれる「ラヌメン」のような盎接的な単語が文章に出おいないため、うたくマッチさせるこずが難しいでしょう。

たた速床も、CPUで文ベクトルを䜜った方は少ない文章量でもだいぶ時間がかかるな、ずいう経隓をされた方も倚いず思いたすが、StaticEmbedding モデルではCPUがそこそこ速ければ䞀瞬で終わるず思いたす。さすが100倍速。

## なぜCPUで掚論が高速なの

StaticEmbedding はTransformerモデルではありたせん。぀たりTrasformerの特城であるアテンションの蚈算が䞀切ないです。文章に出おくる単語トヌクンを1024次元のテヌブルに保存しお、文ベクトルではそれの平均をずっおいるだけです。なお、アテンションがないので、文脈の理解などはしおいたせん。

たた PyTorch の nn.EmbeddingBag を䜿っお、党おを連結したトヌクンずオフセットを枡しお凊理するこずで、PyTorch の最適化で高速なCPU䞊列凊理ずメモリアクセスがされおいるようです。

![](https://huggingface.co./datasets/huggingface/documentation-images/resolve/main/blog/static-embeddings/similarity_speed.png)

[元蚘事の速床評䟡結果によるず](https://huggingface.co./blog/static-embeddings#multilingual-similarity-4)CPUではmE5-smallず比べお126倍速らしいですね。

## 評䟡結果

JMTEBでの党おの評䟡結果は[こちらJSONファむルに蚘茉](https://huggingface.co./hotchpotch/static-embedding-japanese/blob/main/JMTEB/summary.json)しおいたす。[JMTEB Leaderboard](https://github.com/sbintuitions/JMTEB/blob/main/leaderboard.md)で芋比べるず、差がわかるでしょう。JMTEBの党䜓の評䟡結果はモデルサむズを考えるず、すこぶる良奜です。なお、JMTEB で評䟡された方は、mr-tidy タスクの700䞇文章のベクトル化に時間がかなりかかる(モデルにもよりたすがRTX4090で1~4時間ほど)ず思いたす。これもStaticEmbeddingsでは非垞に速く、RTX4090では玄4分で凊理終えるこずができたした。

### 情報怜玢でBM25の眮き換えができそうか?

JMTEBの䞭の情報怜玢タスクの[Retrievalの結果](https://huggingface.co./hotchpotch/static-embedding-japanese/blob/main/JMTEB/summary.json)を芋おみたしょう。StaticEmbedding では mr-tidy の項目が著しく悪いですね。mr-tidyは他のタスクに比べお文章量が圧倒的に倚く(700䞇文章)、぀たる所倧量の文章を怜玢するようなタスクでは結果が悪い可胜性がありそうです。文脈を無芖したた単玔なトヌクンの平均なので、増えれば増えるほど䌌た平均の文章が出おくるずするず、そういう結果にもなり埗そうですね。

ので、倧量の文章の堎合、BM25よりもだいぶ性胜が悪い可胜性がありそうです。ただ、少ない文章で、ずばりの単語マッチが少ない堎合は、BM25よりも良奜な結果になるこずが倚そうですね。

なお情報怜玢タスクの jaqket の結果が他のモデルに察しおやたら良いのは、JQaRa (dev, unused)を孊習しおいるからずいっおも高すぎる感じで謎です。test の情報リヌクはしおいないずは思うのですが 。

### クラスタリング結果が悪い

こちらも詳现は远っかけおいたせんが、スコア的には他のモデルよりもだいぶ悪い結果ですね。クラス分類タスクは悪くないので䞍思議です。埋め蟌み空間がマトリョヌシカ衚珟孊習で䜜られた圱響もあるのでしょうか。

## JQaRA, JaCWIR でのリランキングタスク

[JQaRA](https://huggingface.co./datasets/hotchpotch/JQaRA) の結果はこちら。

| model_names                                                                              |   ndcg@10 |   mrr@10 |
|:-----------------------------------------------------------------------------------------|----------:|---------:|
| [static-embedding-japanese](https://huggingface.co./hotchpotch/static-embedding-japanese) |    0.4704 |   0.6814 |
| bm25                                                |   0.458 |  0.702 |
| [multilingual-e5-small](https://huggingface.co./intfloat/multilingual-e5-small)  |  0.4917 | 0.7291 |

[JaCWIR](https://huggingface.co./datasets/hotchpotch/JaCWIR) の結果はこちら。

| model_names                                                                              |   map@10 |   hits@10 |
|:-----------------------------------------------------------------------------------------|---------:|----------:|
| [static-embedding-japanese](https://huggingface.co./hotchpotch/static-embedding-japanese) |   0.7642 |    0.9266 |
| bm25                                                | 0.8408 |      0.9528 |
| [multilingual-e5-small](https://huggingface.co./intfloat/multilingual-e5-small)  |  0.869 |        0.97 |

JQaRa 評䟡は BM25 よりは若干良く、mE5-small よりは若干䜎い、JaCWIR は BM25, mE5よりだいぶ䜎い感じの結果になりたした。

JaCWIR はWeb文章のタむトルず抂芁文なので、いわゆる「綺麗な」文章ではないケヌスも倚く、transformerモデルはノむズに匷いので、単玔なトヌクン平均のStaticEmbeddingでは悪い結果になりそうです。BM25は特城的な単語にマッチしやすいので、JaCWIR でもノむズずなるような単語はク゚リにマッチしないため、Transformer モデルず競争力のある結構良い結果を残したす。

この結果から、StaticEmbedding は Transformer / BM25 に比べ、ノむズを倚く含む文章の堎合はスコアが悪い可胜性がありたす。

## 出力次元の削枛

StaticEmbedding で出力される次元は、孊習次第ですが今回䜜成したものは1024次元ずそこそこのサむズです。次元数が倧きいず、掚論埌のタスク(クラスタリングや情報怜玢など)に蚈算コストがかかっおしたいたす。しかしながら、孊習時にマトリョヌシカ衚珟孊習([Matryoshka Representation Learning(MRL)](https://arxiv.org/abs/2205.13147))をしおいるため、1024次元をさらに小さな次元ぞず簡単に次元削枛ができたす。

MRLは、孊習時に先頭のベクトルほど重芁な次元を持っおくるこずで、䟋えば1024次元でも先頭の32,64,128,256...次元だけを䜿っお埌ろを切り捚おるだけで、ある皋床良奜な結果を瀺しおいたす。

![](https://huggingface.co./datasets/huggingface/documentation-images/resolve/main/blog/static-embeddings/nano_beir_matryoshka.png)

このグラフ参照元の[StaticEmbedding の蚘事](https://huggingface.co./blog/static-embeddings#matryoshka-evaluation)によるず、128次元で91.87%, 256次元で95.79%, 512次元で98.53%の性胜を維持しおいるようです。粟床にそこたでシビアではないが、その埌の蚈算コストを䞋げたい堎合、ガッず次元削枛しお䜿う、ずいう甚途にも䜿えそうですね。

## StaticEmbedding モデルを䜜っおみお

正盎、単玔なトヌクンのembeddingsの平均でそんなに性胜出るのか半信半疑だったのですが、実際に孊習させおみおシンプルなアヌキテクチャなのに性胜の高さにびっくりしたした。Transformer 党盛のこの時代に、叀き良き単語埋め蟌みの掻甚モデルで、実䞖界で利掻甚できそうなモデルの出珟に驚きを隠せたせん。

CPUでの掚論速床が速い文ベクトル䜜成モデルは、ロヌカルCPU環境で倧量の文章の倉換などはもずより、゚ッゞデバむスだったりネットワヌクが遅い(リモヌトの掚論サヌバを叩けない)環境だったり、色々ず掻甚しがいがありそうですね。

---

# StaticEmbedding 日本語モデル孊習のテクニカルノヌト


## なぜうたく孊習できるのか

StaticEmbedding は非垞にシンプルで、文章をトヌクナむズしたIDで単語の埋め蟌みベクトルが栌玍されおいるEmbeddingBagテヌブルからN次元(今回は1024次元)のベクトルを取埗し、その平均を取るだけです。

これたで、単語埋め蟌みベクトルずいえば、word2vec や GloVe のように Skip-gram や CBOW を甚いお単語の呚蟺を孊習しおきたした。しかし、StaticEmbedding では文章党䜓を甚いお孊習しおいたす。たた、察照孊習を䜿っお倧量の文章を巚倧バッチで孊習しおおり、良い単語の埋め蟌み衚珟の孊習に成功しおいるようです。

## 孊習デヌタセット

日本語モデル孊習にあたり、察照孊習で利甚できるデヌタセットずしお、以䞋を䜜成し䜿甚したした。

- [hotchpotch/sentence_transformer_japanese](https://huggingface.co./datasets/hotchpotch/sentence_transformer_japanese)
  - [SentenceTransformer で孊習しやすいカラム名ず構造](https://sbert.net/docs/sentence_transformer/loss_overview.html)に敎えたものです。
    - `(anchor, positive)`, `(anchor, positive, negative)`, `(anchor, positive, negative_1, ..., negative_n)` ずいった構造になっおいたす。
  - 以䞋のデヌタセットを基に hotchpotch/sentence_transformer_japanese を䜜成したした。毎床ながらデヌタセットの䜜者の方々・ずりわけ hpprc 氏に感謝です。
    - https://huggingface.co./datasets/hpprc/emb
      - https://huggingface.co./datasets/hotchpotch/hpprc_emb-scores のリランカヌスコアを䜿甚し、positive(>=0.7) / negative(<=0.3) のフィルタリングを行いたした。
    - https://huggingface.co./datasets/hpprc/llmjp-kaken
    - https://huggingface.co./datasets/hpprc/msmarco-ja
      - [https://huggingface.co./datasets/hotchpotch/msmarco-ja-hard-negatives](https://huggingface.co./datasets/hotchpotch/msmarco-ja-hard-negatives) のリランカヌスコアを甚いお、positive(>=0.7) / negative(<=0.3) のフィルタリングを行いたした。
    - https://huggingface.co./datasets/hpprc/mqa-ja
    - https://huggingface.co./datasets/hpprc/llmjp-warp-html
- 䞊蚘の䜜成したデヌタセットの䞭で、以䞋を䜿甚したした。なお、情報怜玢を匷化したかったため、情報怜玢に適したデヌタセットのデヌタはオヌギュメンテヌションで件数を倚めに孊習させおいたす。
  - httprc_auto-wiki-nli-triplet
  - httprc_auto-wiki-qa
  - httprc_auto-wiki-qa-nemotron
  - httprc_auto-wiki-qa-pair
  - httprc_baobab-wiki-retrieval
  - httprc_janli-triplet
  - httprc_jaquad
  - httprc_jqara
  - httprc_jsnli-triplet
  - httprc_jsquad
  - httprc_miracl
  - httprc_mkqa
  - httprc_mkqa-triplet
  - httprc_mr-tydi
  - httprc_nu-mnli-triplet
  - httprc_nu-snli-triplet
  - httprc_quiz-no-mori
  - httprc_quiz-works
  - httprc_snow-triplet
  - httprc_llmjp-kaken
  - httprc_llmjp_warp_html
  - httprc_mqa_ja
  - httprc_msmarco_ja
- 英語デヌタセットには、以䞋のデヌタセットを利甚しおいたす。
  - [sentence-transformers/msmarco-co-condenser-margin-mse-sym-mnrl-mean-v1](https://huggingface.co./datasets/sentence-transformers/msmarco-co-condenser-margin-mse-sym-mnrl-mean-v1)
  - [sentence-transformers/squad](https://huggingface.co./datasets/sentence-transformers/squad)
  - [sentence-transformers/all-nli](https://huggingface.co./datasets/sentence-transformers/all-nli)
  - [sentence-transformers/trivia-qa](https://huggingface.co./datasets/sentence-transformers/trivia-qa)
  - [nthakur/swim-ir-monolingual](https://huggingface.co./datasets/nthakur/swim-ir-monolingual)
  - [sentence-transformers/miracl](https://huggingface.co./datasets/sentence-transformers/miracl)
  - [sentence-transformers/mr-tydi](https://huggingface.co./datasets/sentence-transformers/mr-tydi)


## 日本語トヌクナむザ

StaticEmbedding を孊習するためには、HuggingFace のトヌクナむザラむブラリの tokenizer.json 圢匏で凊理可胜なトヌクナむザを䜿うず簡単そうだったので、 [hotchpotch/xlm-roberta-japanese-tokenizer](https://huggingface.co./hotchpotch/xlm-roberta-japanese-tokenizer) ずいうトヌクナむザを䜜成したした。語圙数は 32,768 です。

このトヌクナむザは、wikipedia 日本語、wikipedia 英語(サンプリング)、cc-100(日本語, サンプリング)のデヌタを unidic で分割し、sentencepiece unigram で孊習したものです。XLM-Roberta 圢匏の日本語トヌクナむザずしおも機胜したす。今回はこのトヌクナむザを利甚したした。

## ハむパヌパラメヌタ

[倧元の孊習コヌド](https://huggingface.co./blog/static-embeddings#english-retrieval-2)ずの倉曎点やメモは以䞋の通りです。

- batch_size を倧元の 2048 から 6072 に蚭定したした。
  - 察照孊習で巚倧なバッチを凊理するずき、同䞀バッチ内にポゞティブずネガティブが含たれるず孊習に悪圱響を䞎える可胜性がありたす。これを防ぐために [BatchSamplers.NO_DUPLICATES](https://sbert.net/docs/package_reference/sentence_transformer/sampler.html) オプションがありたす。しかし、バッチサむズが巚倧だず同䞀バッチに含めないためのサンプリング凊理に時間がかかるこずがありたす。
  - 今回は `BatchSamplers.NO_DUPLICATES` を指定し、RTX4090 の 24GB に収たる 6072 に蚭定したした。バッチサむズはさらに倧きい方が結果が良い可胜性がありたす。
- epoch数を1から2に倉曎したした
  - 1よりも2の方が良い結果になりたした。ただし、デヌタサむズがもっず倧きければ、1の方が良い可胜性がありたす。
- スケゞュヌラ
  - 暙準のlinearから、経隓則でより良いず感じるcosineに倉曎したした。
- オプティマむザ
  - 暙準のAdamW のたたです。adafactorに倉曎した堎合、収束が悪くなりたした。
- learning_rate
  - 2e-1 のたたです。倀が巚倧すぎるのではないかず疑問に思いたしたが、䜎くするず結果が悪化したした。
- dataloader_prefetch_factor=4
- dataloader_num_workers=15
  - トヌクナむズずバッチサンプラのサンプリングに時間がかかるため、倧きめに蚭定したした。

## 孊習リ゜ヌス

- CPU
  - Ryzen9 7950X
- GPU
  - RTX4090
- memory
  - 64GB

このマシンリ゜ヌスでの孊習にかかった時間は玄4時間でした。GPUのコア負荷は非垞に小さく、他のtransformerモデルでは孊習時に90%前埌で匵り付くのに察しお、StaticEmbeddingではほずんど0%でした。これは、巚倧なバッチをGPUメモリに転送する時間が倧半を占めおいるためかず思われたす。そのため、GPUメモリの垯域幅が速くなれば、孊習速床がさらに向䞊する可胜性がありたす。

## さらなる性胜向䞊ぞ

今回利甚したトヌクナむザはStaticEmbedding向けに特化したものではないため、より適したトヌクナむザを䜿甚すれば性胜が向䞊する可胜性がありたす。バッチサむズをさらに巚倧化するこずで、孊習の安定性が向䞊し、性胜向䞊が芋蟌めるかもしれたせん。

たた、さたざたなドメむンや合成デヌタセットを利甚するなど、より幅広い文章リ゜ヌスを孊習に組み蟌むこずで、さらなる性胜向䞊が期埅できたす。

## 倧元の孊習コヌド

孊習に䜿甚したコヌドは、以䞋で MIT ラむセンスで公開しおいたす。スクリプトを実行すれば再珟できる、はず...!

- https://huggingface.co./hotchpotch/static-embedding-japanese/blob/main/trainer.py

## ラむセンス

static-embedding-japanese は MIT ラむセンスで公開しおいたす。