Ana içeriğe geç

Transformers v5 Tokenizasyonu: Mimarî ve Geçiş Rehberi

Transformers v5’e yükseltin. Birleşik Rust arka ucu, API değişiklikleri ve kodlama ile sohbet için v4 vs v5 geçiş kalıplarını yan yana gösteren pratik bir rehber.
· 8 dk. oku

Yapay Zeka ile Keşfedin

Tokenizasyon, HuggingFace Transformer yığınının çoğu zaman farkına bile varmadığımız bir parçasıdır; ta ki çıktılarınıza sızmaya başlayana kadar. Tek bir boşluk tuhaflığı, token sınırlarını değiştirebilir; çözümleme beklenmedik dizeler üretebilir ve şablonlama sırasında sohbet istemleri sessizce bozulabilir. 

Transformers v5, uygulamalar arasındaki davranışı standartlaştıran, API yüzeyini sadeleştiren ve hata ayıklamamız gerektiğinde belirteçleyici iç yapılarını incelemeyi kolaylaştıran bir tokenizasyon yeniden tasarımıyla bu sorun noktalarını ele alıyor.

Bu eğitimde, tokenizasyonun ne ürettiğini ve hattın nasıl çalıştığını anlatarak başlayacak, ardından pratik ve geçiş odaklı bir bakışla v5’te gerçekte nelerin değiştiğini adım adım göstereceğim. Kodlama, çözümleme, sohbet şablonları ve serileştirme için v4 ve v5 kod kalıplarını yan yana görerek kod tabanlarınızı güncelleyebileceksiniz.

Tokenizasyonda yeniyseniz, Python ile Doğal Dil İşlemeye Giriş kursuna göz atmanızı öneririm.

Tokenizasyon Nedir?

Çok yaygın bir tokenizasyon tanımı, metni token kimliklerine dönüştürdüğüdür; bu doğru ama eksiktir. Üretimde tokenizasyonu bir sözleşme olarak görmek daha yerindedir. Ham metin verildiğinde, belirteçleyici modelin güvenle tüketebileceği yapılandırılmış bir kodlama üretmelidir.

Asgari olarak bu sözleşme şunları içerir:

  • input_ids: modelin gömme tablosuna indekslenen tamsayı token kimlikleri.
  • Ayrıca gerçek token’lara karşılık gelen konumları dolgulardan ayıran attention_mask’i içerir.
  • Sapmalar/hizalamalar (varsa), token aralıklarını orijinal metindeki karakter veya sözcük düzeyi aralıklara geri eşler; bu, vurgulama, VİE (NER) ve atıf için gereklidir.
  • Özel token semantiği korunmalıdır; yani BOS/EOS/PAD/UNK yerleşimi ve kimlikleri modelin eğitimi sırasında kullanılan kurallarla eşleşmelidir.
  • Sohbet modellerinde, sohbet biçimlendirme de sözleşmenin bir parçasıdır; bu nedenle genellikle tokenizasyondan önce modelin sohbet şablonunu uygularız.

Transformers’ta bu sorumluluklar modelin ileri geçişi içinde değil, belirteçleyici katmanında bulunur; bu nedenle standart giriş noktası AutoTokenizer’dır. İşte basit bir örnek:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM3-3B")
enc = tokenizer("Hello world")
print(enc["input_ids"])
print(tokenizer.convert_ids_to_tokens(enc["input_ids"]))

Beklenen çıktı şöyledir:

[9906, 1917]
['Hello', 'Ġworld']

Burada enc, belirteçleyicinin ürettiği model hazır alanları (ör. input_ids ve çoğu zaman attention_mask) tutan sözlük benzeri bir kap olan bir BatchEncoding nesnesidir. Çıktı, giriş dizgesi için tamsayı token kimlikleri olan [9906, 1917]’yi ve karşılık gelen token dizelerini gösteren ['Hello', 'Ġworld']’ü döndürür. 

Not: Ġ öneki, token’ın başında bir boşluk içerdiğini belirten yaygın bir kuraldır; dolayısıyla Ġworld, boşluksuz “world” yerine “ world”ü temsil eder.

Bir Hat Olarak Tokenizasyon: v5 Bunu Nasıl Hata Ayıklanabilir Kılıyor

Tokenizasyon sorunları genellikle fazladan boşluklar, tuhaf Unicode bölünmeleri, token sayısında ani sıçramalar veya rollerin doğru izlenmediği sohbet istemleri gibi küçük problemler olarak ortaya çıkar. 

Bu sorunları hata ayıklamanın en basit yolu, tokenizasyonu aşamalardan oluşan bir hat olarak görmektir. Hangi aşamanın neyi kontrol ettiğini bildiğinizde, tahmin yürütmek yerine sorunları hızla yalıtabilirsiniz. Aklınızda tutmanız gereken bazı ipuçları şunlardır:

Tokenizasyon, bileşenlerden oluşan bir hattır

İlk hedef, belirteçleyicinin sadece bir WordPiece olduğuna dair yaygın yanılgıyı kırmaktır. Bunun yerine, normalleştirme, ön-tokenizasyon, alt sözcük modelleme, son işleme ve çözümleme gibi farklı dönüşüm aşamalarının ardışık bir dizisidir. Her aşama nihai davranışın farklı bir kısmını kontrol eder.

Hata ayıklanabilir zihinsel model

Tokenizasyonu aşamalara bölmek, güvenilir bir sorun giderme haritası sunar:

  • Boşlukla ilgili tuhaflıklar genellikle ön-belirteçleyiciden veya çözücünden kaynaklanır
  • Unicode çoğunlukla normalleştiricide ortaya çıkar.
  • Token patlamaları sıklıkla alt sözcük modelinden ve onun sözlük/birleştirmelerinden kaynaklanır
  • Sohbet biçimlendirme hataları çoğunlukla şablonlardan veya son işlemden gelir

Tasarım gereği açık ve incelenebilir

Transformers v5, özellikle Rust tokenizers motoru tarafından desteklenen belirteçleyiciler için, incelemeyi kolaylaştırır. 

Rust arka ucu kullanıldığında, tokenizer._tokenizer aracılığıyla (normalleştirici, ön-belirteçleyici, model, son işlemci, çözücü) alttaki bileşenleri inceleyebiliriz. _tokenizer’ı her gün kullanmayız, ancak v5 sürümüyle birlikte gerektiğinde iç yapıları görünür kıldığı için işe yarar.

Bu doğal olarak motor ve sarmalayıcı ayrımına yol açar:

  • Motor (tokenizers): Normalleştirme, bölme, alt sözcük parçalama ve token kimlikleri (ve varsa sapmalar) üretme gibi çekirdek mekanikleri gerçekleştiren düşük seviyeli Rust uygulaması.
  • Sarmalayıcı (transformers): Bu, özel token işleme, sohbet şablonları, dolgu/kırpma kuralları ve çerçeveye özgü tensör çıktıları gibi kuralları uygulayarak bu mekanikleri modele hazır girdilere dönüştüren model odaklı katmandır.

Transformers v5’te Neler Değişti?

Transformers v5 büyük bir standartlaştırma sürümüdür ve tokenizasyon, kullanıcıların göreceği değişikliklerin olduğu alanlardan biridir. Bu sürüm, yinelenen uygulamaları azaltır, belirteçleyici davranışını modeller arasında daha tutarlı hale getirir ve belirteçleyicileri (bazı durumlarda) sıfırdan eğitmeyi ve incelemeyi kolaylaştırır. Günlük kullanıcıları en çok etkileyen değişiklikler aşağıdadır.

Model başına tek bir belirteçleyici uygulaması

Önceki sürümlerde birçok modelde şunlar vardı:

  • yavaş bir Python belirteçleyici
  • hızlı, Rust destekli bir belirteçleyici uygulaması

v5’te Transformers, model başına tek bir belirteçleyici dosyasında birleştirme yapar ve Rust destekli yolu tercih eder. Rust destekli belirteçleyicinin işe yaramasının nedenleri şunlardır:

  • Yavaş ve hızlı uygulamalar arasındaki yinelenmeyi ortadan kaldırır.
  • Bu uygulamalar arasındaki ince davranış farklılıklarının neden olduğu denklik hatalarını azaltır.
  • Artık doğrulanacak tek bir birincil kod yolu olduğundan, bu belirteçleyici uygulaması test yüzeyini küçültür ve sadeleştirir.
  • Ayrıca modeller genelinde belirteçleyici davranışı için tek bir “gerçek kaynağı” tesis eder.

Kodlama API’si geçişi

v4’teki encode_plus() API’si, belirteçleyiciyi doğrudan çağırma lehine kullanımdan kaldırılmıştır. v4 ve v5 arasındaki sürüm farkı şöyledir:

v4 sürümü

enc = tokenizer.encode_plus(
    text,
    truncation=True,
    padding="max_length",
    max_length=128,
    return_tensors="pt",
)

v5 sürümü

enc = tokenizer(
    text,
    truncation=True,
    padding="max_length",
    max_length=128,
    return_tensors="pt",
)

encode_plus()’tan tek bir tokenizer() giriş noktasına geçmek, üretim kodunda ortaya çıkan gerçek hata türlerini azaltır. 

v4’te birden fazla kodlama yöntemi olması, kullandığınız yola bağlı olarak dolgu, kırpma, toplulaştırma veya tensöre dönüştürmede ince farklılıkların görünmesine neden olabiliyordu ve bu durum çoğu zaman tekil girdilerden toplu iş yüklerine geçildiğinde ortaya çıkıyordu. 

v5, her zaman bir BatchEncoding döndüren tek bir kodlama yolunda her şeyi standartlaştırır; bu da davranışı daha öngörülebilir kılar, uç durum hatalarını azaltır ve tokenizasyon hatlarını tutarlı tutmak için gereken kod miktarını düşürür.

Çözümleme API’si geçişi

v5, çözümlemeyi birleştirir; decode() hem tekil hem de toplu girdileri işler ve çözümleme davranışını kodlamayla hizalar.

v4 sürümü

texts = tokenizer.batch_decode(batch_ids, skip_special_tokens=True)

v5 sürümü

texts = tokenizer.decode(batch_ids, skip_special_tokens=True)

v5’te çözümleme, kodlamayı yansıtacak şekilde tasarlanmıştır. tokenizer() nasıl tek bir dizeyi veya bir dizi dizeyi kabul ediyorsa, decode() da tek bir token kimliği dizisini veya bir dizi diziyi kabul edebilir. 

Buradaki ana konu dönüş tipidir; yani bir dizi geçirirseniz tek bir dize alırsınız, ancak bir toplu (ör. list[list[int]]) geçirirseniz bir dize listesi alırsınız. Bu, API’yi genel olarak daha temiz kılar; ancak decode()’un her zaman bir dize döndüğünü varsayan kodların her iki durumu da ele alacak şekilde güncellenmesi gerekir.

Sohbet şablonları

v4’te, geriye dönük uyumluluk için apply_chat_template ham input_ids döndürüyordu. v5’te, diğer belirteçleyici yöntemleri gibi bir BatchEncoding döndürüyor.

v4 sürümü

input_ids = tokenizer.apply_chat_template(messages, return_tensors="pt")

v5 sürümü

enc = tokenizer.apply_chat_template(messages, return_tensors="pt")
input_ids = enc["input_ids"]
attention_mask = enc["attention_mask"]

v5’te apply_chat_template(), özel bir yardımcı yerine düzgün bir belirteçleyici giriş noktası olarak ele alınır. Yalnızca input_ids döndürmek yerine, input_ids ve attention_mask gibi alanları içeren tam bir BatchEncoding nesnesi döndürür. 

Bu önemlidir; çünkü sohbet biçimli girdiler artık normal tokenizasyonla aynı toplulaştırma, dolgu, kırpma ve tensör-dönüşü iş akışına bağlanır. Böylece maskeleri yeniden oluşturmak veya girdileri modele göndermeden önce formatları elle hizalamak için fazladan koda gerek kalmaz.

Belirteçleyici serileştirme

v5’te belirteçleyici serileştirme, özel token ve eklenen token üst verilerini daha az eserde birleştirerek sadeleştirilmiştir; geriye dönük uyumluluk için eski dosyalar desteklenmeye devam eder. Bu, birden fazla “gerçek kaynağı” dosyasının senkron dışına düşme riskini azaltır ve Transformers kütüphanesi dışında çalışan alt araçlarda belirteçleyici varlıklarını yüklemeyi ve yeniden kullanmayı kolaylaştırır.

Yapılandırılabilir mimariler olarak belirteçleyiciler

v5’teki temel değişim, bir belirteçleyicinin yalnızca serileştirilmiş dosyalardan yüklenen bir şey olmak yerine, öğrenilmiş eserlerle birlikte tanımlı bir hat olarak ele alınmasıdır.

  • Belirteçleyici sınıfı, metnin nasıl normalleştirileceğini, parçalara bölüneceğini, alt sözcük token’larına dönüştürüleceğini ve sonunda metne geri çözümleneceğini belirtir.
  • Sözlük ve birleştirme kuralları, hangi token’ların var olduğunu ve metnin token kimliklerine nasıl sıkıştırıldığını belirleyen öğrenilmiş eserlerdir.
  • Bu ayrım, mimari-öncelikli iş akışlarını mümkün kılar. Desteklenen belirteçleyiciler için, bir modelin tasarımını izleyen bir belirteçleyici başlatabilir ve ardından sözlüğü/birleştirmeleri ayrı olarak yükleyebilir veya eğitebilirsiniz; bu da özelleştirmeyi ve yeniden eğitmeyi çok daha yalın hale getirir.

Son Düşünceler 

Transformers v5 tokenizasyonu, standartlaşma ve sadeleşme yönünde büyük bir adımdır. Artık daha kanonik bir davranış yolu (yavaş/hızlı ayrışmasının azaltılması), sadeleştirilmiş bir API yüzeyi, normal tokenizasyonla aynı yapılandırılmış BatchEncoding nesnesini döndüren sohbet şablonlaması ve kırılgan dosya düzeyi varsayımları azaltan birleştirilmiş serileştirme var. 

Ayrıca, belirteçleyicilerin incelenmesini ve desteklenen durumlarda sıfırdan eğitilmesini kolaylaştıran mimari-öncelikli bir zihinsel modeli de teşvik eder. v4’ten sorunsuz geçiş için encode_plus()’ı tokenizer() ile, batch_decode()’u decode() ile değiştirin; apply_chat_template() çağrı noktalarını BatchEncoding ile çalışacak şekilde güncelleyin; kaydederken eski belirteçleyici dosya adlarını sabitlemekten kaçının ve yavaş belirteçleyici tuhaflıklarının tokenizers destekli davranışa yakınsamasını bekleyin.

Son sürümler hakkında daha fazla bilgi edinmek isterseniz, sürüm notları burada. Ayrıca uygulamalı pratik için Hugging Face Fundamentals beceri yolunu öneririm.

Tokenization v5 SSS

Hâlâ "Hızlı" (Rust) ve "Yavaş" (Python) belirteçleyici sınıfları arasında seçim yapmam gerekiyor mu?

Hayır. Transformers v5, model başına tek bir uygulamada bunları birleştirir. Kütüphane artık tüm desteklenen modeller için yüksek düzeyde optimize edilmiş Rust arka ucunu (tokenizers kütüphanesi) varsayılan olarak kullanır; LlamaTokenizerFast ile LlamaTokenizer arasında elle seçim yapma gereğini ortadan kaldırır.

Mevcut encode_plus kodum hemen çalışmayı durduracak mı?

Hemen değil, ancak kullanımdan kaldırıldı. v5, şu anda uyarıyla birlikte encode_plus’ı destekleyebilir; ancak doğrudan tokenizer(__call__) yöntemine geçmeniz şiddetle önerilir. Bu, yeni birleşik toplulaştırma davranışlarını edinmenizi sağlar ve kod tabanınızı geleceğe hazırlar.

apply_chat_template neden artık bir dize yerine BatchEncoding sözlüğü döndürüyor?

Sohbet girdilerini diğer model girdileri gibi ele almak için. Bir sözlük (input_ids ve attention_mask içeren) döndürerek, v5 sohbet biçimli verilerin ikinci bir tokenizasyon adımı gerekmeksizin anında toplulaştırılmasını, doldurulmasını ve kırpılmasını sağlar.

Hâlâ return_tensors="tf" veya return_tensors="jax" kullanabilir miyim?

Hayır. v5 mimari değişikliklerinin bir parçası olarak Transformers, TensorFlow ve Flax/JAX arka uçlarına yönelik resmi desteği bıraktı ve tamamen PyTorch’a odaklandı. PyTorch arka ucuna güvenmeniz veya modelleri diğer çerçeveler için ONNX/GGUF gibi formatlara aktarmanız gerekir.

v5’te "sessiz" tokenizasyon hatalarının hata ayıklamasını nasıl yaparım?

İncelenebilir iç kısımları kullanın. v5’te, tokenizer._tokenizer aracılığıyla alttaki Rust hattına erişebilirsiniz. Bu, Normalizer veya Ön-belirteçleyici gibi belirli aşamaları ayrı ayrı kontrol ederek bir dizgenin tam olarak nerede beklenmedik şekilde bölündüğünü veya değiştirildiğini görmenizi sağlar.

Aashi Dutt

Yazar

Aashi Dutt

ML (Üretken Yapay Zekâ) alanında Google Developers Uzmanıyım, Kaggle 3x Expert unvanına sahibim ve 3+ yıllık teknoloji deneyimiyle Women Techmakers Elçisiyim. 2020'de bir sağlık teknolojileri girişiminin kurucu ortağı oldum ve Georgia Tech'te makine öğrenmesi alanında uzmanlaşarak bilgisayar bilimleri yüksek lisansı yapıyorum.

Konular

İlgili