5
Konfigurasi Argumen dan Pemilihan Model
main.py menyusun konfigurasi dalam dua langkah sebelum model dibuat: get_parser mengumpulkan nilai mentah dari baris perintah, lalu append_dataset_args menurunkan sisa konfigurasi dari satu nilai --dataset. Setelah dict argumen lengkap, load_model dipanggil untuk memilih arsitektur dan tokenizer dari string --model_checkpoint (main.py:141-1421). Label mapping diambil dari kelas dataset tepat sebelum model dimuat (main.py:156-1602).
Parser mengembalikan dict, bukan namespace
get_parser mendaftarkan seluruh flag training, mencetak isinya lewat print_opts, lalu mengembalikan vars(parser.parse_args()). Karena hasilnya dict, semua modul berikutnya membaca nilai sebagai args['...'] dan bukan atribut namespace (utils/args_helper.py:33-603).
Default yang menentukan cabang kode berikutnya (utils/args_helper.py:37-564):
| Flag | Default | Dipakai oleh |
|---|---|---|
--dataset | emotion-twitter | cabang di append_dataset_args |
--model_checkpoint | bert-base-multilingual-uncased | cabang di load_model |
--max_seq_len | 512 | dataloader_class saat training |
--train_batch_size / --valid_batch_size | 4 / 4 | dataloader train dan validasi |
--lr | 6.25e-5 | optimizer Adam |
--n_epochs | 10 | pemanggilan train(...) |
--num_layers | 12 | config.num_hidden_layers pada cabang fasttext dan scratch |
--early_stop | 3 | pemanggilan train(...) |
--device | cuda | pemindahan model ke GPU dan forward_fn |
--lower | flag store_true | lowercase dataset dan SimpleTokenizer |
Dari --dataset ke kelas dan path
append_dataset_args adalah rantai if/elif atas args['dataset'] yang ditutup return args (utils/args_helper.py:83-1015). Satu nama dataset mengisi empat belas kunci sekaligus: task, num_labels, dataset_class, dataloader_class, forward_fn, metrics_fn, valid_criterion, tiga path split, vocab_path, embedding_path, k_fold, dan word_tokenizer_class. Diagram berikut memisahkan jalur task dari jalur kelas dan path.
graph TD
ARGV["argv: --dataset, --model_checkpoint, --max_seq_len, ..."] --> GP["get_parser()"]
GP --> RAW["args dict mentah"]
RAW --> ADA["append_dataset_args(args)"]
ADA --> SEL{"args['dataset']"}
SEL -->|"emotion-twitter, entailment-ui, doc-sentiment-prosa"| SC["task = sequence_classification"]
SEL -->|"absa-airy, absa-prosa"| MLC["task = multi_label_classification"]
SEL -->|"tujuh task token lain"| TC["task = token_classification"]
SC --> F1["forward_sequence_classification"]
MLC --> F2["forward_sequence_multi_classification"]
TC --> F3["forward_word_classification"]
F1 --> BUNDLE["dataset_class, dataloader_class, metrics_fn, valid_criterion, *_set_path"]
F2 --> BUNDLE
F3 --> BUNDLE
BUNDLE --> MAIN["main.py: dataset_class(path, tokenizer, ...) + dataloader_class(...)"]
SEL -->|"nama di luar daftar"| ERR["raise ValueError: Unknown dataset name"]
style BUNDLE fill:#f59e0b,color:#000
style MAIN fill:#2d7d46,color:#fff
style ERR fill:#dc2626,color:#fff
style RAW fill:#8b5cf6,color:#fff
%% fig: Peta nilai --dataset ke bundel konfigurasi
%% desc: Satu nilai --dataset memilih task, forward_fn, metrics_fn, kelas dataset, dataloader, dan path berkas data yang kemudian dipakai main.py.Seluruh dua belas cabang, lengkap dengan kelas dan path yang dihasilkannya:
--dataset | task | dataset_class | dataloader_class | forward_fn | metrics_fn | direktori data |
|---|---|---|---|---|---|---|
emotion-twitter | sequence_classification | EmotionDetectionDataset | EmotionDetectionDataLoader | forward_sequence_classification | emotion_detection_metrics_fn | ./dataset/emot_emotion-twitter/ utils/args_helper.py:84-946 |
absa-airy | multi_label_classification | AspectBasedSentimentAnalysisAiryDataset | AspectBasedSentimentAnalysisDataLoader | forward_sequence_multi_classification | absa_metrics_fn | ./dataset/hoasa_absa-airy/ utils/args_helper.py:102-1127 |
term-extraction-airy | token_classification | AspectExtractionDataset | AspectExtractionDataLoader | forward_word_classification | aspect_extraction_metrics_fn | ./dataset/terma_term-extraction-airy/ utils/args_helper.py:120-1308 |
ner-grit | token_classification | NerGritDataset | NerDataLoader | forward_word_classification | ner_metrics_fn | ./dataset/nergrit_ner-grit/ utils/args_helper.py:138-1489 |
pos-idn | token_classification | PosTagIdnDataset | PosTagDataLoader | forward_word_classification | pos_tag_metrics_fn | ./dataset/bapos_pos-idn/ utils/args_helper.py:156-16610 |
entailment-ui | sequence_classification | EntailmentDataset | EntailmentDataLoader | forward_sequence_classification | entailment_metrics_fn | ./dataset/wrete_entailment-ui/ utils/args_helper.py:174-18411 |
doc-sentiment-prosa | sequence_classification | DocumentSentimentDataset | DocumentSentimentDataLoader | forward_sequence_classification | document_sentiment_metrics_fn | ./dataset/smsa_doc-sentiment-prosa/ utils/args_helper.py:192-20212 |
keyword-extraction-prosa | token_classification | KeywordExtractionDataset | KeywordExtractionDataLoader | forward_word_classification | keyword_extraction_metrics_fn | ./dataset/keps_keyword-extraction-prosa/ utils/args_helper.py:210-22013 |
qa-factoid-itb | token_classification | QAFactoidDataset | QAFactoidDataLoader | forward_word_classification | qa_factoid_metrics_fn | ./dataset/facqa_qa-factoid-itb/ utils/args_helper.py:228-23814 |
ner-prosa | token_classification | NerProsaDataset | NerDataLoader | forward_word_classification | ner_metrics_fn | ./dataset/nerp_ner-prosa/ utils/args_helper.py:246-25615 |
pos-prosa | token_classification | PosTagProsaDataset | PosTagDataLoader | forward_word_classification | pos_tag_metrics_fn | ./dataset/posp_pos-prosa/ utils/args_helper.py:264-27416 |
absa-prosa | multi_label_classification | AspectBasedSentimentAnalysisProsaDataset | AspectBasedSentimentAnalysisDataLoader | forward_sequence_multi_classification | absa_metrics_fn | ./dataset/casa_absa-prosa/ utils/args_helper.py:282-29217 |
Jumlah label tidak ditulis di tabel karena setiap cabang mengambilnya dari atribut kelas dataset, yaitu ...Dataset.NUM_LABELS, dan semua cabang menetapkan valid_criterion ke 'F1' (utils/args_helper.py:83-1015). Perbedaan terakhir di tingkat dataset adalah tokenizer kata: hanya keyword-extraction-prosa yang memakai WordSplitTokenizer (utils/args_helper.py:226-22718), sedangkan cabang lain memakai TweetTokenizer (utils/args_helper.py:13719).
Nama dataset yang tidak dikenal tidak diabaikan, tetapi langsung menghentikan proses:
raise ValueError(f'Unknown dataset name `{args["dataset"]}`')
Pesan itu berasal dari else di ujung rantai (utils/args_helper.py:300-30120).
Setelah dict lengkap, main.py mengonsumsi bundel tersebut. Ketiga path split diserahkan ke dataset_class bersama tokenizer, --lower, dan --no_special_token, lalu dataloader_class menerima --max_seq_len dan batch size (main.py:172-18221). --valid_batch_size dipakai untuk loader validasi sekaligus loader test (main.py:176-18222). forward_fn, metrics_fn, dan valid_criterion diteruskan ke train(...) (main.py:18523). Bentuk tiap kelas dataset dan dataloadernya dibahas di Data Utils dan Dataloader, isi forward_fn dan metrics_fn di Forward Pass dan Metrik Evaluasi, sedangkan tata letak berkasnya di Struktur Berkas Dataset dan Submission.
Dari --model_checkpoint ke arsitektur
load_model menerima dict yang sama dan mencocokkan substring args['model_checkpoint'] dengan enam penanda. Pencocokan memakai in, bukan kesamaan penuh, sehingga nilai seperti indobenchmark/indobert-lite-base-p1 tetap masuk ke cabang indobenchmark (utils/functions.py:286-29724).
graph TD
MC["args['model_checkpoint']"] --> C1{"'bert-base-multilingual'"}
C1 -->|"ya"| B1["BertTokenizer + BertConfig"]
C1 -->|"tidak"| C2{"'xlm-mlm'"}
C2 -->|"ya"| B2["XLMTokenizer + XLMConfig"]
C2 -->|"tidak"| C3{"'xlm-roberta'"}
C3 -->|"ya"| B3["XLMRobertaTokenizer + XLMRobertaConfig"]
C3 -->|"tidak"| C4{"'fasttext'"}
C4 -->|"ya"| B4["SimpleTokenizer + gen_embeddings(emb_dim=300)"]
C4 -->|"tidak"| C5{"'scratch'"}
C5 -->|"ya"| B5["BertTokenizer bert-base-uncased + BertConfig"]
C5 -->|"tidak"| C6{"'indobenchmark'"}
C6 -->|"ya"| B6["BertTokenizer + BertConfig; 'lite' -> Albert*"]
C6 -->|"tidak"| NONE["model dan tokenizer belum terikat saat return"]
B1 --> TASK{"args['task']"}
B2 --> TASK
B3 --> TASK
B4 --> TASK
B5 --> TASK
B6 --> TASK
TASK -->|"sequence_classification"| RET["return model, tokenizer, vocab_path, config_path"]
TASK -->|"token_classification"| RET
TASK -->|"multi_label_classification"| RET
style MC fill:#f59e0b,color:#000
style RET fill:#2d7d46,color:#fff
style NONE fill:#dc2626,color:#fff
style B4 fill:#8b5cf6,color:#fff
%% fig: Pemilihan arsitektur di load_model
%% desc: Enam penanda pada string --model_checkpoint memilih tokenizer dan config, lalu args['task'] memilih kelas kepala klasifikasi sebelum model dikembalikan.Rincian tiap cabang:
Penanda pada --model_checkpoint | Tokenizer | Config | Kelas model menurut args['task'] |
|---|---|---|---|
bert-base-multilingual | BertTokenizer.from_pretrained(args['model_checkpoint']) | BertConfig dari checkpoint yang sama | BertForSequenceClassification, BertForWordClassification, BertForMultiLabelClassification utils/functions.py:300-30525 |
xlm-mlm | XLMTokenizer utils/functions.py:306-31626 | XLMConfig | XLMForSequenceClassification, XLMForWordClassification, XLMForMultiLabelClassification utils/functions.py:319-32427 |
xlm-roberta | XLMRobertaTokenizer utils/functions.py:325-33528 | XLMRobertaConfig | XLMRobertaForSequenceClassification, XLMRobertaForWordClassification, XLMRobertaForMultiLabelClassification utils/functions.py:338-34329 |
fasttext | SimpleTokenizer(vocab_map, word_tokenizer, lower=args['lower']) | BertConfig.from_pretrained('bert-base-uncased') lalu hidden_size 300 dan num_attention_heads 10 | BertFor* diinstansiasi dari config, lalu bobot word_embeddings diisi gen_embeddings utils/functions.py:344-35430 |
scratch | BertTokenizer.from_pretrained('bert-base-uncased') | BertConfig.from_pretrained('bert-base-uncased') dengan hidden_size 300 dan num_attention_heads 10 | BertFor* dari config tanpa checkpoint utils/functions.py:380-39231 |
indobenchmark | BertTokenizer.from_pretrained(args['model_checkpoint']) | BertConfig dari checkpoint yang sama | AlbertFor* bila string memuat lite, selain itu BertFor* utils/functions.py:400-41032 |
Untuk task multi-label, args['num_labels'] berupa list. config.num_labels diisi max(list) dan list aslinya disimpan di config.num_labels_list (utils/functions.py:286-29724).
Cabang fasttext lebih jauh menyimpang dari cabang lain. Tokenizer dibangun dari vocab_path dataset lewat load_vocab, memakai word_tokenizer_class dan nilai --lower (utils/functions.py:344-35430). Config diturunkan dari bert-base-uncased lalu diubah: num_hidden_layers dari --num_layers, hidden_size 300, dan num_attention_heads 10 (utils/functions.py:356-36733). Bobot embedding diisi dari matriks hasil gen_embeddings (utils/functions.py:369-37834).
⚠️ Cabang
fasttextmengambil vektor lewatargs['embedding_path'][args['model_checkpoint']], sehingga nama checkpoint wajib menjadi kunci dict tersebut (utils/functions.py:344-35430). Contohnya cabangemotion-twitterhanya mendaftarkan kuncifasttext-cc-id-300-no-oov-uncaseddanfasttext-4B-id-300-no-oov-uncased(utils/args_helper.py:96-9935). Nama lain yang tetap memuat stringfasttextakan berhenti denganKeyErrorsebelum model dibentuk.
⚠️
load_modeltidak punyaelseterakhir. Checkpoint yang tidak memuat satu pun penanda di atas membuatmodeldantokenizerbelum terikat ketikareturn model, tokenizer, vocab_path, config_pathdijalankan (utils/functions.py:42136).
Nilai balik keempat dipakai pemanggilnya: vocab_path dan config_path disalin ke direktori eksperimen hanya bila tidak None (main.py:188-19137). Cabang scratch mengembalikan keduanya sebagai None, sedangkan cabang fasttext mengembalikan vocab_path milik dataset. Kelas kepala klasifikasi yang dipasang di tiap cabang dijelaskan di Modul Kepala Klasifikasi.
Nilai --model_checkpoint yang benar-benar dipakai skrip contoh:
| Nilai pada skrip | Cabang load_model |
|---|---|
scratch run_single_task.sh:238 | scratch, config dari bert-base-uncased |
fasttext-cc-id-300-no-oov-uncased run_single_task.sh:739 | fasttext, embedding dari embedding_path |
bert-base-multilingual-uncased run_single_task.sh:1740 | bert-base-multilingual |
xlm-roberta-base run_single_task.sh:2041 | xlm-roberta |
xlm-mlm-100-1280 run_single_task.sh:2442 | xlm-mlm |
indobenchmark/indobert-lite-base-p1 run_single_task.sh:3943 | indobenchmark dengan lite, sehingga memakai kelas Albert |
Jalur evaluasi memakai --model_type
get_eval_parser mendefinisikan --model_type, bukan --model_checkpoint, dan tidak memuat flag training seperti --lr atau --n_epochs (utils/args_helper.py:62-8044). predict.py memanggil get_eval_parser lalu append_dataset_args, jadi bundel dataset, forward_fn, dan metrics_fn tetap identik dengan training (predict.py:68-6945). Pemilihan arsitektur diserahkan ke load_eval_model, yang mencocokkan --model_type terhadap word2vec/fasttext, albert, babert, scratch, bert-base-multilingual, xlm-mlm-100-1280, dan xlm-roberta (utils/functions.py:222-23446).
| Jalur | Nama argumen | Fungsi pemilih |
|---|---|---|
training di main.py | --model_checkpoint | load_model (utils/functions.py:286-29724) |
evaluasi di predict.py | --model_type | load_eval_model (utils/functions.py:222-23446) |
Perbedaan nama argumen ini menjelaskan mengapa skrip prediksi menurunkan --model_type dari awalan nama direktori eksperimen, sedangkan training memakai nama checkpoint apa adanya. Alur prediksi selengkapnya ada di Inferensi dan Prediksi, dan urutan pemakaian argumen selama training di Alur Training dan Evaluasi. Pemetaan task ke kelompok klasifikasi dibahas di 12 Task Downstream dan Jenis Klasifikasi.