[실험] token_size 변경 후 PPL 변화 측정
1. 개요
- 원본 코드에서 원하는 token_size는 너무 길어서 현재 컴퓨팅 파워로는 결과를 보기 어려움.
 - 적절한 token_size를 선택할 필요가 있음.
 - 원본 코드의 token_size는 activation.py 실행에 약 7시간 소요.
 - 따라서 token_size를 24K와 2.4M로 조절하여 PPL값을 분석한다.
 - Activation 값은 0으로 고정한다.
 
2. Tokenizer.py
- Train token은 0번부터 원하는 size까지 조절하여 저장한다.
 - valid token은 train token size까지는 버리고 그 뒤부터 저장한다.
 
import os
import torch
from datasets import load_dataset
from transformers import AutoTokenizer
from tqdm import tqdm
def process_language(lang, config_name):
    """
    주어진 언어에 대해 위키백과 데이터셋을 로드, 토크나이즈하고,
    토큰 리스트를 LongTensor로 변환한 뒤 별도의 파일로 저장합니다.
    """
    print(f"\n[{lang}] 데이터 처리 시작 (config: {config_name})")
    # 데이터셋 로드
    dataset = load_dataset("wikimedia/wikipedia", config_name, cache_dir= "/mnt/data6/huggingface_cache")
    # LLaMA와 호환되는 토크나이저 초기화 (필요에 따라 다른 모델로 변경 가능)
    tokenizer = AutoTokenizer.from_pretrained("huggyllama/llama-7b", use_fast=True)
    token_ids = []
    token_len = 0
    # 데이터셋의 "train" split에 대해 토크나이즈 진행
    for example in tqdm(dataset["train"], desc=f"{lang} 토크나이즈 진행중"):
        text = example["text"]
        tokens = tokenizer.encode(text, add_special_tokens=False)
        token_len += len(tokens)
        if token_len <= 2400000: # valid token size 조절
            continue
        token_ids.extend(tokens)
        if len(token_ids) >= 2400000: # train token size 조절
            break
    # 리스트를 LongTensor로 변환
    tokens_tensor = torch.tensor(token_ids, dtype=torch.long)
    # 출력 디렉토리 생성
    os.makedirs("data", exist_ok=True)
    # 언어별 파일명: data/{lang}.train.llama
    output_file = f"data/token_size_2.4M/valid/id.{lang}.valid.llama"
    torch.save(tokens_tensor, output_file)
    print(len(token_ids))
    print(f"[{lang}] 토크나이즈된 데이터가 {output_file} 에 저장되었습니다.")
def main():
    # 언어별 구성: key는 언어 코드, value는 해당 구성 이름 (예: 최신 날짜 구성)
    languages = {
        "en": "20231101.en",
        "zh": "20231101.zh",
        "fr": "20231101.fr",
        "es": "20231101.es",
        "vi": "20231101.vi",
        "id": "20231101.id",
        "ja": "20231101.ja"
    }
    for lang, config_name in languages.items():
        process_language(lang, config_name)
if __name__ == "__main__":
    main()
2. Token_size: 24K
- 
Token_size를 24K로 조절하여 PPL값을 분석한다.
 - 
아래의 표는 activation_mask를 씌운 PPL값에서 activation_mask를 하지 않은 PPL값을 뺸 값이다.
- 
$$ P = P_a - P_0 $$
- 
$P_a$ : 언어별 mask 씌운뒤 PPL 값
 - 
$P_0$: mask를 씌우지 않은 PPL 값
 
 - 
 
 - 
 
| en | zh | fr | es | vi | id | ja | |
|---|---|---|---|---|---|---|---|
| en | 0.001085 | 0.014781 | 0.005042 | 0.007821 | 0.007438 | 0.005447 | 0.010051 | 
| zh | 0.001629 | 0.108548 | 0.005350 | 0.004944 | 0.024637 | 0.006502 | 0.082292 | 
| fr | 0.003134 | 0.005830 | 0.062286 | 0.037556 | 0.010154 | 0.014436 | 0.004016 | 
| es | 0.003797 | 0.006993 | 0.027820 | 0.078101 | 0.015346 | 0.018523 | 0.006489 | 
| vi | 0.002300 | 0.019806 | 0.013916 | 0.020379 | 0.169570 | 0.029632 | 0.008226 | 
| id | 0.003617 | 0.007540 | 0.012297 | 0.022278 | 0.018761 | 0.102763 | 0.004672 | 
| Ja | 0.001656 | 0.064267 | 0.006124 | 0.005797 | 0.015805 | 0.007045 | 0.159938 | 
3. Token_size: 2.4M
- 
Token_size를 2.4M로 조절하여 PPL값을 분석한다.
 - 
아래의 표는 activation_mask를 씌운 PPL값에서 activation_mask를 하지 않은 PPL값을 뺸 값이다.
- 
$$ P = P_a - P_0 $$
- 
$P_a$ : 언어별 mask 씌운뒤 PPL 값
 - 
$P_0$: mask를 씌우지 않은 PPL 값
 
 - 
 
 - 
 
| en | zh | fr | es | vi | id | ja | |
|---|---|---|---|---|---|---|---|
| en | -0.027972 | -0.043170 | 0.044069 | 0.026746 | 0.064751 | 0.024219 | 0.027064 | 
| zh | -0.027634 | 0.034790 | 0.046063 | 0.028860 | 0.079462 | 0.028540 | 0.096886 | 
| fr | -0.026866 | -0.048197 | 0.117208 | 0.064232 | 0.068227 | 0.033389 | 0.021538 | 
| es | -0.026121 | -0.049498 | 0.069080 | 0.097998 | 0.074034 | 0.036817 | 0.024023 | 
| vi | -0.028003 | -0.035161 | 0.053906 | 0.038608 | 0.220909 | 0.046700 | 0.026712 | 
| id | -0.026389 | -0.046483 | 0.051871 | 0.040412 | 0.073968 | 0.116167 | 0.021801 | 
| ja | -0.028558 | 0.003986 | 0.046061 | 0.027811 | 0.076806 | 0.026932 | 0.205830 | 
4. 분석
- Token size 조절 전후 PPL 값은 변화가 있지만, 논문과 비교했을 때 값의 차이가 있음
- Token_size가 24K일 때 논문 PPL값과 약 8배 차이
 - Token_size가 2.4M일 때 논문 PPL 값과 약 4배 차이
 
 - 하지만 target 언어에 대해서 mask를 한 PPL값과 하지 않은 PPL 값이 차이가 뚜렷한 것으로 보아 언어별 뉴런을 잘 찾아낸다고 보인다.