Buckets:
| # تخصيص مكوّنات النموذج | |
| طريقة أخرى لتخصيص نموذج هي تعديل مكوّناته، بدلاً من كتابة نموذج جديد بالكامل، مما يتيح لك تكييف النموذج ليناسب حالتك الاستخدامية المحددة. على سبيل المثال، يمكنك إضافة طبقات جديدة أو تحسين آلية الانتباه في بنية معيّنة. تُطبَّق التخصيصات مباشرةً على نموذج Transformers بحيث يمكنك مواصلة استخدام ميزات مثل [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) و[PreTrainedModel](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel) ومكتبة [PEFT](https://huggingface.co/docs/peft/en/index). | |
| ستُظهر لك هذه الدليل كيفية تخصيص آلية الانتباه في نموذج من أجل تطبيق [Low-Rank Adaptation (LoRA)](https://huggingface.co/docs/peft/conceptual_guides/adapter#low-rank-adaptation-lora) عليها. | |
| > [!TIP] | |
| > يُعدّ الأداة [clear_import_cache](https://github.com/huggingface/transformers/blob/9985d06add07a4cc691dc54a7e34f54205c04d40/src/transformers/utils/import_utils.py#L2286) مفيدة للغاية عند تعديلك وتطويرك كود النموذج بشكل متكرر. فهي تحذف جميع وحدات Transformers المخزنة مؤقتاً، وتسمح لـ Python بإعادة تحميل الكود المعدّل دون الحاجة إلى إعادة تشغيل بيئتك باستمرار. | |
| > | |
| > ```py | |
| > from transformers import AutoModel | |
| > from transformers.utils.import_utils import clear_import_cache | |
| > | |
| > model = AutoModel.from_pretrained("bert-base-uncased") | |
| > # modifications to model code | |
| > # clear cache to reload modified code | |
| > clear_import_cache() | |
| > # re-import to use updated code | |
| > model = AutoModel.from_pretrained("bert-base-uncased") | |
| > ``` | |
| ## فئة الانتباه | |
| [Segment Anything](./model_doc/sam) هو نموذج لتجزئة الصور، ويجمع إسقاط الاستعلام-المفتاح-القيمة (`qkv`) في آليات الانتباه الخاصة به. لتقليل عدد المعلمات القابلة للتدريب والعبء الحسابي، يمكنك تطبيق LoRA على إسقاط `qkv`. ويتطلب ذلك تقسيم إسقاط `qkv` بحيث يمكنك استهداف `q` و`v` بشكل منفصل باستخدام LoRA. | |
| 1. أنشئ فئة انتباه مخصصة، `SamVisionAttentionSplit`، عن طريق إنشاء فئة فرعية من فئة `SamVisionAttention` الأصلية. في `__init__`، احذف `qkv` المدمج وأنشئ طبقة خطية منفصلة لكل من `q` و`k` و`v`. | |
| ```py | |
| import torch | |
| import torch.nn as nn | |
| from transformers.models.sam.modeling_sam import SamVisionAttention | |
| class SamVisionAttentionSplit(SamVisionAttention, nn.Module): | |
| def __init__(self, config, window_size): | |
| super().__init__(config, window_size) | |
| # remove combined qkv | |
| del self.qkv | |
| # separate q, k, v projections | |
| self.q = nn.Linear(config.hidden_size, config.hidden_size, bias=config.qkv_bias) | |
| self.k = nn.Linear(config.hidden_size, config.hidden_size, bias=config.qkv_bias) | |
| self.v = nn.Linear(config.hidden_size, config.hidden_size, bias=config.qkv_bias) | |
| self._register_load_state_dict_pre_hook(self.split_q_k_v_load_hook) | |
| ``` | |
| 2. تقوم دالة `split_q_k_v_load_hook` بتقسيم أوزان `qkv` المُدرَّبة مسبقًا إلى أوزان منفصلة لـ `q` و`k` و`v` عند تحميل النموذج، لضمان التوافق مع أي نموذج مُدرَّب مسبقًا. | |
| ```py | |
| def split_q_k_v_load_hook(self, state_dict, prefix, *args): | |
| keys_to_delete = [] | |
| for key in list(state_dict.keys()): | |
| if "qkv." in key: | |
| # split q, k, v from the combined projection | |
| q, k, v = state_dict[key].chunk(3, dim=0) | |
| # replace with individual q, k, v projections | |
| state_dict[key.replace("qkv.", "q.")] = q | |
| state_dict[key.replace("qkv.", "k.")] = k | |
| state_dict[key.replace("qkv.", "v.")] = v | |
| # mark the old qkv key for deletion | |
| keys_to_delete.append(key) | |
| # remove old qkv keys | |
| for key in keys_to_delete: | |
| del state_dict[key] | |
| ``` | |
| 3. في مسار `forward`، يتم حساب `q` و`k` و`v` بشكل منفصل بينما يبقى بقية آلية الانتباه كما هي. | |
| ```py | |
| def forward(self, hidden_states: torch.Tensor, output_attentions=False) -> torch.Tensor: | |
| batch_size, height, width, _ = hidden_states.shape | |
| qkv_shapes = (batch_size * self.num_attention_heads, height * width, -1) | |
| query = self.q(hidden_states).reshape((batch_size, height * width,self.num_attention_heads, -1)).permute(0,2,1,3).reshape(qkv_shapes) | |
| key = self.k(hidden_states).reshape((batch_size, height * width,self.num_attention_heads, -1)).permute(0,2,1,3).reshape(qkv_shapes) | |
| value = self.v(hidden_states).reshape((batch_size, height * width,self.num_attention_heads, -1)).permute(0,2,1,3).reshape(qkv_shapes) | |
| attn_weights = (query * self.scale) @ key.transpose(-2, -1) | |
| attn_weights = torch.nn.functional.softmax(attn_weights, dtype=torch.float32, dim=-1).to(query.dtype) | |
| attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training) | |
| attn_output = (attn_probs @ value).reshape(batch_size, self.num_attention_heads, height, width, -1) | |
| attn_output = attn_output.permute(0, 2, 3, 1, 4).reshape(batch_size, height, width, -1) | |
| attn_output = self.proj(attn_output) | |
| if output_attentions: | |
| outputs = (attn_output, attn_weights) | |
| else: | |
| outputs = (attn_output, None) | |
| return outputs | |
| ``` | |
| عيّن الفئة المخصصة `SamVisionAttentionSplit` على وحدة `SamVisionAttention` الأصلية في النماذج لاستبدالها. يتم استبدال جميع حالات `SamVisionAttention` في النموذج بإصدار الانتباه المقسّم. | |
| استبدل الفئة *قبل* استدعاء [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained). يعمل خطاف التحميل فقط أثناء تحميل نقطة التفتيش، لذا فإن استبدال الوحدات في نموذج محمّل بالفعل سيترك طبقات `q` و`k` و`v` الجديدة مهيأة بشكل عشوائي. | |
| ```py | |
| from transformers import SamModel | |
| from transformers.models.sam import modeling_sam | |
| # replace the attention class the vision layers instantiate | |
| modeling_sam.SAM_VISION_ATTENTION_CLASSES["eager"] = SamVisionAttentionSplit | |
| # load the pretrained SAM model, the hook splits the qkv weights during loading | |
| model = SamModel.from_pretrained("facebook/sam-vit-base", attn_implementation="eager") | |
| ``` | |
| ## LoRA | |
| عند استخدام إسقاطات منفصلة لـ `q` و`k` و`v`، طبّق LoRA على `q` و`v`. | |
| أنشئ [LoraConfig](https://huggingface.co/docs/peft/package_reference/config#peft.PeftConfig) وحدد الرتبة `r` و`lora_alpha` و`lora_dropout` و`task_type` والأهم من ذلك، الوحدات المستهدفة. | |
| ```py | |
| from peft import LoraConfig, get_peft_model | |
| config = LoraConfig( | |
| r=16, | |
| lora_alpha=32, | |
| # apply LoRA to q and v | |
| target_modules=["q", "v"], | |
| lora_dropout=0.1, | |
| task_type="FEATURE_EXTRACTION" | |
| ) | |
| ``` | |
| مرّر النموذج و[LoraConfig](https://huggingface.co/docs/peft/package_reference/config#peft.PeftConfig) إلى [get_peft_model](https://huggingface.co/docs/peft/package_reference/peft_model#peft.get_peft_model) لتطبيق LoRA على النموذج. | |
| ```py | |
| model = get_peft_model(model, config) | |
| ``` | |
| استدعِ [print_trainable_parameters](https://huggingface.co/docs/peft/package_reference/peft_model#peft.PeftMixedModel.print_trainable_parameters) لعرض عدد المعاملات التي يتم تدريبها مقابل إجمالي عدد المعاملات. | |
| ```py | |
| model.print_trainable_parameters() | |
| "trainable params: 589,824 || all params: 94,274,096 || trainable%: 0.6256" | |
| ``` | |
Xet Storage Details
- Size:
- 8.37 kB
- Xet hash:
- b81d5354c0ed7f23aaf32a372fc910c38731628feb6e7bf4391ad7560f8e37c7
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.