Collate: ํจ๊ป ํฉ์น๋ค.
์ด์์ ์ ์ถ๊ฐ๋ฅํ๋ฏ, Data Collator๋ ๋ค์๊ณผ ๊ฐ์ ์ญํ ์ ์ํํ๋ค.
Data Collator
Data Collator
์ผ๋ จ์ sample list๋ฅผ "single training mini-batch"์ Tensorํํ๋ก ๋ฌถ์ด์ค.
์ด๋ ์๋์ฒ๋ผ train_dataset์ด data_collator๋ฅผ ์ด์ฉํด mini-batch๋ก ๋ฌถ์ฌ ๋ชจ๋ธ๋ก ๋ค์ด๊ฐ ํ์ตํ๋๋ฐ ๋์์ด ๋๋ค.
trainer = Trainer( model=model, train_dataset=train_dataset, eval_dataset=eval_dataset, data_collator=data_collator,โ
batch["input_ids"] , batch["labels"] ?
๋ค๋ง, ์์ ๋ฌ๋ฆฌ ๋๋ถ๋ถ์ Data Collatorํจ์๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ์ ์ฝ๋์ ํํ๋ฅผ ๋ ๋๋ฐ, ์ฌ๊ธฐ์ input_ids์ label์ด๋ผ๋ ์กฐ๊ธ ์์ํ ๋จ์ด๊ฐ ์๋ค:
class MyDataCollator: def __init__(self, processor): self.processor = processor def __call__(self, examples): texts = [] images = [] for example in examples: image, question, answer = example messages = [{"role": "user", "content": question}, {"role": "assistant", "content": answer}] # <-- ์ฌ๊ธฐ๊น์ง ์ ๋ค์ด๊ฐ๋๊ฒ ํ์ธ์๋ฃ. text = self.processor.tokenizer.apply_chat_template(messages, add_generation_prompt=False) texts.append(text) images.append(image) batch = self.processor(text=text, images=image, return_tensors="pt", padding=True) labels = batch["input_ids"].clone() if self.processor.tokenizer.pad_token_id is not None: labels[labels == self.processor.tokenizer.pad_token_id] = -100 batch["labels"] = labels return batch data_collator = MyDataCollator(processor)โ
๊ณผ์ฐ batch["input_ids"]์ batch["labels"]๊ฐ ๋ญ๊น?
์ ์ ํ๋ data_collator๋ ์๋์ ๊ฐ์ ํ์์ ๋ ๋๋ฐ, ์ฌ๊ธฐ์๋ ๋ณด๋ฉด inputs์ labels๊ฐ ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ชจ๋ ๋ชจ๋ธ์ ๋ค๋ฅด์ง๋ง, ๋ค๋ฅธ๋ชจ๋ธ๊ณผ ์ ์ฌํ์ ์ ๊ณต์ ํ๋ค
= ๋๋ถ๋ถ์ ๋ชจ๋ธ์ ๋์ผํ ์ ๋ ฅ์ ์ฌ์ฉํ๋ค!
โInput IDs
Input ID๋ ๋ชจ๋ธ์ ์ ๋ ฅ์ผ๋ก ์ ๋ฌ๋๋ "์ ์ผํ ํ์ ๋งค๊ฐ๋ณ์"์ธ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
Input ID๋ token_index๋ก, ์ฌ์ฉํ sequence(๋ฌธ์ฅ)๋ฅผ ๊ตฌ์ฑํ๋ token์ ์ซ์ํํ์ด๋ค.
๊ฐ tokenizer๋ ๋ค๋ฅด๊ฒ ์๋ํ์ง๋ง "๊ธฐ๋ณธ ๋ฉ์ปค๋์ฆ์ ๋์ผ"ํ๋ค.
ex)from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained("bert-base-cased") sequence = "A Titan RTX has 24GB of VRAM"
tokenizer๋ sequence(๋ฌธ์ฅ)๋ฅผ tokenizer vocab์ ์๋ Token์ผ๋ก ๋ถํ ํ๋ค:tokenized_sequence = tokenizer.tokenize(sequence)
token์ word๋ subword ๋์ค ํ๋์ด๋ค:print(tokenized_sequence) # ์ถ๋ ฅ: ['A', 'Titan', 'R', '##T', '##X', 'has', '24', '##GB', 'of', 'V', '##RA', '##M'] # ์๋ฅผ ๋ค์ด, "VRAM"์ ๋ชจ๋ธ ์ดํ์ ์์ด์ "V", "RA" ๋ฐ "M"์ผ๋ก ๋ถํ ๋จ. # ์ด๋ฌํ ํ ํฐ์ด ๋ณ๋์ ๋จ์ด๊ฐ ์๋๋ผ ๋์ผํ ๋จ์ด์ ์ผ๋ถ์์ ๋ํ๋ด๊ธฐ ์ํด์๋? # --> "RA"์ "M" ์์ ์ด์คํด์(##) ์ ๋์ฌ๊ฐ ์ถ๊ฐ๋ฉ inputs = tokenizer(sequence)
์ด๋ฅผ ํตํด token์ ๋ชจ๋ธ์ด ์ดํด๊ฐ๋ฅํ ID๋ก ๋ณํ๋ ์ ์๋ค.
์ด๋, ๋ชจ๋ธ๋ด๋ถ์์ ์๋ํ๊ธฐ ์ํด์๋ input_ids๋ฅผ key๋ก, ID๊ฐ์ value๋ก ํ๋ "๋์ ๋๋ฆฌ"ํํ๋ก ๋ฐํํด์ผํ๋ค:encoded_sequence = inputs["input_ids"] print(encoded_sequence) # ์ถ๋ ฅ: [101, 138, 18696, 155, 1942, 3190, 1144, 1572, 13745, 1104, 159, 9664, 2107, 102]
๋ํ, ๋ชจ๋ธ์ ๋ฐ๋ผ์ ์๋์ผ๋ก "special token"์ ์ถ๊ฐํ๋๋ฐ,
์ฌ๊ธฐ์๋ ๋ชจ๋ธ์ด ๊ฐ๋ ์ฌ์ฉํ๋ "special IDs"๊ฐ ์ถ๊ฐ๋๋ค.decoded_sequence = tokenizer.decode(encoded_sequence) print(decoded_sequence) # ์ถ๋ ฅ: [CLS] A Titan RTX has 24GB of VRAM [SEP]
โAttention Mask
Attention Mask๋ Sequence๋ฅผ batch๋ก ๋ฌถ์ ๋ ์ฌ์ฉํ๋ Optionalํ ์ธ์๋ก
"๋ชจ๋ธ์ด ์ด๋ค token์ ์ฃผ๋ชฉํ๊ณ ํ์ง ๋ง์์ผ ํ๋์ง"๋ฅผ ๋ํ๋ธ๋ค.
ex)
์๋ฅผ ๋ณด๋ฉด, encoding๋ ๊ธธ์ด๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ "๋์ผํ Tensor๋ก ๋ฌถ์ ์๊ฐ ์๋ค."from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained("bert-base-cased") sequence_a = "This is a short sequence." sequence_b = "This is a rather long sequence. It is at least longer than the sequence A." encoded_sequence_a = tokenizer(sequence_a)["input_ids"] encoded_sequence_b = tokenizer(sequence_b)["input_ids"] len(encoded_sequence_a), len(encoded_sequence_b) # ์ถ๋ ฅ: (8, 19)
--> padding์ด๋ truncation์ด ํ์ํจ.
attention_mask๋ tokenizer๊ฐ ๋ฐํํ๋ dictionary์ "attention_mask" key์ ์กด์ฌํ๋ค.padded_sequences = tokenizer([sequence_a, sequence_b], padding=True) padded_sequences["input_ids"] # ์ถ๋ ฅ: [[101, 1188, 1110, 170, 1603, 4954, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 1188, 1110, 170, 1897, 1263, 4954, 119, 1135, 1110, 1120, 1655, 2039, 1190, 1103, 4954, 138, 119, 102]] padded_sequences["attention_mask"] # ์ถ๋ ฅ: [[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
โToken Types IDs
์ด๋ค ๋ชจ๋ธ์ ๋ชฉ์ ์ classification์ด๋ QA์ด๋ค.
์ด๋ฐ ๋ชจ๋ธ์ 2๊ฐ์ "๋ค๋ฅธ ๋ชฉ์ ์ ๋จ์ผ input_ids"ํญ๋ชฉ์ผ๋ก ๊ฒฐํฉํด์ผํ๋ค.
= [CLS], [SEP] ๋ฑ์ ํน์ํ ํฐ์ ์ด์ฉํด ์ํ๋จ.
ex)
์์ ์์ ์์ tokenizer๋ฅผ ์ด์ฉํด 2๊ฐ์ sequence๊ฐ 2๊ฐ์ ์ธ์๋ก ์ ๋ฌ๋์ด ์๋์ผ๋ก ์์๊ฐ์ ๋ฌธ์ฅ์ ์์ฑํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.# [CLS] SEQUENCE_A [SEP] SEQUENCE_B [SEP] from transformers import BertTokenizer tokenizer = BertTokenizer.from_pretrained("bert-base-cased") sequence_a = "HuggingFace is based in NYC" sequence_b = "Where is HuggingFace based?" encoded_dict = tokenizer(sequence_a, sequence_b) decoded = tokenizer.decode(encoded_dict["input_ids"]) print(decoded) # ์ถ๋ ฅ: [CLS] HuggingFace is based in NYC [SEP] Where is HuggingFace based? [SEP]
์ด๋ seq์ดํ์ ๋์ค๋ seq์ ์์์์น๋ฅผ ์๊ธฐ์๋ ์ข๋ค.
๋ค๋ง, ๋ค๋ฅธ ๋ชจ๋ธ์ token_types_ids๋ ์ฌ์ฉํ๋ฉฐ, token_type_ids๋ก ์ด MASK๋ฅผ ๋ฐํํ๋ค.
encoded_dict['token_type_ids'] # ์ถ๋ ฅ: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
์ง๋ฌธ์ ์ฌ์ฉ๋๋ context๋ ๋ชจ๋ 0์ผ๋ก,
์ง๋ฌธ์ ํด๋น๋๋ sequence๋ ๋ชจ๋ 1๋ก ์ค์ ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
โPosition IDs
RNN: ๊ฐ ํ ํฐ์ ์์น๊ฐ ๋ด์ฅ.
Transformer: ๊ฐ ํ ํฐ์ ์์น๋ฅผ ์ธ์ โ
∴ position_ids๋ ๋ชจ๋ธ์ด ๊ฐ ํ ํฐ์ ์์น๋ฅผ list์์ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋๋ optional ๋งค๊ฐ๋ณ์.๋ชจ๋ธ์ position_ids๊ฐ ์ ๋ฌ๋์ง ์์ผ๋ฉด, ID๋ ์๋์ผ๋ก Absolute positional embeddings์ผ๋ก ์์ฑ:
Absolute positional embeddings์ [0, config.max_position_embeddings - 1] ๋ฒ์์์ ์ ํ.
์ผ๋ถ ๋ชจ๋ธ์ sinusoidal position embeddings์ด๋ relative position embeddings๊ณผ ๊ฐ์ ๋ค๋ฅธ ์ ํ์ positional embedding์ ์ฌ์ฉ.
โLabels
Labels๋ ๋ชจ๋ธ์ด ์์ฒด์ ์ผ๋ก ์์ค์ ๊ณ์ฐํ๋๋ก ์ ๋ฌ๋ ์ ์๋ Optional์ธ์์ด๋ค.
์ฆ, Labels๋ ๋ชจ๋ธ์ ์์ ์์ธก๊ฐ์ด์ด์ผ ํ๋ค: ํ์ค ์์ค์ ์ฌ์ฉํ์ฌ ์์ธก๊ฐ๊ณผ ์์๊ฐ(๋ ์ด๋ธ) ๊ฐ์ ์์ค์ ๊ณ์ฐ.
์ด๋, Labels๋ Model Head์ ๋ฐ๋ผ ๋ค๋ฅด๋ค:
- AutoModelForSequenceClassification: ๋ชจ๋ธ์ (batch_size)์ฐจ์ํ ์๋ฅผ ๊ธฐ๋ํ๋ฉฐ, batch์ ๊ฐ ๊ฐ์ ์ ์ฒด ์ํ์ค์ ์์ label์ ํด๋น.
- AutoModelForTokenClassification: ๋ชจ๋ธ์ (batch_size, seq_length)์ฐจ์ํ ์๋ฅผ ๊ธฐ๋ํ๋ฉฐ, ๊ฐ ๊ฐ์ ๊ฐ๋ณ ํ ํฐ์ ์์ label์ ํด๋น
- AutoModelForMaskedLM: ๋ชจ๋ธ์ (batch_size, seq_length)์ฐจ์ํ ์๋ฅผ ๊ธฐ๋ํ๋ฉฐ, ๊ฐ ๊ฐ์ ๊ฐ๋ณ ํ ํฐ์ ์์ ๋ ์ด๋ธ์ ํด๋น: label์ ๋ง์คํน๋ token_ids์ด๋ฉฐ, ๋๋จธ์ง๋ ๋ฌด์ํ ๊ฐ(๋ณดํต -100).
- AutoModelForConditionalGeneration: ๋ชจ๋ธ์ (batch_size, tgt_seq_length)์ฐจ์ํ ์๋ฅผ ๊ธฐ๋ํ๋ฉฐ, ๊ฐ ๊ฐ์ ๊ฐ ์ ๋ ฅ ์ํ์ค์ ์ฐ๊ด๋ ๋ชฉํ ์ํ์ค๋ฅผ ๋ํ๋ ๋๋ค. ํ๋ จ ์ค์๋ BART์ T5๊ฐ ์ ์ ํ ๋์ฝ๋ ์ ๋ ฅ ID์ ๋์ฝ๋ ์ดํ ์ ๋ง์คํฌ๋ฅผ ๋ด๋ถ์ ์ผ๋ก ๋ง๋ค๊ธฐ์ ๋ณดํต ์ ๊ณตํ ํ์X. ์ด๋ Encoder-Decoder ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ธ์๋ ์ ์ฉ๋์ง ์์. ๊ฐ ๋ชจ๋ธ์ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ฌ ๊ฐ ํน์ ๋ชจ๋ธ์ ๋ ์ด๋ธ์ ๋ํ ์์ธํ ์ ๋ณด๋ฅผ ํ์ธํ์ธ์.
๊ธฐ๋ณธ ๋ชจ๋ธ(BertModel ๋ฑ)์ Labels๋ฅผ ๋ฐ์๋ค์ด์ง ๋ชปํ๋๋ฐ, ์ด๋ฌํ ๋ชจ๋ธ์ ๊ธฐ๋ณธ ํธ๋์คํฌ๋จธ ๋ชจ๋ธ๋ก์ ๋จ์ํ ํน์ง๋ค๋ง ์ถ๋ ฅํ๋ค.
โ Decoder input IDs
์ด ์ ๋ ฅ์ ์ธ์ฝ๋-๋์ฝ๋ ๋ชจ๋ธ์ ํนํ๋์ด ์์ผ๋ฉฐ, ๋์ฝ๋์ ์ ๋ ฅ๋ ์ ๋ ฅ ID๋ฅผ ํฌํจํฉ๋๋ค.
์ด๋ฌํ ์ ๋ ฅ์ ๋ฒ์ญ ๋๋ ์์ฝ๊ณผ ๊ฐ์ ์ํ์ค-ํฌ-์ํ์ค ์์ ์ ์ฌ์ฉ๋๋ฉฐ, ๋ณดํต ๊ฐ ๋ชจ๋ธ์ ํน์ ํ ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.๋๋ถ๋ถ์ ์ธ์ฝ๋-๋์ฝ๋ ๋ชจ๋ธ(BART, T5)์ ๋ ์ด๋ธ์์ ๋์ฝ๋ ์ ๋ ฅ ID๋ฅผ ์์ฒด์ ์ผ๋ก ์์ฑํฉ๋๋ค.
์ด๋ฌํ ๋ชจ๋ธ์์๋ ๋ ์ด๋ธ์ ์ ๋ฌํ๋ ๊ฒ์ด ํ๋ จ์ ์ฒ๋ฆฌํ๋ ์ ํธ ๋ฐฉ๋ฒ์ ๋๋ค.
์ํ์ค-ํฌ-์ํ์ค ํ๋ จ์ ์ํ ์ด๋ฌํ ์ ๋ ฅ ID๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ํ์ธํ๋ ค๋ฉด ๊ฐ ๋ชจ๋ธ์ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
โFeed Forward Chunking
ํธ๋์คํฌ๋จธ์ ๊ฐ ์์ฐจ ์ดํ ์ ๋ธ๋ก์์ ์ ํ ์ดํ ์ ๋ ์ด์ด๋ ๋ณดํต 2๊ฐ์ ํผ๋ ํฌ์๋ ๋ ์ด์ด ๋ค์์ ์์นํฉ๋๋ค.
ํผ๋ ํฌ์๋ ๋ ์ด์ด์ ์ค๊ฐ ์๋ฒ ๋ฉ ํฌ๊ธฐ๋ ์ข ์ข ๋ชจ๋ธ์ ์จ๊ฒจ์ง ํฌ๊ธฐ๋ณด๋ค ํฝ๋๋ค(์: bert-base-uncased).ํฌ๊ธฐ [batch_size, sequence_length]์ ์ ๋ ฅ์ ๋ํด ์ค๊ฐ ํผ๋ ํฌ์๋ ์๋ฒ ๋ฉ์ ์ ์ฅํ๋ ๋ฐ ํ์ํ ๋ฉ๋ชจ๋ฆฌ [batch_size, sequence_length, config.intermediate_size]๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ํฐ ๋ถ๋ถ์ ์ฐจ์งํ ์ ์์ต๋๋ค.
Reformer: The Efficient Transformer์ ์ ์๋ค์ ๊ณ์ฐ์ด sequence_length ์ฐจ์๊ณผ ๋ ๋ฆฝ์ ์ด๋ฏ๋ก ๋ ํผ๋ ํฌ์๋ ๋ ์ด์ด์ ์ถ๋ ฅ ์๋ฒ ๋ฉ [batch_size, config.hidden_size]_0, ..., [batch_size, config.hidden_size]_n์ ๊ฐ๋ณ์ ์ผ๋ก ๊ณ์ฐํ๊ณ n = sequence_length์ ํจ๊ป [batch_size, sequence_length, config.hidden_size]๋ก ๊ฒฐํฉํ๋ ๊ฒ์ด ์ํ์ ์ผ๋ก ๋์ผํ๋ค๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค.
์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ด๋ ๋์ ๊ณ์ฐ ์๊ฐ์ ์ฆ๊ฐ์ํค๋ ๊ฑฐ๋๋ฅผ ํ์ง๋ง, ์ํ์ ์ผ๋ก ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.apply_chunking_to_forward() ํจ์๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ธ์ ๊ฒฝ์ฐ, chunk_size๋ ๋ณ๋ ฌ๋ก ๊ณ์ฐ๋๋ ์ถ๋ ฅ ์๋ฒ ๋ฉ์ ์๋ฅผ ์ ์ํ๋ฉฐ, ๋ฉ๋ชจ๋ฆฌ์ ์๊ฐ ๋ณต์ก์ฑ ๊ฐ์ ๊ฑฐ๋๋ฅผ ์ ์ํฉ๋๋ค. chunk_size๊ฐ 0์ผ๋ก ์ค์ ๋๋ฉด ํผ๋ ํฌ์๋ ์ฒญํน์ ์ํ๋์ง ์์ต๋๋ค.
'HuggingFace๐ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
HuggingFace(๐ค)์ ๋ฌธ์๋ฅผ ์ํ transformers ์ ๋ฆฌ (3) | 2024.11.18 |
---|---|
HuggingFace(๐ค)-Tutorials (1) | 2024.07.31 |
QLoRA ์ค์ต & Trainer vs SFTTrainer (0) | 2024.07.12 |
[QLoRA] & [PEFT] & deepspeed, DDP (0) | 2024.07.09 |