SON DAKİKA

Nvdia

NVIDIA NeMo Curator ile Yüksek Kaliteli Vietnamca Veri İşleme

Open-source büyük dil modelleri (LLM’ler), özellikle İngilizce dilinde başarılı iken, Güneydoğu Asya’nın dilleri gibi diğer dillerde zorluklar yaşamaktadır. Bu durum, bu dillerdeki eğitim verisi eksikliği, yerel kültürlerin sınırlı anlaşılması ve benzersiz dil yapıları ile ifadeleri yakalamak için yetersiz token sayısı gibi etkenlerden kaynaklanmaktadır.

Müşteri ihtiyaçlarını tam olarak karşılamak için, İngilizce konuşmayan ülkelerdeki işletmelerin, genel modellerin ötesine geçmesi ve yerel dillerin inceliklerini kapsayan özel modifikasyonlar yapması gerekmektedir. Bu şekilde, müşterilere sorunsuz ve etkili bir deneyim sunulmuş olacaktır.

Viettel Çözümleri’nin Başarısı

Bu yazıda, hızlı bir şekilde büyüyen Viettel Solutions şirketinin, NVIDIA NeMo Curator aracını kullanarak yüksek kaliteli Vietnamca veri işleme sürecinden bahsedeceğiz. Bu süreç, Llama 3 ViettelSolution 8B modelinin eğitiminde kullanılarak, onu VMLU liderlik tablosunda üst sıralara taşıyan bir başarı öyküsüdür. NeMo Curator, LLM’lerin ön eğitimine yönelik büyük ölçekli ve yüksek kaliteli veri setleri oluşturmayı sağlayan bir GPU hızlandırmalı veri kürasyon aracıdır.

Veri Küretme Süreci

Bu yolculuğun kritik bir adımı, büyük ölçekli ve yüksek kaliteli veri setlerinin derlenmesidir. Yazının geri kalanında, kullanılan veri derleme pipeline’ını inceleyecek ve her aşamanın etkisini gösterecek detaylı bir keşif veri analizi (EDA) ile örnek kodlar sunacağız. Yazının sonunda, NeMo Curator ile başlamak için net bir yol haritası ve referans elde etmiş olacaksınız, bu ister Vietnamca olsun ister başka diller.

Viettel Solutions, Vietnam hükümeti ve işletmeleri için dijital dönüşüm çözümleri sunmada öncü bir firma olarak, çeşitli sektörlerde AI benimseme gereksinimlerini karşılamaya odaklanmıştır. Viettel, jeneratif AI alanında lider olmayı ve müşterileri için AI destekli ürünler geliştirmeyi hedeflemektedir. Bu amaçla, NeMo Curator ekibiyle iş birliği yapmıştır.

“NeMo Curator’ın GPU hızlandırmalı özellikleri, tam ve bulanık çiftleme olarak adlandırılan işlemleri ve heuristik ve sınıflayıcı filtrelemeyi içeriyor. Bu sayede, doğruluk yüzde 10 artırıldı, eğitim süresi üç kat hızlandı ve veri setinin boyutu yüzde 60 azaltıldı,” diyor Viettel Solutions’tan Veri Analitiği Müdürü Tuan Nguyen.

Gereksinimler ve Ortam Kurulumu

Bu yazıda sunulan adımları takip edebilmek için aşağıdaki gereksinimlerinizi hazırlayın:

Kurulum

İlk olarak, NeMo Curator’ı kurmak için, NeMo Curator deposunun README dosyasındaki talimatları izleyin.

Daha sonra, veri setlerini ve jsonlines paketlerini yüklemeniz gerekecektir. Aşağıdaki komutları kullanabilirsiniz:

pip install datasets
pip install jsonlines

Veri işleme sürecine devam etmek için bir Dask ortamı kurmalısınız. Dask, Python‘da paralel ve dağıtık hesaplamaları etkin bir şekilde gerçekleştirmeye olanak tanıyan esnek ve açık kaynaklı bir kütüphanedir. Dask, görevleri dağıtarak veri yönetim sürecini belirgin şekilde hızlandırır.

Bu deneyimi, veri seti boyutunu işlemek için 128 çekirdekli CPU ve 2TB RAM’e sahip bir NVIDIA DGX A100 üzerinde gerçekleştirdik. Veri seti ve hesaplama kaynaklarına bağlı olarak, Dask işçi konfigürasyonunu buna göre ayarlamanız gerekebilir. Aşağıdaki komutlarla bir Dask kümesi başlatabilirsiniz:

import nemo_curator
from dask.distributed import Client, LocalCluster
# 64GB bellek sınırına sahip 12 işçi ile bir Dask kümesi başlatın. Bu sayıları, bilgisayar kaynaklarınıza göre ayarlamalısınız.
cluster = LocalCluster(n_workers=12, processes=True, memory_limit='64GB')
client = Client(cluster)

Veri İşleme Pipeline’ına Genel Bakış

Veri kürasyon pipeline’ı aşağıdaki temel adımları içermektedir:

  • İndirme ve parçalara ayırma: Veri setleri çeşitli kaynaklardan indirilir, birleştirilir ve dağıtılmış işleme için parçalara ayrılır.
  • Unicode yeniden formatlama: Metinler tutarlı bir Unicode formatına standardize edilir.
  • Kesin deduplikasyon: Tekrar eden verileri ortadan kaldırarak, veri setindeki fazlalığı azaltır.
  • Kalite filtreleme
    • Heuristik filtreleme: Düşük kaliteli içeriği kaldırmak için kurallar bazlı filtreler uygulanır.
    • Sınıflayıcı tabanlı filtreleme: Kaliteye göre belgeleri sınıflandırmak için makine öğrenimi kullanılır.
Data processing pipeline with NeMo Curator. The pipeline includes these key steps, Download and Sharding, Unicode Reformatting, Exact Deduplication and Quality Filtering.
Şekil 1. NeMo Curator ile oluşturulan veri işleme pipeline’ı

Veri Toplama

LLM’ler için eğitim verimizin çeşitliliğini ve hacmini artırmak amacıyla çoklu veri setlerinden içerik temin ettik. Bu veri setleri şunlardır:

  • C4 veri setinin Vietnamca alt kümesi; çeşitli web taraması verilerinden oluşan büyük ve çeşitli bir koleksiyon.
  • OSCAR veri setinin Vietnamca alt kümesi; web tarama verilerinin bir derlemesi (versiyon 23.01).
  • Wikipedia’nın Vietnamca makaleleri, yapılandırılmış ve bilgilendirici içerik sunmaktadır.
  • Vietnamca haber kümesi, yerel olarak alakalı haber makaleleri sunar.

Her veri seti, Hugging Face Hub üzerinden erişilip indirilmiştir. OSCAR için ek adımlar gerekmektedir; bu veri seti için veri seti sayfasında koşulları kabul etmeniz gerekmektedir. Daha sonra bir Hugging Face erişim belirteci ile indirebilirsiniz.

Veri Setlerini İndirme ve Parquet Formatına Dönüştürme

Parquet, Dask gibi dağıtık sistemler için optimize edilmiştir; böylece büyük ölçekli veriler ile çalışırken bölümlendirme ve paralel işleme kolaylığı sağlamaktadır. Bu yazıda, tüm veri seti aşamaları Parquet formatında kaydedilecektir.

Aşağıdaki kod parçacığı, Hugging Face’den veri setlerini indirip Parquet dosyaları olarak kaydeder:

import os
from datasets import load_dataset as load_hf_dataset
from datasets import DownloadConfig

data_dir = "./datasets/"
download_config = DownloadConfig(num_proc=4)

# Vietnamca Wikipedia veri setini yükleyip kaydetme
ds = load_hf_dataset("wikimedia/wikipedia", "20231101.vi")
ds["train"].to_parquet(os.path.join(data_dir, "wiki_vi_231101.parquet"))

# Vietnamca haber kümesini yükleyip kaydetme
ds = load_hf_dataset("jetaudio/binhvq_news")
ds["train"].to_parquet(os.path.join(data_dir, "binhvq_news_train.parquet"))

# OSCAR veri setini yükleyip kaydetme
ds = load_hf_dataset("oscar-corpus/OSCAR-2301", language="vi", token=True, download_config=download_config, trust_remote_code=True)
ds['train'].to_parquet(os.path.join(data_dir, 'oscar_vi.parquet'))

# C4 veri setini yükleyip kaydetme
ds = load_hf_dataset("allenai/c4", data_files='multilingual/c4-vi.*.json.gz', download_config=download_config, trust_remote_code=True)
ds['train'].to_parquet(os.path.join(data_dir, "c4_vi.parquet"))

Veri seti belgelerini, NeMo Curator alan sınıflayıcı modelini kullanarak 26 alandan birine sınıflandırdık. Şekil 3’te görüldüğü gibi, dağılım oldukça dengeli olup, birçok alan toplam verinin %3 ile %6’sını kapsamaktadır. Bu, eğitim verilerinin geniş bir konu yelpazesini kapsamasının faydalı olduğunu göstermektedir.

This pie chart illustrates the domain distribution within the raw dataset as identified by a domain classifier model. The largest domain is Business and Industrial at 7.1%, followed closely by Arts and Entertainment at 6.8% and News at 6.4%. Other significant categories include Health at 6.2% and Sensitive Subjects at 5.7%. Smaller domains represented are Shopping (2.3%) and Games (2.5%), highlighting the diverse content within the dataset.
Şekil 3. Ham veri setinde alan sınıflayıcı modeli tarafından tanımlanan alan oranları

Birleşitirme ve Formatı Standardize Etme

Veri setleri indirildikten sonra, sonraki adım tüm kaynaklar arasında verileri tutarlı bir şekilde standardize etmek ve formatlamaktır. Bunlar, sadece ‘metin’ alanını koruyarak tek bir veri setinde birleştirilir. Eğitim için kullanılan bütün metinsel veriler bu alanda bulunduğundan, metin dışı diğer veriler genellikle gerekli değildir.

from datasets import concatenate_datasets
# Veri setlerini birleştirir ve formatı standart hale getirir
datasets = [os.path.join(data_dir, file) for file in ["wiki_vi_231101.parquet", "c4_vi.parquet", "oscar_vi.parquet", "binhvq_news_train.parquet"]]

data_files = {"train": datasets[0]}
ds = load_hf_dataset("parquet", data_files=data_files)
ds = ds["train"].remove_columns([col for col in ds["train"].column_names if col != "text"])

for d in datasets[1:]:
    ds_ = load_hf_dataset("parquet", data_files={"train": d})
    ds_ = ds_["train"].remove_columns([col for col in ds_["train"].column_names if col != "text"])
    ds = concatenate_datasets([ds, ds_])

Birleşik Veri Setini Parçalara Ayırma

Birleşik veri seti daha sonra daha küçük parçalara ayrılır. Parçalama, Dask kümesindeki işçi sayısını artırmak ve veri kürasyon aşamalarında verimli paralel işlemeyi sağlamak amacıyla yapılır.

# Ham veriler için yolları tanımlama
raw_data_directory = os.path.join(data_dir, "raw")

# Veri setini parçalara ayır
num_shards = 256
for shard_idx in range(num_shards):
    shard = ds.shard(index=shard_idx, num_shards=num_shards)
    shard.to_parquet(os.path.join(raw_data_directory, f"{shard_idx}.parquet"))

NeMo Curator ile Yüksek Kaliteli Veri İşleme

Bu bölümde NeMo Curator’dan yararlandığımız çeşitli teknikleri ele alacağız. Unicode yeniden formatlama, kesin deduplikasyon, heuristik filtreleme ve sınıflayıcı tabanlı filtreleme, bu veri setini yüksek kaliteli bir son versiyona işlemek ve geliştirmek için kullanılmıştır.

Unicode Yeniden Formatlama

Unicode yeniden formatlama, metin verilerinin standartlaştırılması ve şifreleme hatalarından arındırılması açısından kritik bir ön işleme adımıdır. Aşağıdaki kod, NeMo Curator kullanarak Unicode yeniden formatlamayı göstermektedir:

from nemo_curator import Modify
from nemo_curator.modifiers import UnicodeReformatter
from nemo_curator.utils.distributed_utils import read_data, write_to_disk
from nemo_curator.utils.file_utils import get_all_files_paths_under
from nemo_curator.datasets import DocumentDataset

# Unicode formatında veri için yolları tanımlama
unicode_formatted_output_path = os.path.join(data_dir, "formatted")

def load_dataset(input_data_dir, file_type="parquet"):
    files = list(get_all_files_paths_under(input_data_dir))
    raw_data = read_data(files, file_type=file_type, backend="pandas", add_filename=True)
    dataset = DocumentDataset(raw_data)

    return dataset

# Ham veriyi yükle
raw_data = load_dataset(raw_data_directory, file_type="parquet")

# Unicode yeniden formatlayıcıyı başlat
cleaner = Modify(UnicodeReformatter())

# Unicode yeniden formatlamayı uygula
cleaned_data = cleaner(raw_data)

# Temizlenmiş verileri diske kaydet
write_to_disk(cleaned_data.df, unicode_formatted_output_path, write_to_filename=True, output_type="parquet")

Belgelere Özel Kimlikler Ekleme

Daha ileri kürasyon adımlarına geçmeden önce, veri setine her belge için benzersiz bir kimlik eklemek önerilir. Bu kimlikler, kopya ya da düşük kaliteli belgelerin tespitinde yardımcı olur ve her belgenin işlem boyunca özgün olarak tanımlanmasını sağlar.

NeMo Curator, belirli bir önek formatı kullanarak belgelere özel kimlikler eklemek için bir AddId sınıfı sunmaktadır. Aşağıdaki kod parçacığı bu adımı göstermektedir:

from nemo_curator import AddId

# Giriş verisi ve eklenmiş ID'ler ile çıkış yollarını tanımlama
add_id_input_data_dir = unicode_formatted_output_path
added_id_output_path = os.path.join(data_dir, "add_id")
add_ID_id_prefix = "VI_"

# Formatlanmış veri setini yükle
dataset = DocumentDataset.read_parquet(add_id_input_data_dir)

# Önerilen bir önek ve başlangıç indeksi ile AddId sınıfını başlat
add_id = AddId(id_field='id', id_prefix=add_ID_id_prefix, start_index=0)

# Veri setine kimlik eklemeyi uygula
id_dataset = add_id(dataset)

# Kimlik eklenmiş veri setini diske kaydet
write_to_disk(id_dataset.df, output_file_dir=added_id_output_path, write_to_filename=True, output_type="parquet")

Kesin Deduplikasyon

Kesin deduplikasyon, veri setinden özdeş tekrarlananları kaldırarak her veri noktasının eğitim sürecine eşsiz bir şekilde katkıda bulunmasını sağlar ve veri setinin çeşitliliğini artırır.

Bu aşama, GPU Dask kümesi kullanarak hızlandırılmaktadır. Mevcut küme CPU destekli olduğundan, kapatılıp GPU desteği ile yeni bir küme başlatılması gerekmektedir.

Mevcut kümeyi kapatmak için aşağıdaki kodu kullanabilirsiniz:

client.cluster.close()
client.shutdown()

Daha sonra, GPU Dask kümesini başlatmak için:

os.environ["DASK_DATAFRAME__QUERY_PLANNING"] = "False"

from nemo_curator.utils.distributed_utils import get_client

def pre_imports():
    import cudf 

client = get_client(cluster_type='gpu', set_torch_to_use_rmm=False)
client.run(pre_imports)

Kesin deduplikasyonun uygulanması aşağıdaki gibidir:

from nemo_curator.modules import ExactDuplicates

# Giriş ve çıkış yollarını tanımlama
exact_dedup_input_dataset_dir = added_id_output_path
exact_dedup_base_output_path = os.path.join(data_dir, "exact_dedup")
exact_dedup_log_dir = os.path.join(exact_dedup_base_output_path, "log")
exact_dedup_output_dir = os.path.join(exact_dedup_base_output_path, "data")
deduped_output_dir = os.path.join(data_dir,"remove_duplicate")

# Loglar ve çıkış için dizinler oluştur
!mkdir -p {exact_dedup_log_dir}
!mkdir -p {exact_dedup_output_dir}
!mkdir -p {deduped_output_dir}

# Kesin Duplicates için parametreler
exact_dedup_dataset_id_field = "id"
exact_dedup_dataset_text_field = "text"

# Giriş veri setini yükle
input_dataset = DocumentDataset.read_parquet(exact_dedup_input_dataset_dir, backend="cudf")

# Kesin deduplikasyonu başlat ve çalıştır
exact_dup = ExactDuplicates(
    logger=exact_dedup_log_dir,
    id_field=exact_dedup_dataset_id_field,
    text_field=exact_dedup_dataset_text_field,
    hash_method="md5",
    cache_dir=exact_dedup_output_dir
)
duplicates = exact_dup(dataset=input_dataset)

print(f"Kesin yineleyen dosya sayısı: {len(duplicates)}")

# Yineleyen belgeleri tespit edip kaldırmak için veri kümesini yükle
input_dataset = DocumentDataset.read_parquet(added_id_output_path, backend="cudf")
exact_duplicates = DocumentDataset.read_parquet(
    os.path.join(exact_dedup_output_dir, "_exact_duplicates.parquet"), backend="cudf")

# Yineleyen belge kimliklerinin listesini davet edelim
exact_docs_to_remove = exact_duplicates.df.map_partitions(
    lambda x: x[x._hashes.duplicated(keep="first")]
)

# Giriş veri kümesinden yineleyen belgeleri kaldır
result = input_dataset.df[
~input_dataset.df[exact_dedup_dataset_id_field].isin(exact_docs_to_remove[exact_dedup_dataset_id_field].compute())
]

# Son deduplikedyatılmış veri kümesini kaydet
write_to_disk(result, output_file_dir=deduped_output_dir, write_to_filename=True, output_type="parquet")

Heuristik Kalite Filtreleme

Heuristik kalite filtreleme, önceden belirlenmiş kurallara göre düşük kaliteli içeriği kaldırarak veri setinin kalitesini artırmayı amaçlar. Bu yaklaşım, istenmeyen veri karakteristiklerini ortadan kaldırmak için bir dizi filtre uygulamayı içerir; örneğin aşırı özel karakterler, çok kısa ya da uzun metinler gibi kriterler.

Heuristik filtreler için bir yapılandırılmış YAML dosyası kullanarak filtreleme kriterlerini ve ayarlarını belirledik. Bu dosya, filtreleme boru hattını oluştururken kullanılan kurallar listesini içermektedir. filter_pipeline yardımcı fonksiyonu, YAML ayarlarını okuyarak filtreleri birer birer veri kümesine uygular.

from nemo_curator.utils.config_utils import build_filter_pipeline
import warnings

# Giriş veri dosyası ve heuristik filtreleme sonrası çıkış yolu tanımlama
HF_input_data_dir = deduped_output_dir
HF_output_path = os.path.join(data_dir, "heuristic_filtering")

# Konfigürasyon dosyası için dizin oluştur
os.makedirs("config", exist_ok=True)
# Heuristik filtreleme için yapılandırma dosyasını indirin
!wget https://raw.githubusercontent.com/NVIDIA/NeMo-Curator/main/config/heuristic_filter_non-en.yaml -O ./config/heuristic_filter_non-en.yaml

# Filtreleme yapılandırma dosyası yolu tanımlama
filter_config_file = "./config/heuristic_filter_non-en.yaml"
os.makedirs(HF_output_path, exist_ok=True)

# YAML yapılandırma dosyasını yükleyin
filter_pipeline = build_filter_pipeline(filter_config_file)

# Veri setini yükle
dataset = DocumentDataset.read_parquet(HF_input_data_dir, backend="pandas")

# Filtreleme sırasında belirli uyarıları bastım
with warnings.catch_warnings():
    warnings.simplefilter("ignore", category=UserWarning)
    # Heuristik filtreleri veri kümesine uygulama
    result_data = filter_pipeline(dataset)

    # Filtrelenen veri kümesini diske kaydet
    result_data.to_parquet(HF_output_path, write_to_filename=True)

Token Sayısının Dağılımı

Heuristik filtrelemenin veri kümesini nasıl değiştirdiğini inceleyelim. Filtrelemeden önce, veri kümesinde çok fazla metin uzunluğu bulunmaktaydı; bazı belgeler birkaç token’dan başlarken, diğerleri 16K token’dan fazlasını kapsamaktadır. Filtrelemeden sonra, veri kümesi daha uniform bir dağılım göstermekte ve aşırı kısa belgeler (örneğin 64 token’den az olanlar) kaldırılmış, fazlalık içeren uzun belgeler ise daraltılarak önem taşımayan içerikleri içermemektedir.

This histogram illustrates the frequency of Log2 token counts per sample in the deduplicated and heuristic-filtered datasets, highlighting the removal of extremely short and overly long documents. In the deduplicated dataset, the highest frequency occurs at Log2 = 10 with 29.6 million samples, while heuristic filtering reduces this to 22.3 million. For Log2 = 8, the frequency drops from 19.7 million in the deduplicated dataset to 12.8 million after filtering. At the lower end, the frequency for Log2 = 4 is 0.6 million in the deduplicated dataset but eliminated in the heuristic-filtered dataset.
Şekil 4. Deduplication ve heuristik filtrelenmiş veri setlerinin örnek uzunluk dağılımını karşılaştırma

Karakter Bazlı Metreler

Şekil 5, heuristik kürasyon öncesi ve sonrası veri setinin karşılaştırmalı analizini göstermektedir.

This set of box plots shows the effect of heuristic filtering on symbol, number, and whitespace percentages in the dataset, demonstrating significant noise reduction. In the raw data, the maximum symbol percentage reaches 99.44%, while heuristic filtering reduces it to 81.61%. The number percentage also drops from a maximum of 91.53% in the raw data to 15.40% after filtering. For whitespace percentage, the maximum value decreases from 76.06% to 25.88%, indicating more consistent text formatting post-filtering.
Şekil 5. Heuristik kürasyondan önce ve sonra sembol, sayı, ve boşluk yüzdeleri üzerine kutu grafikler

Kutu grafikleri, başlıca gürültü veri setinde dışlama basamaklarının belirgin şekilde düşüşünü vurgulamaktadır. Sembollerde %8.84’ten %5.47’e, sayılarda %11.19’dan %6.14’e ve boşluklarda ise maksimum %76.06’dan %25.88’e kadar düşmüştür; %95’lik yüzdelik kesitte ise sabit kalmaktadır. Bu düşüşler, heuristik filtrelemenin sağlıklı metinler içeren daha fazla veriyi hedeflediği anlamına gelmektedir.

This chart presents box plots of word counts (left) and mean word length (right) before and after heuristic filtering, showing how extreme outliers are reduced. In the raw dataset, the maximum word count is 163,822, while the heuristic-filtered dataset has a reduced maximum of 100,948. The median word count drops from 459 in the raw dataset to 574 post-filtering, indicating a focus on more substantial text samples. For mean word length, the maximum decreases from 9.24 to 5.29, reflecting a more consistent text quality after filtering.
Şekil 6. Heuristik filtrelemeden önce ve sonra kelime sayısı ve ortalama kelime uzunluğu grafikler

Filtreleme, son derece uzun belgeleri kaldırmış, fakat genel kelime sayısı dağılımını benzer seviyede tutabilmiştir. Bu durum, hatalı tokenlar içeren o kadar uzun belgelerin kaldırıldığını göstermektedir.

Sınıflayıcı Tabanlı Kalite Filtreleme

Heuristik filtreleme, düşük kaliteli içeriği basit kurallarla kaldırmasına rağmen daha karmaşık kalite örüntülerini kaçırabiliyor. Sınıflayıcı tabanlı filtreleme, içerikleri yüksek veya düşük kalite olarak ayırmak için eğitilmiş bir sınıflayıcı modeli kullanarak, çeşitli veri setlerine daha akıllı ve esnek bir yanıt oluşturur.

Classifier için Veri Hazırlığı

Kalite sınıflayıcı eğitimi, her iki yüksek kaliteli ve düşük kaliteli içerik için temsili örnekler gerektirir. Yüksek kaliteli veri için, genel olarak yapılandırılmış ve güvenilir olan Vietnamca Wikipedia makaleleri kullanılmıştır. Düşük kaliteli örnekler ise filtrelenmeyen Vietnamca haber kümesine dayanmaktadır.

Veri hazırlığı süreci şöyle uygulanmaktadır:

# Yüksek ve düşük kaliteli örnek veriler için yollar
hq_samples_path = os.path.join(data_dir, "classifier_filtering/train_samples/hq")
lq_samples_path = os.path.join(data_dir, "classifier_filtering/train_samples/lq")

# Yüksek kaliteli veri setini yükleyip parçalamak
ds = load_hf_dataset("wikimedia/wikipedia", "20231101.vi")
num_shards = 8
for shard_idx in range(num_shards):
    shard = ds["train"].shard(index=shard_idx, num_shards=num_shards)
    shard.to_parquet(os.path.join(hq_samples_path, f"{shard_idx}.parquet"))

# Düşük kaliteli veri kümesini yükleyerek parçalamak
ds = load_hf_dataset("vietgpt/binhvq_news",split="train[:100000]")
num_shards = 32
for shard_idx in range(num_shards):
    shard = ds.shard(index=shard_idx, num_shards=num_shards)
    shard.to_parquet(os.path.join(lq_samples_path, f"{shard_idx}.parquet"))

Sınıflayıcıyı Eğitme

Sınıflayıcıyı eğitmek için, metin sınıflandırmasında etkili ve verimli bir yol sunan FastText algoritmasını kullandık. İşte yüksek kalite ve düşük kalitedeki örnekleri kullanarak sınıflayıcının eğitilmesine dair bir süreç:

from nemo_curator.modifiers import FastTextLabelModifier
import fasttext
import random

# Etiketlenmiş örnekler oluşturma fonksiyonu
def create_samples(data_path, label, num_samples):
    raw_dataset = DocumentDataset.read_parquet(data_path, backend='pandas')
    label_quality = Modify(FastTextLabelModifier(label))
    labeled_dataset = label_quality(raw_dataset)
    labeled_samples = labeled_dataset.df.sample(frac=num_samples / len(labeled_dataset.df))
    return labeled_samples["text"].compute().values.tolist()

# Eğitim verisi hazırlık
low_quality_samples = create_samples(lq_samples_path, "__label__lq", 100000)
high_quality_samples = create_samples(hq_samples_path, "__label__hq", 100000)
train_samples = low_quality_samples + high_quality_samples
random.shuffle(train_samples)

# Eğitim verisini bir dosyaya kaydet
train_file = "./cf_model_fasttext.train"
with open(train_file, "w", encoding="utf-8") as f:
    for sample in train_samples:
        f.write(sample + "n")

# FastText sınıflayıcısını eğit
model = fasttext.train_supervised(input=train_file, lr=0.01, dim=100, epoch=5, wordNgrams=2)
model_path = "./cf_model_fasttext_model.bin"
model.save_model(model_path)

Veri Setini Sınıflandırma ve Filtreleme

Sınıflayıcı eğitildikten sonra, veri setini filtrelemek amacıyla kullanılır. Bu noktada belgeler, öğrenilen ayırıcı özellere göre yüksek veya düşük kaliteli olarak sınıflandırılır:

from nemo_curator.filters import FastTextQualityFilter
from nemo_curator import ScoreFilter

# Yolları tanımla ve veri setini yükle
CF_input_data_dir = HF_output_path
CF_output_path = os.path.join(data_dir, "classifier_filtering/output")
target_dataset = DocumentDataset.read_parquet(CF_input_data_dir, "parquet")

# Filtreleme boru hattını ayarlarıyla yapılandır
filter_pipeline = ScoreFilter(FastTextQualityFilter(model_path), score_field="quality_score", score_type=float)
filtered_dataset = filter_pipeline(target_dataset)

# Filtrelenen veri kümesini kaydet
write_to_disk(filtered_dataset.df, output_file_dir=CF_output_path, write_to_filename=True, output_type="parquet")

Hassas ve Duygusal Verileri Ortadan Kaldırma

Özellikle Yetişkin ve Hassas Konular alanları ile birlikte Olumlu ve Olumsuz duygusal içerikler büyük ölçüde azaltılmıştır. Bu, modelin daha güvenli, daha nötr ve farklı bağlamlarda uygun yanıtlar vermesine olanak tanır.

This visualization shows the impact of classifier-based filtering in removing sensitive and sentimental data. In the heuristic-filtered dataset, 4542.31K samples belong to the "Sensitive Subjects" domain, which reduces to 273K samples after classifier-based filtering, accounting for 6.97% and 2.02% respectively. For "Adult" content, the count drops from 481.03K in heuristic filtering to 31K in classifier-based filtering, representing 0.74% and 0.23%. On the right, sentiment filtering shows a reduction in "Positive" samples from 4640K in heuristic filtering to 744K, and "Negative" samples reduce from 524K to 77K, making up 7.12% and 5.63% in heuristic filtering versus 0.80% and 0.59% in classifier-based filtering.
Şekil 7. Sınıflayıcı tabanlı filtrelemeden önce ve sonra hassas alan sayısı ve duygusal örneklerin sayısı

İçerik Çeşitliliğini Koruma

Kapsamlılık ve çeşitlilik sağlamak açısından, veri kümesini tekrar kontrol ettik. Veri setinin alan sınıflayıcı modeli ile yapılan bu son kontrol, temel dağılma özelliğini sürdürmekteydir. Çoğu alan, verinin %3 ila %8’ini kapsıyor ve bu çeşitlilik, Habercilik ve Hukuk gibi alanları içerirken Oyun ve Otomobil gibi daha uzmanlaşmış alanlarda bile dengeli dağılımlar göstermektedir.

This pie chart illustrates the domain distribution in the final dataset as identified by a domain classifier model. The largest domain is Arts and Entertainment at 7.86%, followed by Health at 7.42%, and People and Society at 7.07%. Other notable categories include Sports (6.66%), News (6.46%), and Food and Drink (5.7%). Smaller domains include Pets and Animals at 1.73% and Finance at 2.67%.
Şekil 8. Nihai veri kümesinin alan sınıflayıcı modeliyle tanımlanan dağılımları

Her Aşamada Veri Seti Boyutunu Azaltma

Her aşamada yaklaşık %90 oranında veri kaldırıldı; bu, düşük kaliteli, gürültü veya hatalı örneklerden oluşmaktadır. Bu seçimci filtreleme, eğitim verilerinin en yüksek kalitede olmasını sağlamaktadır. En büyük azalmanın %45.43’ü, sınıflayıcı tabanlı filtrelemeden gelmişken, bu çok miktarda içerik düşük kaliteli olarak işaretlenmiş ve bu aşamada kaldırılmıştır. Heuristik filtreleme, %35.74 oranında veri kaldırırken; kesin deduplikasyon ise %8.31 oranında veri taşımaktadır.

This bar chart displays the proportions of data filtered at each phase across different datasets, showing that 90% of data was removed to ensure high-quality training data. In the "All" dataset, 45.43% of data was removed through classifier-based filtering, 35.74% through heuristic filtering, and 8.31% due to duplication. For the "Binhvq_News" dataset, classifier-based filtering accounted for the largest reduction at 48.04%, followed by heuristic filtering at 36.6%. The "Wiki_Vietnamese" dataset saw 49.59% of data removed via classifier-based filtering and 37.31% via heuristic filtering, with 11.31% due to duplication.
Şekil 9. Farklı veri setlerinde her kürasyon aşamasında filtrelenen verilerin oranı

Gömme Görselleştirmesi

Nihai veri seti, orijinal dağılım ile benzerlik gösterirken, konuların çeşitliliği de haliyle korunmaktadır. Farklı konuların bağımsız alanları daha belirgin hale gelmektedir; bunu daha düşük kalitedeki içeriklerin kaldırılmasıyla ilişkilendirmek mümkündür.

Hem heuristik hem de sınıflayıcı tabanlı filtreleme sayesinde, veri kümesi kapsamlı bir alan çeşitliliğini korumakta. Özgün alanları temsil eden belirgin kümeler hala belirginliğini korurken, daha genel ve örtüşen alanların bu aşamada bile bağlantılı olduğu görülmektedir; bu, veri setinin dengeli ve kapsamlı olmasını sağlamaktadır.

This image showcases UMAP visualizations comparing a 5% sample of the raw dataset (left) and a 5% sample of the classifier-based filtered dataset (right). The visualizations demonstrate that the final dataset maintains domain diversity even after filtering, with well-distributed clusters for each domain. Both visualizations depict a range of 26 domains, such as Arts and Entertainment, Health, and News, represented by distinct colors. The classifier-based filtering retains the main structure and diversity of the raw dataset, ensuring well-represented domains post-filtering.
Şekil 10. Ham veri setinin (solda) ve sınıflayıcı tabanlı filtrelenmiş veri setinin (sağda) %5’lik örneklemine ait UMAP görselleştirmesi

Sonuç

Bu yazıda, Viettel Solutions’ın Vietnamca metin verileri için kullandığı veri kürasyon pipeline’ını sergilemekteyiz; ayrıca işlem sürecinin her aşamasının veri kümesine etkisini de ele alıyoruz. Pipeline, NVIDIA NeMo Curator’ı kullanarak yüksek kaliteli, verimli ve ölçeklenebilir veri hazırlama sürecinde önemli avantajlar sunmaktadır.

  • Düşük kaliteli içerikleri kaldırarak veri seti kalitesini artırma.
  • Veri setinin temel yapısını koruma; böylece ana özelliklerin korunabilirliği.
  • Farklı veri setlerine uyum sağlama; bu sayede her derlemenin özgül gereksinimlerini karşılama.

Tam kodu görmek için Jupyter Notebook’a göz atabilirsiniz. Diğer teknikler için NeMo Curator örnek skriptlerine göz atmayı unutmayın; bu sayede bulanık deduplikasyon ve PII redaksiyonu gibi diğer teknikler hakkında bilgi alabilirsiniz.

Kaynak

Nvdia Blog

Düşüncenizi Paylaşın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İlgili Teknoloji Haberleri