如何用韩语语料继续预训练Google多语言BERT以优化文本向量?
嘿,我刚好有过类似的实践经验,给你梳理下在TensorFlow里实现BERT继续预训练(也就是你说的“追加训练”)的具体方案,完全符合你只更新BERT本身、后续直接提取固定向量的需求:
核心思路:继续预训练(而非任务微调)
你要的这种训练方式本质是BERT的继续预训练——和针对分类/回归等任务的微调不同,我们复用BERT预训练时的核心任务(掩码语言模型MLM),在韩语文料上让模型学习更贴合韩语的语义表示,训练完成后得到的就是可以直接用来提取特征的“韩语增强版”BERT,不需要附加任何任务头。
具体实现步骤(TensorFlow)
1. 准备工作
- 下载TensorFlow版的多语言BERT权重:比如
bert-base-multilingual-cased(可以通过TensorFlow Hub或者官方BERT代码库获取) - 预处理韩语文料:把你的语料整理成每行一句的纯文本格式,确保文本干净无噪声;如果是长文本,可以拆分到合适的长度(BERT最大输入长度通常是512 tokens)
2. 构建MLM训练任务
MLM是BERT预训练的核心任务,也是继续预训练的最优选择,具体逻辑是:随机掩码文本中15%的token,让模型预测这些被掩码的token。
这里可以用TensorFlow Text或者官方BERT的预处理工具来生成训练数据:
import tensorflow as tf import tensorflow_text as text from tensorflow_hub import KerasLayer # 加载预训练BERT的预处理模型 preprocessor = KerasLayer("https://tfhub.dev/tensorflow/bert_multi_cased_preprocess/3") # 加载预训练BERT编码器 bert_encoder = KerasLayer("https://tfhub.dev/tensorflow/bert_multi_cased_L-12_H-768_A-12/4", trainable=True) # 定义MLM数据生成函数 def create_mlm_dataset(texts, batch_size=32): # 先做基础预处理 preprocessed = preprocessor(texts) input_ids = preprocessed["input_ids"] attention_mask = preprocessed["attention_mask"] # 生成MLM掩码和标签 masked_input_ids, masked_lm_labels = text.mask_language_model( input_ids, mask_token_id=preprocessor.resolved_object.vocab_table.lookup(tf.constant("[MASK]")), masking_probability=0.15, mask_selection_rate=0.8, # 80%替换成[MASK] random_selection_rate=0.1, # 10%替换成随机token keep_selection_rate=0.1 # 10%保留原token ) dataset = tf.data.Dataset.from_tensor_slices({ "input_ids": masked_input_ids, "attention_mask": attention_mask, "masked_lm_labels": masked_lm_labels }) return dataset.shuffle(10000).batch(batch_size).prefetch(tf.data.AUTOTUNE)
3. 定义训练模型
我们只需要训练BERT编码器本身,不需要附加任务头:
# 构建MLM训练模型 inputs = { "input_ids": tf.keras.Input(shape=(None,), dtype=tf.int32), "attention_mask": tf.keras.Input(shape=(None,), dtype=tf.int32) } # 获取BERT的输出 encoder_outputs = bert_encoder(inputs) sequence_output = encoder_outputs["sequence_output"] # (batch_size, seq_len, hidden_size) # 构建MLM预测头(和预训练时一致) mlm_dense = tf.keras.layers.Dense(bert_encoder.resolved_object.config["hidden_size"], activation="gelu") mlm_layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-12) mlm_output = tf.keras.layers.Dense(bert_encoder.resolved_object.config["vocab_size"])(mlm_layer_norm(mlm_dense(sequence_output))) model = tf.keras.Model(inputs=inputs, outputs=mlm_output) # 定义损失函数和优化器 loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction="none") def mlm_loss(labels, logits): # 只计算被掩码位置的损失 mask = tf.cast(tf.not_equal(labels, -100), tf.float32) loss = loss_fn(labels, logits) * mask return tf.reduce_sum(loss) / tf.reduce_sum(mask) model.compile( optimizer=tf.keras.optimizers.AdamW(learning_rate=2e-5), loss=mlm_loss )
4. 开始训练
把你的韩语文料转换成数据集后,就可以启动训练了:
# 假设你的韩语文料存在ko_corpus.txt文件中,每行一句 with open("ko_corpus.txt", "r", encoding="utf-8") as f: texts = [line.strip() for line in f if line.strip()] train_dataset = create_mlm_dataset(texts) model.fit(train_dataset, epochs=3) # 保存训练后的BERT编码器(注意要单独保存编码器部分,方便后续提取特征) tf.saved_model.save(bert_encoder, "./fine_tuned_bert_ko")
5. 提取文本向量
训练完成后,你可以加载保存的编码器,直接提取特征:
# 加载训练后的BERT编码器 loaded_bert = tf.saved_model.load("./fine_tuned_bert_ko") # 定义特征提取函数 def get_features(texts): preprocessed = preprocessor(texts) outputs = loaded_bert(preprocessed) # 可选:用[CLS] token的向量作为句子表示,或者取整个序列的均值 pooled_output = outputs["pooled_output"] # (batch_size, 768) sequence_output = outputs["sequence_output"] # (batch_size, seq_len, 768) return pooled_output # 这里返回句子级向量,你可以根据需求选择 # 测试 sample_texts = ["안녕하세요, 반갑습니다!", "TensorFlow로 BERT를 계속 학습하는 방법"] features = get_features(sample_texts) print(features.shape) # (2, 768)
关键注意事项
- 学习率设置:继续预训练的学习率要远低于任务微调,推荐用
2e-5到5e-5,避免破坏BERT原有的通用语义表示 - 语料规模:尽量用足够大的韩语文料(百万级以上),否则容易过拟合,反而降低模型通用性
- 掩码策略:严格遵循BERT预训练的掩码比例(15%)和替换规则,保证训练任务的一致性
内容的提问来源于stack exchange,提问作者Alena
相关产品推荐
相关产品推荐

