Transformers documentation

Dinamik ağırlık yükleme

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Dinamik ağırlık yükleme

Checkpoint'ler genellikle, bir modelin çalışma zamanında beklediğiyle eşleşmeyen bir formatta serileştirilir. Yaygın senaryolar şunları içerir:

  1. Birleştirilmiş ağırlıklar: Kontrol noktaları ayrı gate_proj ve up_proj ağırlıklarını saklar, ancak model verimlilik için birleştirilmiş bir gate_up_proj kullanır.
  2. MoE uzman birleştirme: Bireysel uzman ağırlıkları (experts.0.weight, experts.1.weight, …) tek bir 3B tensöre yığılmalıdır.
  3. Eski adlandırma: Eski denetim noktaları farklı adlandırma kuralları kullanır (ör. LayerNorm.gamma ve LayerNorm.weight).
  4. Bileşik modeller: Bir görme-dil modeli, her biri kendi checkpoint sözleşmesine sahip iki PreTrainedModel alt modülü içerir.
  5. Kantizasyon: Ağırlıklar, serileştirme kaldırma gerektiren kantize formatlarda saklanabilir.

Dinamik ağırlık yükleme, checkpoint tensörleri yüklenirken bunlara zamanlanmış ve geri alınabilir işlemler uygulayarak bu sorunu ele alır. Transformers, bu özelliği WeightConverter ve WeightRenaming sınıfları aracılığıyla sunar; bu sınıflar, bir veya birden fazla checkpoint anahtarının bir veya birden fazla model parametresine nasıl eşlendiğini ve eşleşen tensörler üzerinde çalıştırılması gereken birleştirilebilir ConversionOps işlemlerini tanımlar. Bu yaklaşım, yeni ağırlık düzenlerine uyum sağlar, kuantize edilmiş uzman karışımlarını (MoE) destekler ve tensör paralelliğiyle entegre çalışır.

Bu kılavuz, tensörleri dönüştürmek için WeightConverter sınıfının nasıl kullanılacağını gösterir. Dönüşüm eşlemeleri conversion_mapping.py dosyasında yer alır; kayıtlı bir eşleme, bir model_type dizesiyle (ör. "mixtral") veya bir sınıf adıyla (ör. "LlavaModel") anahtarlanır.

Tam yükleme hattı

Tüm modeller dinamik ağırlık yükleme sisteminden geçer. Dönüşüm eşlemesi, yalnızca modelin sınıf adı veya model_type için kayıtlı girdileri varsa etkinleşen, bu sistem içindeki isteğe bağlı bir adımdır.

Checkpoint File → from_pretrained() → convert_and_load_state_dict_in_model()
                                              ↓
                         ┌───────────────────────────────────────────────────────────┐
                         │  For each weight in checkpoint:                           │
                         │  1. Match renamed/processed source key to model parameter │
                         │  2. Shard the weight and send to device (async)           │
                         │  3. Collect tensors with the same source_pattern together │
                         │     (e.g. MoE experts, gate_up_proj)                      │
                         │  4. Apply dequantization/deserialization (if pre-quant)   │
                         │  5. Apply conversion (if defined)                         │
                         │  6. Apply quantization (if enabled and step 4 not used)   │
                         │  7. Set parameter on model                                │
                         └───────────────────────────────────────────────────────────┘
AdımAktif olduğunda
Dinamik yüklemeHer zaman, tüm modeller için
Dönüşüm eşlemesiSadece modelin sınıfı veya model_type değeri _MODEL_TO_CONVERSION_PATTERN içinde kayıtlıysa
TP bölmeYalnızca DistributedConfig(tp_size=N) kullanıldığında ve modelin base_model_tp_plan içerdiği durumlarda
Dequantization/deserializationYalnızca önceden kantize edilmiş bir kontrol noktası yüklenirken
KantizasyonYalnızca bir kuantizasyon yapılandırması sağlandığında ve ağırlıklar önceden kuantize edilmemişse

Yoğun modeller (ör. Llama)

Çoğu yoğun model için kontrol noktası biçimi, model biçimiyle doğrudan eşleşir; bu nedenle dönüştürme eşlemesi gerekmez. Bazı modellerde yeniden adlandırma gerekebilir (ör. eski adlandırma kuralları). Etkinleştirildiğinde TP parçalaması hâlâ uygulanır.

Checkpoint:                             Model:
model.layers.0.self_attn.q_proj.weight  →  model.layers.0.self_attn.q_proj.weight
model.layers.0.self_attn.k_proj.weight  →  model.layers.0.self_attn.k_proj.weight
model.layers.0.mlp.gate_proj.weight     →  model.layers.0.mlp.gate_proj.weight
model.layers.0.mlp.up_proj.weight       →  model.layers.0.mlp.up_proj.weight
model.layers.0.mlp.down_proj.weight     →  model.layers.0.mlp.down_proj.weight

Eski kontrol noktaları, tüm modellere uygulanan yerleşik yeniden adlandırmalarla ele alınan eski adlandırma kurallarını kullanabilir:

Checkpoint:                          Model:
LayerNorm.gamma              →       LayerNorm.weight
LayerNorm.beta               →       LayerNorm.bias

MoE modelleri (ör. Mixtral)

MoE modelleri için checkpoint biçimi, model biçiminden farklıdır. Dönüşüm eşlemesi, ayrı uzman ağırlıklarını füzyonlu 3D tensörlere dönüştürür ve TP parçalama, dönüşüm uygulandıktan sonra yapılır.

Checkpoint:                              Model:
experts.0.w1.weight  ─┐
experts.1.w1.weight   │ MergeModulelist
...                   ├───────────────→  experts.gate_up_proj (8, hidden, 2*intermediate)
experts.0.w3.weight   │ + Concatenate
experts.1.w3.weight  ─┘

Bileşik modeller (ör. görme-dil)

PreTrainedModel, başka PreTrainedModel alt modülleri içerebilir. Her alt model, sınıf adına veya model_type'ine karşı kaydedilmiş kendi dönüşüm eşlemesine sahip olabilir. Ana model yüklendiğinde get_model_conversion_mapping, alt modelleri derinlik öncelikli sırada gezerek eşlemelerini toplar ve her dönüştürmeyi scope_prefix aracılığıyla ilgili alt modülün yoluna otomatik olarak daraltır.

Composite model:                              Per-submodel mappings (auto-scoped):
LlavaForConditionalGeneration
├── vision_model: SiglipVisionModel    →     SiglipVisionModel mapping (scope="vision_model")
└── language_model: LlamaForCausalLM   →     LlamaForCausalLM mapping  (scope="language_model")

scope_prefix, alt modülün noktalı yoludur ("vision_model", "language_model.model" vb.). Kapsam sınırlı bir dönüştürme, yalnızca f"{scope_prefix}." ile başlayan anahtarlar için tetiklenir; ön ek, desen eşleştirme öncesinde kaldırılır ve yer değiştirme sonrasında yeniden eklenir, böylece her alt modelin eşlemesi alt modele göre, sanki kök modül o alt modelmiş gibi yazılır.

Mimari

Sistem, core_model_loading.py içinde tanımlanan birkaç temel bileşen etrafında inşa edilmiştir:

Aşama 1 — Anahtar başına işleme (kontrol noktası anahtarları üzerinde döngü yapar):

  1. Transform listesini bir kez dolaşın. Eşleşen her WeightRenaming tetiklenir (ör. block_sparse_moe → mlp) ve en fazla bir WeightConverter anahtarı alabilir (ör. experts.*.w1.weight).
  2. Shard (TP) ve cihaza gönder işlemini ThreadPoolExecutor üzerinden asenkron olarak gerçekleştirin.
  3. Aynı source_pattern'a sahip Collect tensörlerini bir araya getirin (ör. tüm MoE uzman ağırlıkları, gate + up projeksiyonları).

2. Aşama — Haritalama başına işleme (toplanan haritalamalar üzerinde döner):

  1. Dequantize/deserialize (yalnızca önceden kuantize edilmiş checkpoint'ler için).
  2. ConversionOps zincirini uygula: Chunk, Concatenate, MergeModulelist, Transpose vb.
  3. Quantize işlemini anlık olarak (önceden quantize edilmemişse) gerçekleştirin.
  4. Modelde parametreyi ayarla.

WeightTransform

Desen eşleştirme ve tensör toplama işlemlerini yöneten temel sınıf:

  • Desen derleme: Kaynak desenler, re.search() ile eşleştirilen tam düzenli ifadelerdir. * jokeri, herhangi bir dizinlenebilir bileşeni eşleştirir ve tüm eşleşmeleri toplu işlemler için bir araya getirir.
  • Yakalama grupları ve geri referanslar: Kaynak desenlerindeki yakalama grupları, yeniden adlandırma sırasında alt dizeleri (ör. katman indeksleri) korumak için hedef desenlerde \1, \2, … olarak referans alınabilir.
  • Kapsam: scope_prefix (get_model_conversion_mapping tarafından alt modeller için otomatik olarak ayarlanır) dönüştürmeyi, o yol altındaki anahtarlara sınırlar. Eşleştirme öncesinde önek kaldırılır ve yer değiştirme sonrasında yeniden eklenir.
  • Anahtar yeniden adlandırma: rename_source_key(), regex'i (kapsam işleme ile birlikte) uygular ve yükleyicinin anahtarı hangi dönüştürücünün (varsa) talep ettiğini bilmesi için (renamed_key, source_pattern) döndürür.
  • Tensor toplama: add_tensor(), çözümlenmiş tensörleri (veya Future nesnelerini) source_pattern altında biriktirir; böylece tek bir dönüştürme işlemi için (ör. tüm MoE uzman ağırlıkları) gereken tüm tensörler, işlem zinciri çalıştırılmadan önce birlikte gruplanır.
  • Tersinirlik: reverse_transform() kaynak ↔ hedef desenlerini değiştirir ve her işlemi tersine çevirir; böylece aynı listenin tersi, kaydetme işlemini yönlendirir.
  • İzleme: was_used(), yükleme sırasında dönüştürmenin herhangi bir anahtarla eşleşip eşleşmediğini bildirir; bu, çift yönlü olmayan yeniden adlandırmaların (ör. zaten mevcut olabilecek bir önek ekleyen PrefixChange) kaydetme sırasında simetrik olarak yeniden uygulanabilmesi için gereklidir.

WeightRenaming

WeightRenaming, tensör işlemleri içermeyen saf anahtar yeniden adlandırmaları için özel bir WeightTransform'dır. WeightConverter'ın aksine, bir WeightRenaming anahtarı claim etmez; bu nedenle birden çok yeniden adlandırma serbestçe zincirlenebilir. Yükleme yolunda tüm yeniden adlandırmalar dönüştürücüden önce çalışır; kaydetme yolunda (ters çevrilmiş liste) ise tüm ters çevrilmiş yeniden adlandırmalar ters çevrilmiş dönüştürücüden sonra çalışır — yukarıdaki sıralama kuralına bakınız.

# Legacy checkpoint compatibility
WeightRenaming("LayerNorm.gamma", "LayerNorm.weight")

# Module path changes
WeightRenaming(".block_sparse_moe.", ".mlp.")

PrefixChange, bir yol bileşeninin tamamını kaldırma veya ekleme gibi yaygın durumlar için WeightRenaming sarmalayıcısının üstünde daha yüksek seviyeli bir sarmalayıcıdır. İsteğe bağlı model_prefix parametresi, işlemi bu ad alanı altındaki anahtarlara daraltır:

# "model.layers.bad_prefix.weight" → "model.layers.weight"
PrefixChange(prefix_to_remove="bad_prefix", model_prefix="model.layers")
# "layers.0.weight" → "model.layers.0.weight"
PrefixChange(prefix_to_add="model")

WeightConverter

WeightConverter, toplanan tensörler üzerinde çalışan bir ConversionOps zinciriyle WeightTransform sınıfını genişletir. Desteklenen dört kardinalite şunlardır:

KardinaliteKaynak desenleriHedef desenlerTipik çalışma
bir-bir11Transpose, PermuteForRope
bir-çok1>1Parça (ör. qkv_proj paketini aç)
çoktan bire>11Concatenate, MergeModulelist (ör. uzmanları birleştir)
çoktan çoğa>1>1yalnızca bunu açıkça destekleyen işlemlerle (ör. ErnieFuseAndSplitTextVisionExperts)
WeightConverter(
    source_patterns=[".experts.*.w1.weight", ".experts.*.w3.weight"],
    target_patterns=".experts.gate_up_proj",
    operations=[MergeModulelist(dim=0), Concatenate(dim=1)],
)

WeightConverter ayrıca geri dönüşümlüdür: reverse_transform() kaynak ↔ hedefi yer değiştirir ve her işlemi reverse_op ile değiştirir; bu sayede kayıtlı bir dönüşüm eşlemesi yapısal olarak çift yönlüdür (yükleme işlemi listeyi olduğu gibi kullanırken, kaydetme işlemi onu tersine çevirir).

Yeniden adlandırmaların ve dönüştürücülerin sıralanması

WeightRenaming girdilerini WeightConverter girdilerinden önce listeleyin ve yapraklarını ayrık tutun: yeniden adlandırmalar, dönüştürücülerin kullandığı anahtarları normalleştirir ancak asla bir dönüştürücünün ürettiği bir yaprağı hedef almaz. Kaydetme yolu, eşlemeyi iki aşamada (önce dönüştürücülerin, ardından yeniden adlandırmaların tersi) tersine çevirmek için buna dayanır.

Dönüşüm listesi, her kontrol noktası anahtarı için bir kez, sırayla işlenir. Her anahtar için:

  • Eşleşen her WeightRenaming tetiklenir; birden çok yeniden adlandırma zincirlenebilir.
  • Anahtarı iddia eden ilk WeightConverter. Sonraki dönüştürücüler atlanır — bu, tensörün birleştirme/bölme adımı için tek bir dönüştürücüye yönlendirilmesini garanti eder ve niyetleri örtüşen iki dönüştürücünün bir yapılandırma hatası olmasının nedenidir.
weight_mapping = [
    WeightRenaming("^old_prefix", "encoder"),              # rename runs always
    WeightConverter(                                       # converter claims the key
        "attn.qkv_proj.weight",
        ["attn.q_proj.weight", "attn.k_proj.weight", "attn.v_proj.weight"],
        operations=[Chunk(dim=0)],
    ),
]
# Load:  "old_prefix.attn.qkv_proj.weight"
#   → WeightRenaming  → "encoder.attn.qkv_proj.weight"
#   → WeightConverter → "encoder.attn.{q,k,v}_proj.weight"
#
# Save: list reversed, each transform inverted:
#   → rev(WeightConverter) repacks QKV → "encoder.attn.qkv_proj.weight"
#   → rev(WeightRenaming)  fixes prefix → "old_prefix.attn.qkv_proj.weight"

Dönüşüm işlemleri

WeightConverter sınıfı, from_pretrained() çağrıldığında checkpoint kaynak tensörlerini model hedef tensörlerine dönüştürmek için yürütülen birkaç işleme sahiptir.

Operasyonlar tamamen geri alınabilir. Kaydetme işlemi dönüşümleri geri alır ve orijinal checkpoint'i döndürür, böylece farklı framework'ler arasında kolayca çalışabilirsiniz.

İşlemTersine çevir
Chunk(dim)Concatenate(dim)
Concatenate(dim)Chunk(dim)
MergeModulelist(dim)SplitModulelist(dim)
SplitModulelist(dim)MergeModulelist(dim)
Transpose(d0, d1)Transpose(d1, d0)
PermuteForRope()PermuteForRope()
Conv3dToLinear(...)LinearToConv3d(...)

Parça

Chunk işlemi, bir tensörü bir boyut boyunca eşit parçalara böler. Örneğin, bir modelin Q, K ve V'yi tek bir tensör yerine üç ayrı tensör olarak beklediği durumlarda.

WeightConverter(
    "self_attn.qkv_proj",
    ["self_attn.q_proj", "self_attn.k_proj", "self_attn.v_proj"],
    operations=[Chunk(dim=0)],
)

Birleştir

Concatenate işlemi, ayrı tensörleri tek bir tensörde birleştirir. Örneğin, bir modelin Q, K ve V'yi ayrı tensörler yerine tek bir tensör olarak beklediği durumlarda.

WeightConverter(
    ["self_attn.q_proj", "self_attn.k_proj", "self_attn.v_proj"],
    "self_attn.qkv_proj",
    operations=[Concatenate(dim=0)],
)

MergeModulelist

MergeModulelist, bir 2D tensör listesini tek bir 3D tensöre birleştirir. Örneğin, MoE'deki uzmanları yığmak ve bunları tek bir tensöre paketlemek için MergeModulelist'i Concatenate ile birleştirebilirsiniz.

WeightConverter(
    ["block_sparse_moe.experts.*.w1.weight", "block_sparse_moe.experts.*.w3.weight"],
    "mlp.experts.gate_up_proj",
    operations=[MergeModulelist(dim=0), Concatenate(dim=1)],
)

SplitModulelist

SplitModulelist, 3B bir tensörü 2B tensörlerden oluşan bir listeye geri böler. Örneğin, bir uzman yığınısını tek tek uzmanlara geri bölebilirsiniz.

WeightConverter(
    "mlp.experts.down_proj",
    "block_sparse_moe.experts.*.w2.weight",
    operations=[SplitModulelist(dim=0)],
)

PermuteForRope

PermuteForRope, ağırlıkları iç içe geçmiş formattan sin/cos formatına dönüştürür. Örneğin, Chunk ile PermuteForRope bileşkesini oluşturarak birleşik bir QKV tensörünü bölebilir ve Q ile K için sin/cos RoPE permütasyonunu uygulayabilirsiniz.

WeightConverter(
    ["model.layers.*.self_attn.qkv_proj.weight"],
    [
        "model.layers.*.self_attn.q_proj.weight",
        "model.layers.*.self_attn.k_proj.weight",
        "model.layers.*.self_attn.v_proj.weight",
    ],
    operations=[Chunk(dim=0), PermuteForRope()],
)

Değiştir

Transpose, bir tensörün boyutlarını değiştirir. Farklı konvansiyonlar arasında ağırlık yerleşimlerini dönüştürmek için kullanışlıdır.

WeightConverter(
    source_patterns="mlp.gate.weight",
    target_patterns="mlp.text_moe.gate.weight",
    operations=[Transpose(dim0=0, dim1=1)],
)

Operasyon zincirleme

Operasyonlar, karmaşık dönüşümleri gerçekleştirmek için zincirlenebilir. Operasyonlar sırayla çalışır ve her operasyonun çıktısı, bir sonraki operasyonun girdisi olur.

Örnek: Mixtral MoE dönüştürme

WeightConverter(
    source_patterns=[
        ".experts.*.w1.weight",  # gate_proj per expert
        ".experts.*.w3.weight",  # up_proj per expert
    ],
    target_patterns=".experts.gate_up_proj",
    operations=[
        MergeModulelist(dim=0),  # Stack all experts: (n_experts, in, out)
        Concatenate(dim=1),      # Fuse gate+up: (n_experts, in, 2*out)
    ],
)

Veri akışı:

Input:
  ".experts.*.w1.weight": [tensor_0, tensor_1, ..., tensor_7]  # 8 experts
  ".experts.*.w3.weight": [tensor_0, tensor_1, ..., tensor_7]  # 8 experts

After MergeModulelist(dim=0):
  ".experts.*.w1.weight": (8, 4096, 14336)  # stacked gate
  ".experts.*.w3.weight": (8, 4096, 14336)  # stacked up

After Concatenate(dim=1):
  ".experts.gate_up_proj": (8, 4096, 28672)  # fused gate_up

Desen eşleştirme kuralları

  • Kaynak desenleri, re.search() ile değerlendirilen tam düzenli ifadelerdir. ^, scope_prefix kaldırıldıktan sonra kapsamlı anahtarın başına sabitlenir.
  • *, aynı kaynak deseninin altında eşleşen tüm tensörleri toplayan, indeks başına bir joker karakterdir (doğru birleştirme için checkpoint sırasını korur).
  • Kaynak desenlerindeki yakalama grupları, orijinal anahtarın kısımlarını (ör. katman indeksleri) korumak için hedef desenlerde \1, \2, … olarak referans alınabilir.
  • Kapsamlı dönüşümler (scope_prefix ayarlı) yalnızca f"{scope_prefix}." ile başlayan anahtarlarla eşleşir.

Dönüşüm eşlemesi kaydetme

Bir dönüştürme listesi, bir dize anahtarına karşı kaydedilir — bu anahtar bir model_type (ör. "mixtral") veya bir sınıf adı (ör. "LlavaModel") olabilir:

from transformers.conversion_mapping import register_checkpoint_conversion_mapping

register_checkpoint_conversion_mapping(
    "my_model_type",
    [
        WeightRenaming(".old.", ".new."),
        WeightConverter(
            ".experts.*.w1.weight",
            ".experts.gate_proj",
            operations=[MergeModulelist(dim=0)],
        ),
    ],
)

Arama kuralları

get_model_conversion_mapping, bir PreTrainedModel işlediğinde, tüm alt PreTrainedModel ögeleri DFS sırasıyla ziyaret edilir (nn.Module.named_modules(), PreTrainedModel örneklerine göre filtrelenir). Her alt model iki aşamada çözümlenir: önce özel bir kod filtresi çalıştırılır, ardından kayıtlı eşleme sorgulanır.

Özel kod modelleri, herhangi bir arama işlemi yapılmadan önce atlanır. Bir alt model, is_custom_code() True döndürdüğünde özel kod olarak sayılır; bu durum, trust_remote_code=True ile Hub'dan yüklenen modelleri ve Transformers'ta bulunmayan herhangi bir model sınıfını kapsar. Özel kod modelleri, sınıf adlarının veya model_type değerlerinin yerel bir modelle çakışma ihtimali nedeniyle bir dönüştürme eşlemesi devralmaz. Örneğin, model_type="mixtral" ayarlayan özel bir mimari, Mixtral'in yerleşik uzman füzyonu dönüştürmelerini devralmaz.

Bir dönüştürme eşlemesi uygulamak için özel kod modelini açıkça register_checkpoint_conversion_mapping ile kaydedin. Kayıt işlemi, sınıf adını veya model_type değerini kullanıcı tarafından kaydedilen eşlemeler kümesine ekler; bu da modeli özel kod atlamasından muaf tutar ve aşağıdaki normal arama akışına yönlendirir.

Özel kod filtresini geçen her alt model için:

  1. Sınıf adı araması önce denenir, ardından model_type. İkisi de aynı modül için kayıtlıysa, sınıf adı eşlemesi önceliklidir ve o modül için model_type eşlemesi yok sayılır — bu, bir görev başlığının (ör. LlavaForConditionalGeneration) paylaşılan model_type temelini ("llava") geçersiz kılmasına olanak tanır.
  2. Seçilen eşlemede scope_prefix, alt modülün noktalı yoluna ("" kök için) ayarlanmıştır.
  3. Ancestor-based deduplication haritanın korunup korunmayacağına karar verir:
    • Eğer bir üst düzey yol, aynı tanımlayıcıyı (sınıf adı veya model_type) zaten kullanmışsa, alt modül atlanır — üst düzeyin kapsam dışı veya daha geniş kapsamlı eşlemesi bu alt ağacı zaten kapsar.
    • Eğer yalnızca bir kardeş bunu talep ettiyse, alt modül kendi scope_prefix'iyle korunur. Her kardeş, kendi kapsamlı eşlemesine sahip olur.

Sınıf adları ve model_type görülmüş listeleri ayrı ayrı izlenir; burada bir nüans vardır: bir modül sınıf adıyla eşleştirildiğinde, onun model_type değeri görülmüş listesine eklenmez. Bunun nedeni, aynı model_type değerini paylaşan ancak sınıfa özgü bir eşlemesi olmayan diğer modüllerin (ör. DetrForSegmentation altındaki DetrModel) model_type araması yoluyla erişilebilir kalmasını sağlamaktır.

Sınıf tabanlı eşlemeler ve model_type takma adları

Her iki stil de _MODEL_TO_CONVERSION_PATTERN içinde bir arada bulunur:

_MODEL_TO_CONVERSION_PATTERN = {
    # model_type aliases (lookup by config.model_type)
    "minimax": "mixtral",
    "qwen3_moe": "qwen2_moe",
    "mistral3": "llava",
    # class-name aliases (lookup by type(submodule).__name__)
    "PaliGemmaModel": "LlavaModel",
    "MaskFormerDetrDecoder": "DetrModel",
    ...
}

model_type paylaşıldığında ancak belirli bir sınıfın farklı davranışa ihtiyaç duyduğu durumlarda, sınıf adı anahtarları tercih edilir.

Tensor paralelliği entegrasyonu

Dinamik yükleme sistemi, src/transformers/integrations/tensor_parallel.py dosyasında tanımlanan TensorParallelLayer hiyerarşisi aracılığıyla tensor paralelliği (TP) ile entegre edilir.

TP etkin olduğunda, tensörler materyalleştirme sırasında parçalanır, sonrasında değil. Bu, her rank'ın yalnızca ihtiyacı olan tensör bölümünü yüklediği anlamına gelir.

def spawn_tp_materialize(thread_pool, tensor, sharding_method, tensor_idx, device, dtype):
    def _job():
        return sharding_method.shard_tensor(tensor, tensor_idx=tensor_idx, device=device, dtype=dtype)
    return thread_pool.submit(_job)

Kullanılabilir paralel stiller

StilAğırlık Parça BoyutuAçıklama
colwise-2Sütun bazlı: parçalara ayrılmış çıktı özellikleri
rowwise-1Satır bazlı: girdi özellikleri bölünmüş
packed_colwise-2Birleşik ağırlıklar için (gate_up_proj)
packed_rowwise-1Birleştirilmiş ağırlıklar için
embedding_rowwise0Sözlük paralellik
grouped_gemm0MoE için uzman paralelliği
sequence_parallelNoneAğırlık bölümlendirmesi yok

Paketlenmiş ağırlık işleme

gate_up_proj gibi füzyonlu ağırlıklar için doğru şekilde parçalamak özel bir özen gerektirir:

def get_packed_weights(param, empty_param, device_mesh, rank, dim):
    """
    Interleaves gate and up shards correctly.

    Packed tensor: [G0 G1 G2 G3 | U0 U1 U2 U3]

    With TP=2:
    - Rank 0 gets: [G0 G1 | U0 U1]
    - Rank 1 gets: [G2 G3 | U2 U3]
    """

TP işlemi WeightTransform içinde saklanır ve dönüştürme işlemlerinden sonra uygulanır:

if matched_tp_pattern := tp_plan_alt.search(renamed_key):
    tp_layer = ALL_PARALLEL_STYLES[model.tp_plan[matched_tp_pattern]]
    mapping.distributed_operation = tp_layer(
        device_mesh=device_mesh,
        rank=device_mesh.get_local_rank(),
        empty_param=empty_param.clone()
    )

Quantization entegrasyonu

Quantization, checkpoint'in zaten kuantize edilip edilmediğine bağlı olarak, yükleme hattına iki farklı şekilde entegre olur:

  • Önceden kuantize edilmiş kontrol noktaları: Kuantizatör, kuantize edilmiş tensörleri serileştirmeyi çözen WeightConverter örnekleri sağlar (get_weight_conversions() üzerinden). İstenmeyen dönüşümleri önlemek için kontrol noktası veri türleri korunur.
  • Uçtan uca (on-the-fly) kuantizasyon: Kuantizatör, dönüşüm işlemlerinden sonra uygulanan ve ağırlıklar yükendikçe kuantize eden bir kuantizasyon işlemi sağlar.

Kantizatör, get_model_conversion_mapping işlevinin sonunda update_weight_conversions(...) aracılığıyla tüm dönüştürme listesini yeniden yazabilir — örneğin FP8 dekantizatörü, her mevcut dönüştürücünün başına Fp8Dequantize işlemini ekler, böylece blok başına ölçekler, uzman birleştirme / birleştirme işlemleri uzman başına yapıyı düzleştirmeden önce uygulanır.

Hızlı ve verimli model yükleme

Yükleyici, işlemler için hangi tensörlerin gerekli olduğunu bildiği ve bunların somutlaştırılmasını tembel (lazy) olarak planladığı için bir modelin yüklenmesi daha hızlıdır ve daha az bellek kullanır.

Yükleme aracı, desen eşleşmelerini keşfetmek ve tensörleri toplamak için kontrol noktasını bir kez tarar. Bunları Future nesneleri olarak saklar ve GIL'i bloklamadan asenkron yükleme için bir iş parçacığı havuzuna iletir. Bir parametre, kendisine bir iş parçacığı ayrıldığında hemen yüklemeye başlar.

Sisteminiz başka ağır süreçler çalıştırıyorsa, çoklu iş parçacıkları yüklemeyi hızlandırmak yerine yavaşlatabilir. Bu durumda, ağırlıkları sıralı olarak yüklemek için HF_DEACTIVATE_ASYNC_LOAD=1 ortam değişkenini ayarlayın.

Asenkron parametre yükleme için varsayılan değer 4 iş parçacığıdır. Bu, yükleme senaryoları ve donanım arasında en iyi dengeyi sağlar. İş yükü büyük ölçüde I/O sınırlıdır; ancak hızlandırıcı donanımına ve yükleme sırasında gereken dtype'e bağlı olarak, dtype serileştirilmiş olanla farklıysa CPU/GPU sınırlı hale gelebilir (bu, ek bir kopyalama işlemi gerektirir).

Eşzamanlı ve eş zamanlı yükleme

def spawn_materialize(thread_pool, tensor, device, dtype) -> Future | Callable:
    def _job():
        return _materialize_copy(tensor, device, dtype)

    if thread_pool is not None:
        return thread_pool.submit(_job)  # Async: returns Future
    else:
        return _job  # Sync: returns Callable (deferred execution)

Eşzamanlı yükleme şu durumlarda kullanılır:

  • HF_DEACTIVATE_ASYNC_LOAD=1 ortam değişkeni ayarlanmıştır.
  • Disk offloading etkinleştirildi (bellek kısıtlamaları sıralı yükleme gerektirir).
  • Uçtan uca (on-the-fly) kuantizasyon etkinleştirilmiştir (kuantizasyon adımının önüne geçmesini önlemek için işçi iş parçacıklarının ilerlemesini engeller).

Materiyalizasyon akışı

1. Checkpoint iteration (Phase 1):
   - For each key, walk the transform list once
   - Submit materialization job to ThreadPoolExecutor
   - Job returns Future (async) or Callable (sync)
   - Collect into the matching WeightConverter / WeightRenaming

2. Per-mapping processing (Phase 2, one mapping at a time):
   - materialize_tensors() waits for this mapping's Futures only
   - Apply conversion operations chain (self.operations)
   - Apply quantization operation (if on-the-fly)
   - Set parameters on model
   - Delete realized tensors immediately

3. Cleanup:
   - Thread pool shutdown (with cancel_futures=True for interrupts)

Bellek verimliliği

Bir ağırlık dönüştürülürken, dönüştürücü, henüz yüklenmemişse tüm gerekli tensörlerin materyalize olmasını bekler. Örneğin, MergeModulelist işlemi, birleştirme işleminden önce ModuleList içindeki tüm ağırlıkların yüklenmesini gerektirir.

Tensor birleştirme işlemleri geçici bir kopya gerektirdiğinden, MergeModulelist ve Concatenate gibi işlemler dönüştürme sırasında alttaki tensörlerin 2 katı bellek kullanır. Birleştirme tamamlandıktan sonra bellekte yalnızca sonuç tensörü kalır. Teorik en kötü durum bellek zirvesi, model boyutuna en büyük MergeModulelist veya Concatenate işlemi için gereken tensörlerin eklenmesiyle oluşur.

Bu en kötü durum, yalnızca talep yoğun dönüşüm çalışmadan önce diğer tüm parametreler yüklendiğinde ortaya çıkar. Bu durumu tetikleyen iki senaryo vardır.

  1. Talepkar dönüşüme geçilmeden önce tüm parametreler asenkron olarak yüklendi (iş parçacığı havuzu, dönüşüm kuyruğundan daha hızlıydı).
  2. Zorlu dönüştürme sonuncusudur.

Örneğin, her katmandaki uzmanlar için MergeModulelist kullanan bir MoE modelinde, teorik en kötü durum bellek zirvesi model boyutu ile bir katmandaki uzmanların toplamıdır.

Bu en kötü senaryolar nadiren görülür. Gerçek bellek zirvesi genellikle model boyutuna yakın kalır.

Geri Dönüştürülebilirlik

Sistem, ters dönüşümlerle modellerin kaydedilmesini destekleyerek gidiş-dönüş kaydet/yükle işlemini mümkün kılar. Kaydetme işlemi iki aşamada çalışır: önce ters çevrilmiş dönüştürücüler (her tensör en fazla birine eşleşir), ardından yukarıdaki sıralama kuralına göre ters çevrilmiş yeniden adlandırmalar.

def revert_weight_conversion(model, state_dict):
    """Applies reverse conversions for saving."""
    weight_conversions = getattr(model, "_weight_conversions", None)

    # Reverse all transforms
    reverse_weight_conversion = [
        conversion.reverse_transform() for conversion in weight_conversions
    ]

    # Apply in reverse
    for first_param_name, reversed_converter in conversion_mapping.items():
        realized_value = reversed_converter.convert(first_param_name, model=model)

Yükleme sırasında kullanılan dönüşümlerin listesi, modelde _weight_conversions olarak önbelleğe alınır (yalnızca gerçekten tetiklenen girdiler saklanır, bu nedenle PrefixChange gibi çift yönlü olmayan yeniden adlandırmalar doğru şekilde simetrik olarak yeniden uygulanır). Model from_pretrained kullanılmadan örneklenmişse (ve dolayısıyla _weight_conversions içermiyorsa), revert_weight_conversion eşlemeyi get_model_conversion_mapping üzerinden yeniden hesaplayarak geriye düşer ve eşlemeden herhangi bir PrefixChange öğesini düşürür (orijinal checkpoint'in öneki içerip içermediğini belirleyemeyiz).

Hedef desenler, ters yönde işlenmesi gereken regex öğeleri içerebilir:

def process_target_pattern(pattern: str) -> tuple[str, str | None]:
    """
    - Removes `^` and `$` anchors
    - Removes negative lookahead/lookbehind
    - Detects capturing groups, replaces with \1
    """

Gerçek örnekler

Mixstil MoE

Kontrol noktası biçimi:

model.layers.0.block_sparse_moe.experts.0.w1.weight  # gate per expert
model.layers.0.block_sparse_moe.experts.0.w2.weight  # down per expert
model.layers.0.block_sparse_moe.experts.0.w3.weight  # up per expert
...
model.layers.0.block_sparse_moe.experts.7.w1.weight

Model formatı:

model.layers.0.mlp.experts.gate_up_proj  # (8, 4096, 28672)
model.layers.0.mlp.experts.down_proj     # (8, 14336, 4096)

Dönüşüm eşlemesi (conversion_mapping.py dosyasından):

"mixtral": [
    WeightRenaming(".block_sparse_moe.", ".mlp."),
    WeightConverter(
        source_patterns=[".experts.*.w1.weight", ".experts.*.w3.weight"],
        target_patterns=".experts.gate_up_proj",
        operations=[MergeModulelist(dim=0), Concatenate(dim=1)],
    ),
    WeightConverter(
        source_patterns=[".experts.*.w2.weight"],
        target_patterns=".experts.down_proj",
        operations=[MergeModulelist(dim=0)],
    ),
],

Bileşik görme-dil modeli (Gemma3)

Gemma3, baş model ile temel model için farklı önek mantığına sahip standart yapıya sahiptir. İki kayıt tanımlanmıştır (burada paylaşılan "llava" / "LlavaModel" listelerine işaret eden takma adlar aracılığıyla):

# model_type: applies to Gemma3ForConditionalGeneration / Gemma3ForSequenceClassification
"gemma3": "llava"           # → adds "model." in front of language_model / vision_tower / ...

# class:    applies to the inner Gemma3Model only
"Gemma3Model": "LlavaModel"  # → minimal rename inside the already-prefixed namespace

Gemma3ForConditionalGeneration için DFS yürüyüşü:

  1. Root — sınıf araması kaçırır (Gemma3ForConditionalGeneration kayıtlı değil), model_type araması isabet eder ("gemma3") → "llava" önek yeniden yazma dönüştürmeleri kapsamsız olarak eklenir ve language_model, vision_tower, multi_modal_projector öğeleri model.* altına yerleştirilir.
  2. İç model: Gemma3Model — sınıf araması eşleşmeleri (Gemma3Model → LlavaModel) → yalnızca LlavaModel eşlemesi uygulanır ve kapsamı "model" ile sınırlıdır. Çok daha geniş kapsamlı "gemma3" (="llava") önek yeniden adlandırmaları burada yeniden uygulanmaz; bu da tam olarak istediğiniz şeydir: iç model, önekin zaten doğru olduğu bir ad alanında yer alır.

Llava ailesine ait tüm VLM'ler (PaliGemma, InternVL, Mistral3, …) aynı çift biçimini kullanır. model_type girdisi, baş modelinin önek ameliyatını ele alır; sınıf girdisi ise iç temel modelin eşlemesini minimal tutar.

Başlığa özgü bir geçersiz kılma ile daha derin iç içe geçme (DETR)

DetrForSegmentation, iki iç içe geçmiş seviyenin üzerine eklenmiş bir başlık özel geçersiz kılma (override) gösterir:

DetrForSegmentation                  (class registered: segmentation-only renames)
├── detr: DetrForObjectDetection     (no mapping; just walked through)
│   └── model: DetrModel             (class registered: shared base transforms)
│       └── backbone, encoder, ...
└── mask_head, bbox_attention        (head-specific weights)

İki eşleme söz konusudur (kayıtlı her anahtar için bir tane):

"DetrModel":           [WeightRenaming("backbone.conv_encoder", "backbone"), ...]      # shared base
"DetrForSegmentation": [WeightRenaming("mask_head.lay1", "mask_head.conv1.conv"), ...] # head-specific

DFS yürüyüşü:

  1. Kök DetrForSegmentation sınıf eşleşmesine göre → segmentasyon yeniden adlandırmaları unscoped olarak eklendi.
  2. detr: DetrForObjectDetection kayıtlı değil → dönüştürme eklenmedi; DFS içine devam ediyor.
  3. detr.model: DetrModel sınıf eşleşmesi → temel dönüşümler scope_prefix="detr.model" ile eklenir.

Bu nedenle DetrForObjectDetection kendi eşlemesine ihtiyaç duymaz: alt ağacındaki (DetrModel) tek kayıtlı eşleme, doğru yola otomatik olarak sınırlanır.

Sınıf anahtarlı takma adlar, ek kayıt gerektirmeden temel eşlemeyi yeniden kullanır: "MaskFormerDetrDecoder": "DetrModel", bir MaskFormer decoder'ının kendi sınıf adı altında aynı dönüşümleri almasını sağlar.

Özel işlemler (ERNIE 4.5 VL MoE)

Yerleşik işlemler yeterli olmadığında, özel bir ConversionOps alt sınıfı oluşturabilirsiniz. Örneğin, ERNIE 4.5 VL MoE, paylaşılan uzman listesini metin ve görme modaliteleri arasında bölmek zorundadır; bunu tek bir yerleşik işlem karşılamaz. Özel ErnieFuseAndSplitTextVisionExperts işlemi, uzmanları iki hedef anahtar arasında böler ve yeniden yığar:

"ernie4_5_vl_moe": [
    WeightRenaming("vision_model", "vision_tower"),
    WeightConverter(
        source_patterns=["experts.*.down_proj.weight"],
        target_patterns=[
            "text_moe.experts.down_proj",
            "vision_moe.experts.down_proj",
        ],
        operations=[ErnieFuseAndSplitTextVisionExperts(stack_dim=0, concat_dim=1)],
    ),
],

Özel op'lar, gidiş-dönüş kaydetme/yükleme desteği sağlamak için convert() ve reverse_op özelliğini uygulamalıdır.

Model türü takma adları

Birçok model, dönüşüm kalıplarını paylaşır:

_MODEL_TO_CONVERSION_PATTERN = {
    "mixtral": "mixtral",
    "minimax": "mixtral",
    "qwen2_moe": "qwen2_moe",
    "deepseek_v2": "qwen2_moe",
    "deepseek_v3": "qwen2_moe",
    "qwen3_moe": "qwen2_moe",
    "olmoe": "qwen2_moe",
    ...
}

Dinamik yükleme yapı taşlarının yeniden kullanımı

Dinamik ağırlık yükleme, yalnızca tam model kontrol noktalarıyla sınırlı değildir. Kontrol noktası anahtarlarının parametrelere nasıl eşlendiğini tanımlayabildiğiniz ve hedef modüllerin mevcut olduğunu doğruladığınız sürece, aynı yapı taşları herhangi bir ağırlık kümesini yüklemenizi sağlar.

Genel hatlarıyla sözleşme şu şekilde görünmektedir:

  1. Model ad alanını hazırlayın. Yüklemek istediğiniz modüllerin/parametrelerin mevcut olduğundan ve eşlemenizin onları hedefleyeceği şekilde adlandırıldığından emin olun. Adaptörler için, yüklemeye başlamadan önce adaptör modüllerinin var olmasını sağlamak üzere inject_adapter_in_model(...) çağrısını yapmanız gerekir. Özel başlıklar veya ek modüller için, bunları önce model üzerinde örnekleyin.
  2. Describe how to map weights. Bir dönüşüm/yeniden adlandırma listesi oluşturun (örneğin, _build_peft_weight_mapping(...)) kullanarak WeightConverter veya WeightRenaming. Bu, checkpoint anahtarlarının model ad alanınıza uyması için nasıl dönüştürüleceğini, bölüneceğini, birleştirileceğini veya yeniden adlandırılacağını ifade ettiğiniz yerdir. Temel olarak 3 şey yapabilirsiniz:
    • Dönüştürücüler listesine işlemler ekleyin: bunlar, WeightConverter içinde toplananlar hariç olmak üzere tüm ağırlıklara uygulanacaktır. Bunlar genel olarak WeightRenaming işlemleri olmalıdır
    • her dönüştürücünün işlemler listesine işlemler ekleyin: Quantization için olan da budur, burada herhangi bir WeightConverter'in işlemler listesinin ardından yalnızca bir kuantizasyon işlemi ekliyoruz.
    • özel operasyonlarınıza / map işlemlerini değiştirin: peft ile olan durum budur. Örneğin mixtral'in Concatenate operasyonunu PeftConcatenate olarak değiştiririz (PEFT'te tanımlıdır). Bu sayede adaptör kontrol noktası okunduğunda, birleştirilecek ağırlıklar toplanır ve peft için uygun biçimde formatlanır.
  3. Load + finalize + report. Çevrimiçi ve sonuçları günlüğe kaydetmek için çekirdek yükleyiciyi kullanın. Somut olarak bu akış şudur:
    • Yükleme ve dönüştürme için LoadStateDictConfig(...) + _load_pretrained_model(...) kullanın.
    • _finalize_load_state_dict(...) ile eksen/uymayan tensörleri meta dışına taşıyın, bunları başlatın ve ağırlıkları bağlayın.
    • eksik/beklenmeyen/uyumsuz anahtarları (ve dönüştürme hatalarını) raporlamak için log_state_dict_report(...) kullanın.

Bu API'ler, özel kod ve özel ağırlık biçimlerini işlemenize olanak tanımakla birlikte, transformers API'sinin en yüksek ve en verimli ağırlık yükleme, parçalama (sharding) ve kullanım kolaylığından da faydalanmanızı sağlamak için sunulmaktadır!

Ana dosyalar referansı

DosyaAmaç
src/transformers/core_model_loading.pyÇekirdek yükleme mantığı, WeightConverter, WeightRenaming, ConversionOps
src/transformers/conversion_mapping.pyYerleşik eşlemeler ve alt model başına kompozisyon (get_model_conversion_mapping)
src/transformers/integrations/tensor_parallel.pyTP bölme sınıfları ve yardımcıları
src/transformers/quantizers/base.pyKantizasyon kancaları ve temel sınıf
Update on GitHub