在 SageMaker AI 上为形态丰富语言训练专属大模型——阿塞拜疆语实践

2026-05-29 33 预计阅读时间:1 分钟
来源:aws.amazon.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:12 分钟

阿塞拜疆语属于突厥语族,一个词通过后缀叠加可以表达英语整句话的含义——名词有 18 种格变,动词时态与人称通过层层黏着完成。这种"形态丰富"(morphologically rich)的语言对大模型来说意味着两件事:词表膨胀极快,训练数据却极其稀缺。Azercell 作为阿塞拜疆最大电信运营商,需要在六周内从零搭建一套生产级训练框架,把通用基础模型改造成能理解本地电信场景的阿塞拜疆语 LLM,用于内部业务和面向客户的聊天机器人。他们与 AWS Generative AI Innovation Center 合作,在 Amazon SageMaker AI 上完成了这条没有现成蓝图的路。

形态丰富语言的三重挤压

阿塞拜疆语不是"少几个词"的问题,而是结构性差异:

  1. 词表爆炸——英语 go 加后缀产生 goes / going / gone,阿塞拜疆语一个动词根可派生出几十种形态。如果照搬英语 LLM 的词表策略,token 覆盖率会急剧下降,大量词被拆成无意义子串。
  2. 数据稀缺——高质量阿塞拜疆语语料在公开数据集中占比极低。Common Crawl 里阿塞拜疆语页面不足 0.1%,且噪声严重。
  3. 无先例可循——英语、中文、德语都有成熟的预训练与微调路径,阿塞拜疆语几乎没有公开的基座模型或训练 recipe,每一步都需要验证。

Azercell 的做法是:不从头预训练,而是选取已有基础模型(Foundation Model),通过词表扩展 + 领域微调两条主线,把模型"嫁接"到阿塞拜疆语电信场景。

SageMaker AI 上的训练框架设计

六周时间要跑通从数据清洗到模型部署的全流程,关键在于把每一步都变成可复现的 pipeline,而不是手动 ad-hoc 操作。SageMaker AI 提供了几个核心能力来支撑这个框架:

  • 托管训练集群:按需拉起 GPU 实例(如 ml.p4d.24xlarge),训练完自动释放,不用维护常驻集群。
  • Processing Job:数据清洗、词频统计、词表构建等预处理步骤作为独立 job 运行,输入输出都走 S3,可审计可回溯。
  • HyperParameter Tuning:形态丰富语言的微调超参没有文献参考,需要系统搜索。SageMaker 的 HPO 可以并行跑多组实验,自动收敛到较优配置。
  • Model Registry + Endpoint:训练产出的模型直接注册,一键部署为推理端点,衔接聊天机器人场景。

整个流程被组织为:数据准备 → 词表扩展 → 继续预训练(CPT)→ 领域微调(SFT)→ 评估 → 部署,每一步对应一个或多个 SageMaker job,通过 Step Functions 或 Python SDK 串联。

实操:词表扩展与微调训练 Job

下面给出一个可以在 SageMaker AI 上直接运行的训练配置示例。场景是:对已有基座模型做词表扩展后,用阿塞拜疆语电信语料进行监督微调(SFT)。假设你已经把词表扩展后的模型权重上传到了 S3。

1. 准备训练脚本(train_sft.py)

将以下脚本打包为 sft_code.tar.gz,上传到 S3:

# train_sft.py — 阿塞拜疆语电信场景 SFT 训练入口
import argparse
import json
import os

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from trl import SFTTrainer
from datasets import load_dataset

def main():
    parser = argparse.ArgumentParser()
    # SageMaker 会把超参以 JSON 传入 /opt/ml/input/config/hyperparameters.json
    parser.add_argument("--model_dir", type=str, default="/opt/ml/input/data/model")
    parser.add_argument("--train_file", type=str, default="/opt/ml/input/data/train/sft_telecom_az.jsonl")
    parser.add_argument("--epochs", type=int, default=3)
    parser.add_argument("--lr", type=float, default=2e-5)
    parser.add_argument("--batch_size", type=int, default=8)
    parser.add_argument("--max_seq_length", type=int, default=2048)
    parser.add_argument("--output_dir", type=str, default="/opt/ml/model")
    args = parser.parse_args()

    tokenizer = AutoTokenizer.from_pretrained(args.model_dir)
    model = AutoModelForCausalLM.from_pretrained(
        args.model_dir,
        torch_dtype=torch.bfloat16,
        device_map="auto",
    )

    # 加载阿塞拜疆语电信 SFT 数据(JSONL 格式:{"prompt":..., "response":...})
    dataset = load_dataset("json", data_files=args.train_file, split="train")

    def format_example(example):
        return f"<s>[INST] {example['prompt']} [/INST] {example['response']}</s>"

    training_args = TrainingArguments(
        output_dir=args.output_dir,
        num_train_epochs=args.epochs,
        per_device_train_batch_size=args.batch_size,
        learning_rate=args.lr,
        bf16=True,
        gradient_checkpointing=True,
        logging_steps=50,
        save_strategy="epoch",
        remove_unused_columns=False,
    )

    trainer = SFTTrainer(
        model=model,
        tokenizer=tokenizer,
        args=training_args,
        train_dataset=dataset,
        formatting_func=format_example,
        max_seq_length=args.max_seq_length,
    )

    trainer.train()
    # SageMaker 要求最终模型写到 /opt/ml/model,会自动打包上传到 S3
    trainer.save_model(args.output_dir)
    tokenizer.save_pretrained(args.output_dir)

if __name__ == "__main__":
    main()

2. 启动 SageMaker Training Job

import sagemaker
from sagemaker.pytorch import PyTorch

sagemaker_session = sagemaker.Session()
role = "arn:aws:iam::YOUR_ACCOUNT_ID:role/SageMakerExecutionRole"

# 训练代码包与数据在 S3 上的位置
code_uri = "s3://az-llm-bucket/code/sft_code.tar.gz"
model_uri = "s3://az-llm-bucket/models/az-llm-extended-vocab/"   # 词表扩展后的基座模型
train_uri = "s3://az-llm-bucket/data/sft_telecom_az.jsonl"        # 阿塞拜疆语电信 SFT 数据

estimator = PyTorch(
    entry_point="train_sft.py",
    source_dir=code_uri,          # 也可以用本地目录,SDK 会自动上传
    role=role,
    instance_type="ml.p4d.24xlarge",   # 8× A100 40GB,适合 7B-13B 模型微调
    instance_count=1,
    framework_version="2.1",
    py_version="py310",
    hyperparameters={
        "epochs": 3,
        "lr": 2e-5,
        "batch_size": 8,
        "max_seq_length": 2048,
    },
    # 把模型权重和数据作为 channel 传入,SageMaker 会下载到 /opt/ml/input/data/ 下对应子目录
    channels={
        "model": sagemaker.inputs.TrainingInput(s3_data=model_uri, input_mode="File"),
        "train": sagemaker.inputs.TrainingInput(s3_data=train_uri, input_mode="File"),
    },
    output_path="s3://az-llm-bucket/output/",
    sagemaker_session=sagemaker_session,
)

estimator.fit()
print(f"Training job: {estimator.latest_training_job.name}")
print(f"Model artifact: {estimator.model_data}")

运行前需要替换 YOUR_ACCOUNT_ID 和 S3 路径为你的实际值。ml.p4d.24xlarge 在部分区域可能需要申请容量配额;如果资源受限,可先用 ml.g5.12xlarge(4× A10G)做小规模验证。

3. SFT 数据格式参考

{"prompt": "Azercell的5G套餐有哪些选择?", "response": "Azercell目前提供三种5G套餐:Basic(每月29 AZN,含10GB流量)、Standard(49 AZN,含30GB流量+无限通话)、Premium(79 AZN,含无限流量+国际漫游100分钟。所有套餐均支持5G NSA接入,覆盖巴库主要城区。"}
{"prompt": "如何查询我的号码余额?", "response": "您可以通过以下方式查询余额:1. 发送短信BAL到7777;2. 登录Azercell自助服务App;3. 拨打*111#USSD代码。查询结果会显示主账户余额及当前套餐剩余流量。"}

数据质量是形态丰富语言微调的生命线——每条样本都要用母语人员审核,避免翻译腔和语法错误被模型学到。

词表扩展的取舍

词表扩展本身是一个容易被忽视但影响深远的步骤。常见做法是:

  1. 从阿塞拜疆语语料中统计高频子词(用 SentencePiece 或 HuggingFace tokenizer 的 train_new_from_iterator)。
  2. 将新 token 加入模型词表,对应的 embedding 行用已有 token 的均值初始化。
  3. 先用纯语言语料做继续预训练(CPT),让新 embedding 适应上下文,再进入 SFT。

风险在于:扩展比例过大会导致原有语言能力退化,扩展过小则阿塞拜疆语仍然被过度拆分。Azercell 的经验是控制在原词表 5%-10% 的增量,并在 CPT 阶段混入少量英语数据作为"锚点",防止模型在单语训练中遗忘通用能力。

部署与落地建议

训练完成后,模型通过 SageMaker Model Registry 注册,部署为实时推理端点:

from sagemaker.model_monitor import ModelRegistry

# 注册模型
model_package_group_name = "az-llm-telecom"
# ... 通过 estimator.model_data 创建 ModelPackage ...

# 部署为端点
predictor = estimator.deploy(
    initial_instance_count=1,
    instance_type="ml.g5.xlarge",  # 推理用单卡 A10G 即可
    endpoint_name="az-llm-telecom-endpoint",
)

聊天机器人服务调用该端点,将用户问题拼接为 <s>[INST] ... [/INST] 格式后发送请求,拿到模型生成的阿塞拜疆语回复。

落地检查清单

项目 要点
词表扩展比例 控制在 5%-10%,过大需回退测试
CPT 数据配比 阿塞拜疆语为主,混入 5%-10% 英语作为能力锚点
SFT 数据审核 必须由母语人员逐条检查,不接受机器翻译
评估指标 除通用 benchmark 外,增加电信场景专项测试集(套餐查询、故障报修、账单解释)
推理延迟 阿塞拜疆语 token 数比英语多 20%-40%,需预留额外推理时间
成本控制 训练用 p4d 按需拉起,推理用 g5 持续部署;非高峰可考虑异步端点降本

形态丰富语言的 LLM 训练没有捷径,但 Azercell 的实践说明:在 SageMaker AI 上把数据准备、词表扩展、多阶段训练、HPO 搜索、模型部署都变成可复现的 pipeline,六周可以从零走到生产级。这套框架不只适用于阿塞拜疆语——任何面临"数据少、形态复杂、无先例"的语言,都可以按同样的骨架去搭建自己的训练路径。


相关推荐