MCPcopy Create free account
hub / github.com/Pints-AI/1.5-Pints / DataCollatorForCausalLMDecoderOnlyChatML

Class DataCollatorForCausalLMDecoderOnlyChatML

finetune/datacollators.py:14–242  ·  view source on GitHub ↗

This DataCollator is purpose-made for ChatML templates. Referenced: https://medium.com/@xuebinbin12/fine-tuning-chat-based-llm-with-multi-turn-conversational-data-part-i-d8c64d01a20d

Source from the content-addressed store, hash-verified

12
13@dataclass
14class DataCollatorForCausalLMDecoderOnlyChatML(object):
15
16 '''
17 This DataCollator is purpose-made for ChatML templates.
18 Referenced: https://medium.com/@xuebinbin12/fine-tuning-chat-based-llm-with-multi-turn-conversational-data-part-i-d8c64d01a20d
19 '''
20 tokenizer: PreTrainedTokenizer
21 target_max_len: int
22
23 # Decoder only doesn't require source source_max_length
24 # source_max_length: int
25
26 # `train_on_source` in this context refers to calculating prediction losses on the "user" prompts
27 # In some cases where there are things to learn from the user prompts, this might help.
28 # However in some finetuning dataset, the user prompts mimick a real-world poor quality prompts.
29 # And usually doesn't contain anything useful. Therefore, prediction losses should be ignored,
30 # So that the model doesn't learn to mimick it.
31 train_on_source: bool
32 add_special_tokens: bool
33
34 def __call__(self, instances: Sequence[Dict]) -> Dict[str, torch.Tensor]:
35
36 if self.train_on_source:
37 message = 'In some cases where there are things to learn from the user prompts, this might help.'
38 message += 'However in some finetuning dataset, the user prompts mimick a real-world poor quality prompts.'
39 message += 'And usually doesn\'t contain anything useful. Therefore, prediction losses should be ignored.'
40 message += 'so that the model doesn\'t learn to mimick it.'
41 match input(f'{message}\n\nAre you sure you want to continue? (yes/no): '):
42 case 'yes':
43 pass
44 case _:
45 exit()
46
47 # In decoder-only model, we concat source and targets
48 contents: List[str] = []
49
50 for example in instances:
51 content = example['input'] + example['output']
52 contents.append(content)
53
54 # Default is to not train on source, so we ignore losses on the source with IGNORE_INDEX
55 if not self.train_on_source:
56
57 # identify the start and end of the sequence to ignore losses
58 # <|im_start|>user\nhello~<|im_end|>\n<|im_start|>assistant\nHow may I help?<|im_end|>
59 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60 # The ^ represents the positions that we will apply IGNORE_INDEX
61
62 # To do the ignore_index for cross-entropy loss, we need the start tokens and the end tokens to ignore
63 start_tokens = self.tokenizer.encode(
64 '<|im_start|>user\n',
65 max_length=999,
66 truncation=True,
67 add_special_tokens=False,
68 )
69 end_tokens = self.tokenizer.encode(
70 '<|im_start|>assistant\n',
71 max_length=999,

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected