GithubHelp home page GithubHelp logo

wangyuxinwhy / uniem Goto Github PK

View Code? Open in Web Editor NEW
796.0 7.0 60.0 12.96 MB

unified embedding model

License: Apache License 2.0

Makefile 0.21% Python 99.79%
embeddings huggingface nlp sentence-embeddings sentence-transformers

uniem's People

Contributors

ctyytc avatar hesic73 avatar howard-sun avatar ncliang avatar wangyuxinwhy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

uniem's Issues

mean pooling 与 embedding_strategy 问题

辛苦问个问题,使用 sentence-transformers 进行 encode 时最后会加上一个 mean pooling 操作,然后将池化后的特征作为最终的特征,model 定义时候我看可选cls, last_mean, first_last_mean,embedding_last_mean, last_weighted 几种不同的方式,这个的选择对最终embedding 效果有影响吗?

关于py3.10

🐛 bug 说明

由于一些原因无法使用py3.10进行微调,想重构一下源码,请问一下,fintuner或者说uniem库中有哪些组件是必须使用py3.10的,您方还有印象吗?

Python Version

None

关于微调环境

🐛 bug 说明

背景:
之前作者您说,是可以在colab 试下,如今我试了:出了很多问题,如下所示:
image

问题:
还是之前的问题,我现在是想在colab 的试验下,然后把微调的环境的requireme.txt 导出来,但是目前看起来这条路是不行的,因此想要问下作者,可否导出requirement。txt?

Python Version

3.10

检索排序的指标问题

🐛 bug 说明

想问下,检索排序的三个指标MAP, MRR, NDCG 分别是检索的还是排序的指标,如果三个指标是对同一份推理结果的指标,那么MAP@1是不是应该和MRR@1相等

Python Version

None

sentenceTransformer在encode方法上面有什么优化吗

我直接调huggingface上面的m3e模型

class HuggingfaceModel:
    def __init__(
        self,
        model_name: str = 'moka-ai/m3e-small',
        device: str | None = None,
    ) -> None:
        from transformers import AutoModel, AutoTokenizer  # type: ignore

        if device is None:
            self.device = 'cuda' if torch.cuda.is_available() else 'cpu'
        else:
            self.device = device
        self.model = AutoModel.from_pretrained(model_name)
        self.model.to(self.device)
        self.tokenizer = AutoTokenizer.from_pretrained(model_name)
        self.model.eval()
    def encode(self, sentences: list[str], batch_size: int = 32, **kwargs) -> list[np.ndarray]:
        all_embeddings: list[np.ndarray] = []
        for batch_texts in tqdm(
            generate_batch(sentences, batch_size),
            total=len(sentences) // batch_size,
        ):
            inputs = self.tokenizer(
                batch_texts,
                padding=True,
                truncation=True,
                return_tensors='pt',
                max_length=512,
            )
            inputs = inputs.to(self.device)
            with torch.no_grad():
                outputs = self.model(**inputs, output_hidden_states=True)
                embeddings = outputs.hidden_states[-1][:, 0, :].squeeze()
            embeddings = cast(torch.Tensor, embeddings)
            all_embeddings.extend(embeddings.cpu().numpy())
        return all_embeddings

观察到这样的调用和编码方式跟用sentenceTransformer上面调用有千分之二左右的性能差距,想问一下SentenceTransformer具体相对这样编码有什么改进,自己看没看出什么门道!感谢

提高负样本的方法

目前负样本的数量还是受限于单卡的显存,即最多为batch size per gpu。
是否有这种操作:把GPU2的样本作为GPU1样本的负样本呢?

关于M3e模型微调的问题

@wangyuxinwhy 大佬,非常感谢开源贡献的这个项目。

小白有一个疑问。
请问m3e模型如何微调?

因为我这里主要是医疗数据,这里m3e文本嵌入的向量间的相似度有点高,需要进行调整。
图中这个是我的训练数据和测试样例
image

finetune时报错 argument after ** must be a mapping, not NoneType

🐛 bug 说明

您好,照着官网的教程,使用了自己的数据集,finetune时报错 argument after ** must be a mapping, not NoneType
感谢大佬们看看
代码如下:

import pandas as pd
from uniem.finetuner import FineTuner
df3_raw = """{"sentence1":"金霉素", "sentence2":"红霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"妥布霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"硫酸新霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"灰黄霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"曲霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"复方新霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"庆大霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"克林霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"黄曲霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"青霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"土霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"阿奇霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"林可霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"氯霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"螺旋霉素", "label":"0.0"}"""
df3 = pd.read_json(df3_raw, lines=True)
finetuner = FineTuner('moka-ai3/m3e-base/', dataset=df3.to_dict('records'))
finetuner.run(epochs=1)

Python Version

None

m3e支持交互式模型嘛?

🐛 bug 说明

感谢非常棒的工作!
请问下用在交互式模型上怎么样?
1.比如,输入query[sep]title 来通过模型,来判断是否相关。
2.如果不行的话,我加载m3e模型,继续把数据组织成交互式的方法来微调,是否比原生的bert好点呢?

Python Version

None

问下怎么切换s2s、s2p、s2c

很棒的工作!我目前正在做检索任务,问下怎么切换s2s、s2p,目前貌似只有一个encode方法,我直接embe_q=model.encode(问题) 和 embe_p=model.encode(文档),embe_q和embe_p做相似度对比吗。

自动获取数据集样本类型的代码可能会出现误判

🐛 bug 说明

首先感谢大佬开源如此优秀的工具!

版本:0.2.2
函数:uniem.data_structures.get_record_type
描述:该函数的逻辑似乎会导致程序将 TripletRecord 类型识别为 PairRecord
实验:

from uniem.data_structures import RecordType, get_record_type
sample = {
    'text': 'hello', 
    'text_pos': 'hi', 
    'text_neg': 'no',
}
ret = get_record_type(sample)
print(ret.__class__)
print(ret)

返回:期望返回类型名称是 TripletRecord
<enum 'RecordType'>
RecordType.PAIR

Python Version

3.10

batch size 小的时候使用 `SigmoidContrastLoss` 会好一点,大的时候 `SoftmaxContrastLoss` 好一点?

🐛 bug 说明

batch size 小的时候使用 SigmoidContrastLoss 会好一点,大的时候 SoftmaxContrastLoss 好一点。请问这个是做实验了还是有理论分析呢?理论上,第一个loss是一个query,对于一个正例,做batch_size-1个二分类任务(batch_size-1)个负例。
而SoftmaxContrastLoss,一个query,对于一个正例,做一个多分类任务(也是见到batch_size-1个负例)。从负例的角度没差别呀?

Python Version

None

finetune时报错 argument after ** must be a mapping, not NoneType

🐛 bug 说明

您好,照着官网的教程,使用了自己的数据集,finetune时报错 argument after ** must be a mapping, not NoneType
感谢大佬们看看,前一个issue不小心关闭了
代码如下:

import pandas as pd
from uniem.finetuner import FineTuner
df3_raw = """{"sentence1":"金霉素", "sentence2":"红霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"妥布霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"硫酸新霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"灰黄霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"曲霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"复方新霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"庆大霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"克林霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"黄曲霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"青霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"土霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"阿奇霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"林可霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"氯霉素", "label":"0.0"}
{"sentence1":"金霉素", "sentence2":"螺旋霉素", "label":"0.0"}"""
df3 = pd.read_json(df3_raw, lines=True)
finetuner = FineTuner('moka-ai3/m3e-base/', dataset=df3.to_dict('records'))
finetuner.run(epochs=1)

Python Version

3.10

max_length 和 position embedding 相关

2023-07-13 21-09-44屏幕截图

在看E5论文的时候发现,他们在pretrain和finetune时分别采用了128和192的max length,同时fix住了position embedding,
因此测试时也能把length设置为最大的512。
我猜测这样的优势是训练速度会比较快?不知道M3E有没有做过相关的尝试,比如fix住pos embedding而采用较小的max_length以加快训练速度,不知道对精度的影响如何。

复现实验的参数配置

非常棒的工作,请教一下复现instructor的实验的超参。请问是batch size=32, epoch=3吗,那就是训练10万多步。

运行微调代码报错

image 如图所示,符号异常是为啥呢? 我查阅资料发现,match语法python3.7不支持,您是python3.10吗?感觉可以把版本号也顺带澄清一下

finetune 会出现显存泄露的问题

🐛 bug 说明

使用该脚本,执行 python test.py,一段时间后就会占光显存,然后 OOM
安装的uniem 版本为 0.2.4post1

import pandas as pd

from uniem.finetuner import FineTuner

# 读取 jsonl 文件
df = pd.read_json('/paddle/data/embedding/m3e.train_data.jsonl', lines=True)
# 指定训练的模型为 m3e-small
finetuner = FineTuner('/paddle/data/suke/model_hub/m3e-base', dataset=df.to_dict('records'))
finetuner.run(batch_size=50, epochs=3, save_on_epoch_end=True,output_dir='/paddle/data/suke/test_sft/finetuned-model-m3e')

Python Version

3.10

报错信息

Start with seed: 42
Output dir: /paddle/data/suke/test_sft/finetuned-model-m3e
Start training for 3 epochs
Epoch 1/3 - loss: 1.2525:   0%|          | 27/42092 [00:59<26:17:28,  2.25s/it]╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /paddle/code/suke/uniem/scripts/test_m3e_sample.py:9 in <module>      │
│                                                                              │
│    6 df = pd.read_json('/paddle/data/embedding/m3e.train_data.jsonl', lines= │
│    7 # 指定训练的模型为 m3e-small                                            │
│    8 finetuner = FineTuner('/paddle/data/suke/model_hub/m3e-base', datase │
│ ❱  9 finetuner.run(batch_size=50, epochs=3, save_on_epoch_end=True,output_di │
│   10                                                                         │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/uniem/utils.py:113 in decorator      │
│                                                                              │
│   110 │   │   is_manually_passed_batch_size = 'batch_size' in kwargs         │
│   111 │   │                                                                  │
│   112 │   │   if is_manually_passed_batch_size:                              │
│ ❱ 113 │   │   │   return function(*args, **kwargs)                           │
│   114 │   │   else:                                                          │
│   115 │   │   │   while True:                                                │
│   116 │   │   │   │   if batch_size == 0:                                    │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/uniem/finetuner.py:239 in run        │
│                                                                              │
│   236 │   │   │   save_on_epoch_end=save_on_epoch_end,                       │
│   237 │   │   )                                                              │
│   238 │   │   accelerator.print(f'Start training for {epochs} epochs')       │
│ ❱ 239 │   │   trainer.train()                                                │
│   240 │   │                                                                  │
│   241 │   │   accelerator.wait_for_everyone()                                │
│   242 │   │   accelerator.print('Training finished')                         │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/uniem/trainer.py:52 in train         │
│                                                                              │
│    49 │   │   │   for batch_index, batch in enumerate(self.train_dataloader) │
│    50 │   │   │   │   with self.accelerator.accumulate(self.model):          │
│    51 │   │   │   │   │   self.optimizer.zero_grad()                         │
│ ❱  52 │   │   │   │   │   batch_output = self.model(**batch)                 │
│    53 │   │   │   │   │   loss = batch_output['loss']                        │
│    54 │   │   │   │   │   self.accelerator.backward(loss)                    │
│    55 │   │   │   │   │   self.optimizer.step()                              │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/uniem/model.py:254 in forward        │
│                                                                              │
│   251 │   ) -> dict[str, torch.Tensor]:                                      │
│   252 │   │   text_embeddings = self.embedder(text_ids)                      │
│   253 │   │   text_pos_embeddings = self.embedder(text_pos_ids)              │
│ ❱ 254 │   │   text_neg_embeddings = self.embedder(text_neg_ids)              │
│   255 │   │   loss = self.criterion(text_embeddings, text_pos_embeddings, te │
│   256 │   │   return {'loss': loss}                                          │
│   257                                                                        │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/uniem/model.py:109 in forward        │
│                                                                              │
│   106 │   def forward(self, input_ids: torch.Tensor, attention_mask: torch.T │
│   107 │   │   if attention_mask is None:                                     │
│   108 │   │   │   attention_mask = creat_attention_mask_from_input_ids(input │
│ ❱ 109 │   │   embeddings = self.encoder(input_ids, attention_mask=attention_ │
│   110 │   │   embeddings = mean_pooling(embeddings, attention_mask)          │
│   111 │   │   return embeddings                                              │
│   112                                                                        │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/transformers/models/bert/modeling_be │
│ rt.py:1020 in forward                                                        │
│                                                                              │
│   1017 │   │   │   inputs_embeds=inputs_embeds,                              │
│   1018 │   │   │   past_key_values_length=past_key_values_length,            │
│   1019 │   │   )                                                             │
│ ❱ 1020 │   │   encoder_outputs = self.encoder(                               │
│   1021 │   │   │   embedding_output,                                         │
│   1022 │   │   │   attention_mask=extended_attention_mask,                   │
│   1023 │   │   │   head_mask=head_mask,                                      │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/transformers/models/bert/modeling_be │
│ rt.py:610 in forward                                                         │
│                                                                              │
│    607 │   │   │   │   │   encoder_attention_mask,                           │
│    608 │   │   │   │   )                                                     │
│    609 │   │   │   else:                                                     │
│ ❱  610 │   │   │   │   layer_outputs = layer_module(                         │
│    611 │   │   │   │   │   hidden_states,                                    │
│    612 │   │   │   │   │   attention_mask,                                   │
│    613 │   │   │   │   │   layer_head_mask,                                  │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/transformers/models/bert/modeling_be │
│ rt.py:495 in forward                                                         │
│                                                                              │
│    492 │   ) -> Tuple[torch.Tensor]:                                         │
│    493 │   │   # decoder uni-directional self-attention cached key/values tu │
│    494 │   │   self_attn_past_key_value = past_key_value[:2] if past_key_val │
│ ❱  495 │   │   self_attention_outputs = self.attention(                      │
│    496 │   │   │   hidden_states,                                            │
│    497 │   │   │   attention_mask,                                           │
│    498 │   │   │   head_mask,                                                │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/transformers/models/bert/modeling_be │
│ rt.py:425 in forward                                                         │
│                                                                              │
│    422 │   │   past_key_value: Optional[Tuple[Tuple[torch.FloatTensor]]] = N │
│    423 │   │   output_attentions: Optional[bool] = False,                    │
│    424 │   ) -> Tuple[torch.Tensor]:                                         │
│ ❱  425 │   │   self_outputs = self.self(                                     │
│    426 │   │   │   hidden_states,                                            │
│    427 │   │   │   attention_mask,                                           │
│    428 │   │   │   head_mask,                                                │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/transformers/models/bert/modeling_be │
│ rt.py:306 in forward                                                         │
│                                                                              │
│    303 │   │   │   key_layer = torch.cat([past_key_value[0], key_layer], dim │
│    304 │   │   │   value_layer = torch.cat([past_key_value[1], value_layer], │
│    305 │   │   else:                                                         │
│ ❱  306 │   │   │   key_layer = self.transpose_for_scores(self.key(hidden_sta │
│    307 │   │   │   value_layer = self.transpose_for_scores(self.value(hidden │
│    308 │   │                                                                 │
│    309 │   │   query_layer = self.transpose_for_scores(mixed_query_layer)    │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/module.py:1501 in   │
│ _call_impl                                                                   │
│                                                                              │
│   1498 │   │   if not (self._backward_hooks or self._backward_pre_hooks or s │
│   1499 │   │   │   │   or _global_backward_pre_hooks or _global_backward_hoo │
│   1500 │   │   │   │   or _global_forward_hooks or _global_forward_pre_hooks │
│ ❱ 1501 │   │   │   return forward_call(*args, **kwargs)                      │
│   1502 │   │   # Do not call functions when jit is used                      │
│   1503 │   │   full_backward_hooks, non_full_backward_hooks = [], []         │
│   1504 │   │   backward_pre_hooks = []                                       │
│                                                                              │
│ /usr/local/lib/python3.10/site-packages/torch/nn/modules/linear.py:114 in    │
│ forward                                                                      │
│                                                                              │
│   111 │   │   │   init.uniform_(self.bias, -bound, bound)                    │
│   112 │                                                                      │
│   113 │   def forward(self, input: Tensor) -> Tensor:                        │
│ ❱ 114 │   │   return F.linear(input, self.weight, self.bias)                 │
│   115 │                                                                      │
│   116 │   def extra_repr(self) -> str:                                       │
│   117 │   │   return 'in_features={}, out_features={}, bias={}'.format(      │
╰──────────────────────────────────────────────────────────────────────────────╯
OutOfMemoryError: CUDA out of memory. Tried to allocate 76.00 MiB (GPU 0; 79.35
GiB total capacity; 73.60 GiB already allocated; 22.12 MiB free; 78.13 GiB
reserved in total by PyTorch) If reserved memory is >> allocated memory try
setting max_split_size_mb to avoid fragmentation.  See documentation for Memory
Management and PYTORCH_CUDA_ALLOC_CONF

很棒的效果!请教一下,我在复现的时候发现80G A100放不下80的batch_size,是怎么做到80的?另外train_m3e.py这个脚本采用的是PairInBatch,没有用到add_swap_loss。process_zh_datasets.py处理的数据也是Pair格式

          temperature: 0.01

add_swap_loss: True
batch_size: 80
max_length: 512
lr: 3e-5
epochs: 3

我们自己训练的模型跑了 MTEB ,也传到了 leaderboard 上面,名字叫 exp-base-softmax-last_mean。Classification Average (12 datasets) 跑到了 71.08,低于 instructor-base 的 72.36。不过 instructor 自己的评测是添加了手工调整的指令,我们评测的时候是不添加任何指令的。

Originally posted by @wangyuxinwhy in #1 (comment)

train_m3e细节

背景:之前基于text2vec的代码,使用in-batch的loss方式,在自己的数据集上进行finetune。对比了和uniem的训练脚本,逻辑基本一致,且保证参数一致,比如lr、weight_decay、num_warmup_steps、temperature等
问题:finetune发现,(1)使用text2vec的效果稍微优于uniem。这里指的是训练脚本,其中pretrain model均为m3e-model(2)相同batch size的情况下,uniem占用显存更少
猜测:之前以为是混合精度的原因导致的,但后来发现这个设置默认是"no"。

所以想要请教下,导致这个差异的原因可能是什么呢?期待大佬的答复。

关于使用accelerate启动多卡的问题

🐛 bug 说明

我用指令启动您给的实例脚本 accelerate launch finetune_jsonl.py
然后发现程序报错
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not
used in producing loss. You can enable unused parameter detection by passing the keyword argument find_unused_parameters=True to
torch.nn.parallel.DistributedDataParallel, and by
making sure all forward function outputs participate in calculating loss.
If you already have done the above, then the distributed data parallel module wasn't able to locate the output tensors in the return value of your module's forward
function. Please include the loss function and the structure of the return value of forward of your module when reporting this issue (e.g. list, dict, iterable).
Parameter indices which did not receive grad for rank 1: 197 198
In addition, you can set the environment variable TORCH_DISTRIBUTED_DEBUG to either INFO or DETAIL to print out information about which particular parameters did not
receive gradient on this rank as part of this error
请教一下您这要怎么解决呀

Python Version

None

关于训练,模型容易跑飞的情况

🐛 bug 说明

我在用您提供的代码和模型进行再训练,进行的是句子对的训练,我的数据集比较大,可能有100w条。
我训练的时候发现基本上训练一轮以后,损失函数可能就会突然变大,然后维持一个稳定的数值不变,判断应该是模型跑飞了。
想请教一下作者有遇到过这种情况么,有没有训练经验可以分享一下的。

Python Version

None

复现M3E-Base

如果想要复现M3E-Base的结果,不知道作者方便透露下具体的参数或者相应的config file吗,
还是说train_m3e.py里的默认参数已经是最优参数了?
感谢!

Instruction Tuning数据集使用

🚀 The feature

目前我看代码train/eval,都是没有显式加入instruction,而是自动mergeinstruction和input部分用来作为一个text样本。
这样对于所有pair类型同质的数据,例如STS,NLI, QQpair等,相当于没有instruction?
而对于那种自带instruction的数据,相当于instruction+input融合了,有了instcution,这样需要模型自动辨识是否为一个symmetric/asymmetric任务?

What hidden states should I use?

the output of encoder is N*d states for each text input;

  1. simcse use the 1st one as the output.
  2. the sentence-transformers use the mean pooling(only for attention mask=1 states).

Your default is the same as mean pooling?

关于T2ranking的评测代码,没有在uniem里边找到。

🐛 bug 说明

不同于T2ranking自身的评测, 您的文中有引入了 map、MRR、NDCG等指标。方便发一下这个评估的代码,我们这边是防止自己评估的代码与评测代码有微小差异导致评测不准确的问题。

Python Version

None

请问finetune的脚本支持多个数据集吗

感谢作者的分享,非常棒的项目!

目前看起来Finetuner的接口只支持单个数据集作为输入:
RawDataset = Sequence[dict] | dict[str, Sequence[dict]] | HFDatasetDict | HFDataset
是这样吗?

请问如何微调无监督文本

🚀 The feature

m3e模型如何微调无监督文本呢?就是一条样本不是一对相似句子或不相似句子,只是一条领域文本

单机多卡跑train_m3e.py报错,

🐛 bug 说明

命令:accelerate launch python scripts/train_m3e.py /path/to/model_base/ /path/to/dataset/

报错
mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/ac │
│ celerate/data_loader.py:742 in prepare_data_loader │
│ │
│ 739 │ │ │ if sampler_is_batch_sampler: │
│ 740 │ │ │ │ sampler = dataloader.sampler.sampler │
│ 741 │ │ │ else: │
│ ❱ 742 │ │ │ │ sampler = dataloader.batch_sampler.sampler │
│ 743 │ │ │ if hasattr(sampler, "generator"): │
│ 744 │ │ │ │ if sampler.generator is None: │
│ 745 │ │ │ │ │ sampler.generator = torch.Generator() │
│ │
│ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ │ dataloader = <torch.utils.data.dataloader.DataLoader │ │
│ │ object at 0x7f766b4b5180> │ │
│ │ device = device(type='cuda', index=1) │ │
│ │ dispatch_batches = False │ │
│ │ even_batches = True │ │
│ │ new_batch_sampler = None │ │
│ │ new_dataset = <uniem.data.M3EDataset object at │ │
│ │ 0x7f78b4033cd0> │ │
│ │ num_processes = 8 │ │
│ │ process_index = 1 │ │
│ │ put_on_device = True │ │
│ │ rng_types = ['generator'] │ │
│ │ sampler_is_batch_sampler = False │ │
│ │ split_batches = False │ │
│ │ state = Distributed environment: MULTI_GPU Backend: │ │
│ │ nccl │ │
│ │ Num processes: 8 │ │
│ │ Process index: 1 │ │
│ │ Local process index: 1 │ │
│ │ Device: cuda:1 │ │
│ │ │ │
│ │ Mixed precision type: no │ │
│ │ synchronized_generator = None │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'NoneType' object has no attribute 'sampler'
ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: 1) local_rank: 0 (pid: 132975) of binary: /mnt/cache/zhaofufangchen/anaconda3/envs/m3e/bin/python
Traceback (most recent call last):
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/bin/accelerate", line 8, in
sys.exit(main())
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/accelerate/commands/accelerate_cli.py", line 45, in main
args.func(args)
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/accelerate/commands/launch.py", line 970, in launch_command
multi_gpu_launcher(args)
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/accelerate/commands/launch.py", line 646, in multi_gpu_launcher
distrib_run.run(args)
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/torch/distributed/run.py", line 785, in run
elastic_launch(
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/torch/distributed/launcher/api.py", line 134, in call
return launch_agent(self._config, self._entrypoint, list(args))
File "/mnt/cache/zhaofufangchen/anaconda3/envs/m3e/lib/python3.10/site-packages/torch/distributed/launcher/api.py", line 250, in launch_agent
raise ChildFailedError(
torch.distributed.elastic.multiprocessing.errors.ChildFailedError:

scripts/train_m3e.py FAILED

Failures:
[1]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 1 (local_rank: 1)
exitcode : 1 (pid: 132976)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
[2]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 2 (local_rank: 2)
exitcode : 1 (pid: 132977)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
[3]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 3 (local_rank: 3)
exitcode : 1 (pid: 132978)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
[4]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 4 (local_rank: 4)
exitcode : 1 (pid: 132979)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
[5]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 5 (local_rank: 5)
exitcode : 1 (pid: 132980)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
[6]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 6 (local_rank: 6)
exitcode : 1 (pid: 132981)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html
[7]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 7 (local_rank: 7)
exitcode : 1 (pid: 132982)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html

Root Cause (first observed failure):
[0]:
time : 2023-07-25_13:27:50
host : SH-IDC1-10-198-6-78
rank : 0 (local_rank: 0)
exitcode : 1 (pid: 132975)
error_file: <N/A>
traceback : To enable traceback see: https://pytorch.org/docs/stable/elastic/errors.html

请问这种问题怎么解决呢?如果需要什么更加详细的信息可以和我留言,这个问题确实困扰我很久了。。

Python Version

3.10

process_zh_datasets.py load_wiki_atomic_edits

🐛 bug 说明

load_wiki_atomic_edits的原始process函数如下

def _process(example):
return {
'base_sentence': concat_words(example['base_sentence'].split(' ')),
'edited_sentence': concat_words(example['edited_sentence'].split(' ')),
}

return 的key应该是'text'和'text_pos',而不是'base_sentence'和'edited_sentence'
这里应该写错了。

Python Version

None

T2Ranking检索任务的ground Truth(qrels)的处理是不是应该把 0 1 去掉呀

valid_qrels[qid] = qrels

代码里好像写的是所有的档次的doc都放进了valid_qrels里。
而在MTEB的代码里,在算NDCG的IDCG的时候,只要出现在valid_qrels都算作1,其他都是0。这样那些低档的也算为正确了。
https://github.com/embeddings-benchmark/mteb/blob/582553693de507f338a720a0bc572147b8c6ef33/mteb/evaluation/evaluators/RetrievalEvaluator.py#L212
不知道是不是我的理解有问题,还是代码没考虑到?

m3e有什么特别的改进吗?

🐛 bug 说明

Hi @wangyuxinwhy
感谢分享,主要是有个问题想讨论一下。虽然m3e在几个开源测试集上指标有提升,但是相比openai-ada-002,抗干扰能力明显变弱

比如在自己构造的一份检索的测试集上,m3e-base几乎不能正确召回,luotuo为开源的在openai向量上蒸馏出来的向量模型,虽然效果远不如openai的结果,但是对比m3e也是优势比较大
image

luotuo用你们的评测代码,效果是远不如m3e的
image

测试代码如下:
每个docs是3条数据,docs[0]为问题q, docs[1]为m3e检索回来的相似度最高的doc片段, docs[2]为正确的doc片段

from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
model_path = 'moka-ai/m3e-base'
model = SentenceTransformer(model_path)

docs = ["富森美公司的主要收入模式是什么",
"""公司多年来深耕装饰建材
家居业务,合理设置卖场定位,拥有大量优质代理商、经销商客户资源, 同时,公司在集
合式营销、市场管理、资源整合、产品促销等方面不断创新, 相继被中宣部等八部委联合
授予“全国百城万店无假货示范市场” ,被 国家工商总局授予“全国诚信示范市场” ,被
国家质检总局授予 “全国购物放心市场” ,被 四川省人民政府授予“四川省服务名牌企业”
等荣誉称号, 逐渐树立起品牌规范性专业市场形象 。“富森美”品牌已成为成都及四川地
区具有广泛影响力的装饰建材流通类品牌,在消费者心��中享有较高的品牌认知度和美誉
度,有力地支持了公司渠道扩张和商业模式的实行。  


“服务 +产品”策略, 全业态定位满足消费者需求 。在区域专业市场中, 公司通过 合理的
定位、 高度的便利性和全面的 “服务 +产品” 策略 有效地吸引商户入驻和消费者体验、 消费。""",
 
"""公司目前
自持卖场物业建筑面积超过 110 万平方米, 2019 年底加盟及委托管理卖场经营规模达到
51.6 万平方米, 公司自有和委管卖场均使用的 “富森美” 品牌, 近三年获评 2018 年和 2019
年的**家居品牌大会“**十大家居连锁卖场”以及“ 2019 -2020 十大优选**家居消
费平台” 。公司当前主要收入模式来自卖场招商收租金, 毛利率、 净利率和成本费用率均处
于行业前列,富森美主要优点在于: 1)自持物业成本低; 2)精细化运营能力强,布局多
层次业态,差异化招商、服务; 3)产业链整合创新能力突出,平台资源丰富。 
 数字化整合升 级, 加速新零售布局。公司紧跟家居行业个性化等需求增长的趋势, 围绕 “引
流和赋能” ,通过微信小程序、网上直播、联合营销、专场活动以及优化品牌结构等多种方
式巩固公司的区域优势,重点对卖场数字化升级,实现线上流量的精准转化,同时提升运
营效率。"""]
embeddings = model.encode(docs)
print(cosine_similarity(embeddings))


docs = ["富森美公司的风险提示有哪些",
"""公司报告  
请务必仔细阅读正文之后的各项信息披露与声明  第21页 共28页                        简单金融  成就梦想  
 
2019 年富森美在 **上市公司口碑榜 当中荣获 “最具成长性新零售产业上市公司” ,
公司发展新零售模式主要优势在于: 1)创始人 多年从事装饰建材家居行业工作, 始终以
用户思维、产品思维而非商业地产思维发展业务 ,创新打造或孵化出多层次新业态 ;2)
品牌与销售方面, 公司 始终深耕产品,协助商户完成各类产品的市场营销活动, 为厂家和
商户提供了全产业链服务, 具备良好的销售经验和基础; 3)公司的供应链体系完整,资
源丰富,平台优势突出; 4)新零售项目运营团队年轻化,由 90后担纲运营,能够准确地
把握当代消费者的需求 。""",
 
"""我们对
公司 2020~2022 年EPS 预测分别为 0.89 元/1.09 元/1.26 元,对应 PE分别为
18X/15X/13X ,首次覆盖,给予“买入”评级。  
 风险提示: 地产景气周期下滑,市场竞争加剧,公司新零售业务发展进度不及预期。  
市场数据:  2020 年12月08日 
收盘价(元 )  16.15  
一年内最高 /最低(元)  16.85 /10.47  
市净率  2.3 
息率(分红 /股价)  2.17 
流通 A股 市 值 ( 百 万 元 )  4819  
上证指数 /深证成指  3410.18 /13973.89  
注:“息率 ” 以 最 近 一 年 已 公 布 分 红 计 算  
  
基础数据 : 2020 年09月30日 
每股净资产 ( 元 )  7.02 
资产负债率 % 14."""]
embeddings = model.encode(docs)
print(cosine_similarity(embeddings))

"""
[[1.         0.8282594  0.79422724]
 [0.8282594  1.         0.89455336]
 [0.79422724 0.89455336 0.9999997 ]]

[[1.        0.8106332 0.6698204]
 [0.8106332 1.        0.8019115]
 [0.6698204 0.8019115 0.9999999]]
"""

Python Version

None

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.