Lompat ke konten
dokumentasi.id
Commit ce728f6
v1
Star659

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-142). Label mapping diambil dari kelas dataset tepat sebelum model dimuat (main.py:156-160).

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-60).

Default yang menentukan cabang kode berikutnya (utils/args_helper.py:37-56):

FlagDefaultDipakai oleh
--datasetemotion-twittercabang di append_dataset_args
--model_checkpointbert-base-multilingual-uncasedcabang di load_model
--max_seq_len512dataloader_class saat training
--train_batch_size / --valid_batch_size4 / 4dataloader train dan validasi
--lr6.25e-5optimizer Adam
--n_epochs10pemanggilan train(...)
--num_layers12config.num_hidden_layers pada cabang fasttext dan scratch
--early_stop3pemanggilan train(...)
--devicecudapemindahan model ke GPU dan forward_fn
--lowerflag store_truelowercase 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-101). 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.
Fig. 1: Peta nilai --dataset ke bundel konfigurasiSatu 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:

--datasettaskdataset_classdataloader_classforward_fnmetrics_fndirektori data
emotion-twittersequence_classificationEmotionDetectionDatasetEmotionDetectionDataLoaderforward_sequence_classificationemotion_detection_metrics_fn./dataset/emot_emotion-twitter/ utils/args_helper.py:84-94
absa-airymulti_label_classificationAspectBasedSentimentAnalysisAiryDatasetAspectBasedSentimentAnalysisDataLoaderforward_sequence_multi_classificationabsa_metrics_fn./dataset/hoasa_absa-airy/ utils/args_helper.py:102-112
term-extraction-airytoken_classificationAspectExtractionDatasetAspectExtractionDataLoaderforward_word_classificationaspect_extraction_metrics_fn./dataset/terma_term-extraction-airy/ utils/args_helper.py:120-130
ner-grittoken_classificationNerGritDatasetNerDataLoaderforward_word_classificationner_metrics_fn./dataset/nergrit_ner-grit/ utils/args_helper.py:138-148
pos-idntoken_classificationPosTagIdnDatasetPosTagDataLoaderforward_word_classificationpos_tag_metrics_fn./dataset/bapos_pos-idn/ utils/args_helper.py:156-166
entailment-uisequence_classificationEntailmentDatasetEntailmentDataLoaderforward_sequence_classificationentailment_metrics_fn./dataset/wrete_entailment-ui/ utils/args_helper.py:174-184
doc-sentiment-prosasequence_classificationDocumentSentimentDatasetDocumentSentimentDataLoaderforward_sequence_classificationdocument_sentiment_metrics_fn./dataset/smsa_doc-sentiment-prosa/ utils/args_helper.py:192-202
keyword-extraction-prosatoken_classificationKeywordExtractionDatasetKeywordExtractionDataLoaderforward_word_classificationkeyword_extraction_metrics_fn./dataset/keps_keyword-extraction-prosa/ utils/args_helper.py:210-220
qa-factoid-itbtoken_classificationQAFactoidDatasetQAFactoidDataLoaderforward_word_classificationqa_factoid_metrics_fn./dataset/facqa_qa-factoid-itb/ utils/args_helper.py:228-238
ner-prosatoken_classificationNerProsaDatasetNerDataLoaderforward_word_classificationner_metrics_fn./dataset/nerp_ner-prosa/ utils/args_helper.py:246-256
pos-prosatoken_classificationPosTagProsaDatasetPosTagDataLoaderforward_word_classificationpos_tag_metrics_fn./dataset/posp_pos-prosa/ utils/args_helper.py:264-274
absa-prosamulti_label_classificationAspectBasedSentimentAnalysisProsaDatasetAspectBasedSentimentAnalysisDataLoaderforward_sequence_multi_classificationabsa_metrics_fn./dataset/casa_absa-prosa/ utils/args_helper.py:282-292

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-101). Perbedaan terakhir di tingkat dataset adalah tokenizer kata: hanya keyword-extraction-prosa yang memakai WordSplitTokenizer (utils/args_helper.py:226-227), sedangkan cabang lain memakai TweetTokenizer (utils/args_helper.py:137).

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-301).

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-182). --valid_batch_size dipakai untuk loader validasi sekaligus loader test (main.py:176-182). forward_fn, metrics_fn, dan valid_criterion diteruskan ke train(...) (main.py:185). 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-297).

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.
Fig. 2: Pemilihan arsitektur di load_modelEnam 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_checkpointTokenizerConfigKelas model menurut args['task']
bert-base-multilingualBertTokenizer.from_pretrained(args['model_checkpoint'])BertConfig dari checkpoint yang samaBertForSequenceClassification, BertForWordClassification, BertForMultiLabelClassification utils/functions.py:300-305
xlm-mlmXLMTokenizer utils/functions.py:306-316XLMConfigXLMForSequenceClassification, XLMForWordClassification, XLMForMultiLabelClassification utils/functions.py:319-324
xlm-robertaXLMRobertaTokenizer utils/functions.py:325-335XLMRobertaConfigXLMRobertaForSequenceClassification, XLMRobertaForWordClassification, XLMRobertaForMultiLabelClassification utils/functions.py:338-343
fasttextSimpleTokenizer(vocab_map, word_tokenizer, lower=args['lower'])BertConfig.from_pretrained('bert-base-uncased') lalu hidden_size 300 dan num_attention_heads 10BertFor* diinstansiasi dari config, lalu bobot word_embeddings diisi gen_embeddings utils/functions.py:344-354
scratchBertTokenizer.from_pretrained('bert-base-uncased')BertConfig.from_pretrained('bert-base-uncased') dengan hidden_size 300 dan num_attention_heads 10BertFor* dari config tanpa checkpoint utils/functions.py:380-392
indobenchmarkBertTokenizer.from_pretrained(args['model_checkpoint'])BertConfig dari checkpoint yang samaAlbertFor* bila string memuat lite, selain itu BertFor* utils/functions.py:400-410

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-297).

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-354). 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-367). Bobot embedding diisi dari matriks hasil gen_embeddings (utils/functions.py:369-378).

⚠️ Cabang fasttext mengambil vektor lewat args['embedding_path'][args['model_checkpoint']], sehingga nama checkpoint wajib menjadi kunci dict tersebut (utils/functions.py:344-354). Contohnya cabang emotion-twitter hanya mendaftarkan kunci fasttext-cc-id-300-no-oov-uncased dan fasttext-4B-id-300-no-oov-uncased (utils/args_helper.py:96-99). Nama lain yang tetap memuat string fasttext akan berhenti dengan KeyError sebelum model dibentuk.

⚠️ load_model tidak punya else terakhir. Checkpoint yang tidak memuat satu pun penanda di atas membuat model dan tokenizer belum terikat ketika return model, tokenizer, vocab_path, config_path dijalankan (utils/functions.py:421).

Nilai balik keempat dipakai pemanggilnya: vocab_path dan config_path disalin ke direktori eksperimen hanya bila tidak None (main.py:188-191). 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 skripCabang load_model
scratch run_single_task.sh:2scratch, config dari bert-base-uncased
fasttext-cc-id-300-no-oov-uncased run_single_task.sh:7fasttext, embedding dari embedding_path
bert-base-multilingual-uncased run_single_task.sh:17bert-base-multilingual
xlm-roberta-base run_single_task.sh:20xlm-roberta
xlm-mlm-100-1280 run_single_task.sh:24xlm-mlm
indobenchmark/indobert-lite-base-p1 run_single_task.sh:39indobenchmark 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-80). 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-69). 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-234).

JalurNama argumenFungsi pemilih
training di main.py--model_checkpointload_model (utils/functions.py:286-297)
evaluasi di predict.py--model_typeload_eval_model (utils/functions.py:222-234)

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.