پردازش زبان طبیعی فارسی با ظهور مدل‌های زبانی پیشرفته مانند FaBERT و PersianMind در سال ۲۰۲۵ تحولی عظیم تجربه کرده است. این مدل‌ها قابلیت‌های تحلیل متن فارسی را نسبت به نسل‌های قبلی تا ۳ درصد بهبود داده و امکان پیاده‌سازی سیستم‌های هوشمند فارسی را بی‌سابقه کرده‌اند.

Fine-tuning یا تنظیم ریز این مدل‌ها برای محتوای فارسی چالش‌های منحصربه‌فردی دارد که نیاز به تخصص در پردازش متن راست‌به‌چپ، مدیریت نیم‌فاصله‌ها، و درک ساختار مورفولوژیکی پیچیده زبان فارسی دارد. موفقیت در این حوزه می‌تواند کاربردهای متنوعی از تحلیل احساسات تا سیستم‌های پرسش و پاسخ فارسی را محقق کند.

مدل‌های از پیش آموزش دیده فارسی مناسب برای Fine-tuning

FaBERT: بهترین انتخاب برای سال ۲۰۲۵

FaBERT با ۱۲۴ میلیون پارامتر و واژگان ۵۰ هزار کلمه‌ای، در حال حاضر بهترین عملکرد را برای اکثر کاربردهای فارسی ارائه می‌دهد. این مدل که بر روی ۵۰+ گیگابایت متن بلاگ فارسی آموزش دیده، عملکرد بهتری نسبت به ParsBERT در حین اشغال حافظه کمتر دارد.

from transformers import AutoTokenizer, AutoModelForSequenceClassification

# بارگذاری مدل FaBERT
model_name = "sbunlp/fabert"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=3)

PersianMind: قدرتمندترین مدل زبانی فارسی

PersianMind مبتنی بر LLaMA2-7B با ۷ میلیارد پارامتر و قابلیت پردازش متن‌های ۲۰۴۸ توکنی، نخستین مدل زبانی بزرگ فارسی محسوب می‌شود. این مدل در آزمون Belebele به دقت ۷۳.۹ درصد رسیده که عملکردی قابل مقایسه با GPT-3.5-turbo دارد.

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# بارگذاری PersianMind
model_name = "universitytehran/PersianMind-v1.0"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)

ParsBERT: استاندارد ثابت و قابل اعتماد

ParsBERT با ۱۶۲ میلیون پارامتر و آموزش بر روی ۱.۳ میلیارد کلمه فارسی، همچنان انتخاب مناسبی برای پروژه‌های تولیدی است. نسخه v3.0 این مدل پشتیبانی کاملی از نیم‌فاصله‌های فارسی دارد.

# بارگذاری ParsBERT v3.0
model_name = "HooshvareLab/bert-fa-zwnj-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

بهترین فریمورک‌ها برای Fine-tuning فارسی

کتابخانه Hezar: انتخاب اول برای توسعه‌دهندگان فارسی

Hezar جامع‌ترین کتابخانه هوش مصنوعی فارسی است که بر روی PyTorch، Transformers و Hugging Face بنا شده. این کتابخانه رابط کاربری ساده برای کارهای مختلف NLP فارسی فراهم می‌کند.

# نصب Hezar
# pip install hezar[all]

from hezar.models import BertSequenceLabeling, BertSequenceLabelingConfig
from hezar.data import Dataset
from hezar.trainer import Trainer, TrainerConfig

# تنظیم مدل برای برچسب‌گذاری توالی
base_model_path = "hezarai/bert-base-fa"
model = BertSequenceLabeling(
    BertSequenceLabelingConfig(id2label={0: "منفی", 1: "مثبت", 2: "خنثی"})
)

DadmaTools: ابزارهای جامع پردازش متن فارسی

DadmaTools مجموعه‌ای از ابزارهای پیشرفته برای پردازش متن فارسی است که شامل نرمال‌سازی، توکن‌سازی، و تحلیل مورفولوژی است.

# نصب DadmaTools
# pip install dadmatools

from dadmatools.normalizer import Normalizer
from dadmatools.tokenizer import Tokenizer

# ایجاد نرمال‌ساز فارسی
normalizer = Normalizer(
    unify_chars=True,
    refine_punc_spacing=True,
    remove_extra_space=True,
    remove_puncs=False
)

# استفاده از توکن‌ساز
tokenizer = Tokenizer()
text = "امروز روز خوبی است"
tokens = tokenizer.tokenize(text)
print(tokens)

پیاده‌سازی گام به گام Fine-tuning با کد

مرحله اول: آماده‌سازی محیط و داده‌ها

import torch
from transformers import (
    AutoTokenizer, AutoModelForSequenceClassification,
    TrainingArguments, Trainer, TrainerConfig
)
from datasets import Dataset
import pandas as pd
from sklearn.model_selection import train_test_split

# تابع پیش‌پردازش متن فارسی
def preprocess_persian_text(text):
    # نرمال‌سازی کاراکترها
    text = normalizer.normalize(text)
    
    # حذف کاراکترهای غیرضروری
    text = re.sub(r'[^\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF\s0-9]', '', text)
    
    # تبدیل اعداد فارسی به انگلیسی
    persian_numbers = '۰۱۲۳۴۵۶۷۸۹'
    english_numbers = '0123456789'
    for p, e in zip(persian_numbers, english_numbers):
        text = text.replace(p, e)
    
    return text.strip()

# بارگذاری و آماده‌سازی داده‌ها
def prepare_dataset(texts, labels):
    processed_texts = [preprocess_persian_text(text) for text in texts]
    
    dataset = Dataset.from_dict({
        'text': processed_texts,
        'labels': labels
    })
    
    return dataset

دوم: تنظیم مدل و توکن‌ساز

# انتخاب مدل پایه
model_name = "sbunlp/fabert"  # یا "HooshvareLab/bert-fa-zwnj-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
    model_name, 
    num_labels=3  # تعداد کلاس‌ها
)

# تابع توکن‌سازی
def tokenize_function(examples):
    return tokenizer(
        examples['text'],
        truncation=True,
        padding='max_length',
        max_length=512,
        return_tensors="pt"
    )

# اعمال توکن‌سازی بر داده‌ها
tokenized_train = train_dataset.map(tokenize_function, batched=True)
tokenized_val = val_dataset.map(tokenize_function, batched=True)

سوم: تنظیم پارامترهای آموزش

# تنظیم پارامترهای آموزش
training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    learning_rate=2e-5,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir='./logs',
    logging_steps=10,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    metric_for_best_model="eval_loss",
    greater_is_better=False,
    dataloader_num_workers=4,
    fp16=True,  # برای بهینه‌سازی حافظه
    gradient_checkpointing=True,
    gradient_accumulation_steps=2
)

چهارم: آموزش مدل

# ایجاد Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_train,
    eval_dataset=tokenized_val,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics  # تابع محاسبه معیارها
)

# تابع محاسبه معیارها
def compute_metrics(eval_pred):
    import numpy as np
    from sklearn.metrics import accuracy_score, precision_recall_fscore_support
    
    predictions, labels = eval_pred
    predictions = np.argmax(predictions, axis=1)
    
    precision, recall, f1, _ = precision_recall_fscore_support(
        labels, predictions, average='weighted'
    )
    
    return {
        'accuracy': accuracy_score(labels, predictions),
        'f1': f1,
        'precision': precision,
        'recall': recall
    }

# شروع آموزش
trainer.train()

# ذخیره مدل
trainer.save_model("./persian_model_finetuned")

چالش‌های خاص زبان فارسی و راه‌حل‌ها

مسئله نیم‌فاصله‌ها و کاراکترهای ZWNJ

زبان فارسی از کاراکترهای Zero-Width Non-Joiner (ZWNJ) استفاده می‌کند که در توکن‌سازی مشکل ایجاد می‌کنند. ParsBERT v3.0 و FaBERT این مسئله را حل کرده‌اند.

# مدیریت نیم‌فاصله‌ها
def handle_half_spaces(text):
    # تبدیل نیم‌فاصله‌ها به فاصله معمولی
    text = text.replace('\u200c', ' ')  # ZWNJ
    text = text.replace('\u200d', '')   # ZWJ
    
    # نرمال‌سازی فاصله‌ها
    text = re.sub(r'\s+', ' ', text)
    
    return text.strip()

پردازش متن راست به چپ

# تنظیم درست متن RTL
def prepare_rtl_text(text):
    # اطمینان از UTF-8 encoding
    if isinstance(text, str):
        text = text.encode('utf-8').decode('utf-8')
    
    # مدیریت متن دوجهته
    import unicodedata
    text = unicodedata.normalize('NFKC', text)
    
    return text

مسائل کدگذاری کاراکتر

# نرمال‌سازی کاراکترهای عربی به فارسی
def normalize_persian_chars(text):
    # نقشه‌برداری کاراکترهای عربی به فارسی
    arabic_to_persian = {
        'ي': 'ی',
        'ك': 'ک',
        'ء': 'ء',
        'ؤ': 'ؤ',
        'ة': 'ه',
        'ئ': 'ئ'
    }
    
    for arabic, persian in arabic_to_persian.items():
        text = text.replace(arabic, persian)
    
    return text

نکات بهینه‌سازی و بهترین شیوه‌ها

استفاده از LoRA برای آموزش کارآمد

LoRA (Low-Rank Adaptation) روشی است که امکان fine-tuning مدل‌های بزرگ را با ۹۹ درصد کاهش پارامترهای قابل آموزش فراهم می‌کند.

from peft import LoraConfig, get_peft_model, TaskType

# تنظیم LoRA
lora_config = LoraConfig(
    task_type=TaskType.SEQ_CLS,
    r=64,  # Rank
    lora_alpha=128,  # 2x rank
    lora_dropout=0.1,
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"]
)

# اعمال LoRA به مدل
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

تنظیم بهینه hyperparameter ها

# بهترین تنظیمات برای مدل‌های فارسی
optimal_config = {
    'learning_rate': 0.00015,  # بهینه برای مدل‌های فارسی
    'batch_size': 4,
    'gradient_accumulation_steps': 4,
    'max_length': 1024,
    'num_epochs': 3,
    'warmup_ratio': 0.03,
    'weight_decay': 0.01,
    'lr_scheduler_type': 'cosine'
}

استفاده از Mixed Precision

# تنظیم Mixed Precision برای بهینه‌سازی حافظه
training_args = TrainingArguments(
    # سایر تنظیمات...
    fp16=True,  # یا bf16=True برای GPU های جدیدتر
    dataloader_pin_memory=True,
    gradient_checkpointing=True,
    optim="adamw_torch_fused"  # optimizer بهینه‌تر
)

ارزیابی و اندازه‌گیری عملکرد

معیارهای ارزیابی برای زبان فارسی

def evaluate_persian_model(y_true, y_pred):
    from sklearn.metrics import (
        accuracy_score, precision_recall_fscore_support,
        classification_report, confusion_matrix
    )
    
    # محاسبه معیارهای اصلی
    accuracy = accuracy_score(y_true, y_pred)
    precision, recall, f1, _ = precision_recall_fscore_support(
        y_true, y_pred, average='weighted'
    )
    
    # گزارش تفصیلی
    report = classification_report(y_true, y_pred)
    
    return {
        'accuracy': accuracy,
        'precision': precision,
        'recall': recall,
        'f1_score': f1,
        'detailed_report': report
    }

ارزیابی سیستم‌های پرسش و پاسخ فارسی

def evaluate_persian_qa(predictions, references):
    from collections import Counter
    
    def normalize_persian_answer(text):
        # نرمال‌سازی پاسخ فارسی
        text = preprocess_persian_text(text)
        return text.lower().strip()
    
    def f1_score(prediction, ground_truth):
        pred_tokens = normalize_persian_answer(prediction).split()
        true_tokens = normalize_persian_answer(ground_truth).split()
        
        if len(pred_tokens) == 0 or len(true_tokens) == 0:
            return int(pred_tokens == true_tokens)
        
        common = Counter(pred_tokens) & Counter(true_tokens)
        num_same = sum(common.values())
        
        if num_same == 0:
            return 0
        
        precision = num_same / len(pred_tokens)
        recall = num_same / len(true_tokens)
        
        return (2 * precision * recall) / (precision + recall)
    
    f1_scores = [f1_score(pred, ref) for pred, ref in zip(predictions, references)]
    return sum(f1_scores) / len(f1_scores)

استقرار و اجرای مدل در محیط تولید

استفاده از VLLM برای سرویس‌دهی بهینه

# نصب VLLM
# pip install vllm

from vllm import LLM, SamplingParams

# بارگذاری مدل با VLLM
llm = LLM(
    model="./persian_model_finetuned",
    tensor_parallel_size=1,
    gpu_memory_utilization=0.9,
    max_model_len=1024
)

# تنظیم پارامترهای نمونه‌برداری
sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=512
)

# تولید پاسخ
prompts = ["سوال فارسی شما"]
outputs = llm.generate(prompts, sampling_params)

کوانتیزه کردن مدل برای کاهش حافظه

# استفاده از کوانتیزه 4-bit
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_use_double_quant=False
)

# بارگذاری مدل کوانتیزه شده
model = AutoModelForSequenceClassification.from_pretrained(
    model_name,
    quantization_config=quantization_config,
    device_map="auto"
)

منابع مفید و مجموعه داده‌ها

مجموعه داده‌های فارسی

  • ParsiNLU: مجموعه جامع benchmark فارسی
  • ARMAN & PEYMA: داده‌های NER فارسی
  • DigitalKala Sentiment: تحلیل احساسات فارسی
  • Persian Wikipedia: کوربوس بزرگ متن فارسی

مدل‌های از پیش آموزش دیده

# فهرست مدل‌های توصیه شده
recommended_models = {
    'classification': 'sbunlp/fabert',
    'generation': 'universitytehran/PersianMind-v1.0',
    'ner': 'HooshvareLab/bert-base-parsbert-armanner-uncased',
    'qa': 'SajjadAyoubi/bert-base-fa-qa',
    'multilingual': 'facebook/xlm-roberta-base'
}

نتیجه‌گیری

Fine-tuning مدل‌های زبانی فارسی با استفاده از ابزارهای مدرن مانند Hezar و DadmaTools به همراه تکنیک‌های بهینه‌سازی مانند LoRA و Mixed Precision امکان ایجاد سیستم‌های پیشرفته NLP فارسی را فراهم می‌کند.

کلیدهای موفقیت عبارتند از:

  • انتخاب مدل مناسب: FaBERT برای اکثر کاربردها، PersianMind برای تولید متن
  • پیش‌پردازش صحیح: مدیریت نیم‌فاصله‌ها و کاراکترهای خاص فارسی
  • بهینه‌سازی حافظه: استفاده از LoRA، Mixed Precision و Gradient Checkpointing
  • ارزیابی مناسب: استفاده از معیارهای مخصوص زبان فارسی

با پیروی از این راهنما، می‌توان سیستم‌های NLP فارسی با کیفیت بالا و عملکرد بهینه توسعه داد که قابلیت رقابت با بهترین مدل‌های بین‌المللی را دارند.