kongds / scaling_sentemb

Scaling Sentence Embeddings with Large Language Models
85 stars 4 forks source link

关于DataCollatorForSeq2SeqForNeg #12

Closed AnonymXXXXX closed 4 months ago

AnonymXXXXX commented 4 months ago

Hi~

我发现下述代码中,__call__ 方法的 features 参数中的每个元素(一个 dict)只包含 input_idsattention_masklabels 这三个键,之前添加的一系列 s{prefix} 都去哪里了呢?如果我想要增添新的 key 该怎么做呢?

@dataclass
class DataCollatorForSeq2SeqForNeg:
    tokenizer: PreTrainedTokenizerBase
    model: Optional[Any] = None
    padding: Union[bool, str, PaddingStrategy] = True
    max_length: Optional[int] = None
    pad_to_multiple_of: Optional[int] = None
    label_pad_token_id: int = -100
    return_tensors: str = "pt"

    def __call__(self, features, return_tensors=None):
kongds commented 4 months ago

你好 这里为了方便在tokenize的时候,用input_ids,attention_mask,labels分别存了sent0, sent1, neg对应的input_ids(舍弃了attention_mask和labels),代码如下

https://github.com/kongds/scaling_sentemb/blob/8567aa083c1b3c77586670f91e7f78eb80694ad3/ft_llm.py#L358-L365

DataCollatorForSeq2SeqForNeg只是根据sent0, sent1, neg这几个去pad对应的input_ids

compute_loss的时候会,根据input_ids,attention_mask,labels拿到对应的input_ids并拼接 https://github.com/kongds/scaling_sentemb/blob/8567aa083c1b3c77586670f91e7f78eb80694ad3/ft_llm.py#L123

如果想要添加新的key可以在tokenize加入,修改DataCollatorForSeq2SeqForNeg里的pad,并在training_args里加上remove_unused_columns=False,应该就行

AnonymXXXXX commented 4 months ago

我的确有尝试在tokenize中引入新的key,但在DataCollatorForSeq2SeqForNeg__call__方法中,features中仍旧只有input_idsattention_masklabels。我自己新加入的key以及如下方法引入的一系列新的key(如sinput)似乎都被自动移除了

def generate_sentemb_prompt(data_point, tokenizer, cutoff_len, template, prefix='input'):
    sp = f's{prefix}'
    if sp not in data_point:
        input = tokenizer(
            data_point[prefix],
            truncation=True,
            max_length=cutoff_len,
            padding=False,
            return_tensors=None,
            add_special_tokens=False,
        )
        input = tokenizer.decode(input['input_ids'])
        data_point[sp] = input
    else:
        input = data_point[sp]

    template = template.replace('_', ' ').replace('*sep+*', '')\
                                         .replace('*cls*', '')
    return template.replace('*sent 0*', input).strip()

另外,关于您所说的“在training_args里加上remove_unused_columns=False” 具体是如何设置呢,我发现源代码中并不包含remove_unused_columns这一选项。

kongds commented 4 months ago

这个是huggingface trainer的参数(具体可以参考的document),他默认会移除不是模型输入的key,所以需要加remove_unused_columns这个选项栏。 另外可以加在这个位置 https://github.com/kongds/scaling_sentemb/blob/8567aa083c1b3c77586670f91e7f78eb80694ad3/ft_llm.py#L488

AnonymXXXXX commented 4 months ago

您的建议切实有效,非常感谢。