# التسلسل

`huggingface_hub` يوفر أدوات مساعدة لحفظ أوزان نماذج التعلم الآلي وتحميلها بطريقة موحدة. لا يزال هذا الجزء من المكتبة قيد التطوير وسيتم تحسينه في الإصدارات المستقبلية. الهدف هو توحيد طريقة حفظ الأوزان وتحميلها عبر Hub، وذلك لإزالة تكرار الكود بين المكتبات المختلفة ولإرساء معايير متسقة.

## صيغة ملف DDUF

DDUF هو تنسيق ملفات مصمم لنماذج الانتشار. يتيح حفظ جميع المعلومات اللازمة لتشغيل نموذج في ملف واحد. استُوحيت هذه العملية من تنسيق [GGUF](https://github.com/ggerganov/ggml/blob/master/docs/gguf.md). يوفر `huggingface_hub` أدوات مساعدة لحفظ ملفات DDUF وتحميلها، مع ضمان الالتزام بتنسيق الملف.

> [!WARNING]
> هذا إصدار مبكر جدًا من محلل الصياغة. قد تتطور واجهة برمجة التطبيقات والتنفيذ في المستقبل القريب.
>
> لا يقوم المُحلِّل حاليًا بأي تحقق يُذكر. لمزيد من التفاصيل حول تنسيق الملف، راجع https://github.com/huggingface/huggingface.js/tree/main/packages/dduf.

### كيف تكتب ملف DDUF؟

إليك كيفية تصدير مجلد يحتوي على أجزاء مختلفة من نموذج الانتشار باستخدام [export_folder_as_dduf()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.export_folder_as_dduf):

```python
# Export a folder as a DDUF file
>>> from huggingface_hub import export_folder_as_dduf
>>> export_folder_as_dduf("FLUX.1-dev.dduf", folder_path="path/to/FLUX.1-dev")
```

لمزيد من المرونة، يمكنك استخدام [export_entries_as_dduf()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.export_entries_as_dduf) وتمرير قائمة بالملفات التي تريد تضمينها في ملف DDUF النهائي:

```python
# Export specific files from the local disk.
>>> from huggingface_hub import export_entries_as_dduf
>>> export_entries_as_dduf(
...     dduf_path="stable-diffusion-v1-4-FP16.dduf",
...     entries=[ # List entries to add to the DDUF file (here, only FP16 weights)
...         ("model_index.json", "path/to/model_index.json"),
...         ("vae/config.json", "path/to/vae/config.json"),
...         ("vae/diffusion_pytorch_model.fp16.safetensors", "path/to/vae/diffusion_pytorch_model.fp16.safetensors"),
...         ("text_encoder/config.json", "path/to/text_encoder/config.json"),
...         ("text_encoder/model.fp16.safetensors", "path/to/text_encoder/model.fp16.safetensors"),
...         # ... add more entries here
...     ]
... )
```

يدعم معامل `entries` أيضًا تمرير قابل للتكرار من المسارات أو البايتات. وقد يثبت ذلك فائدة إذا كان لديك نموذج محمّل وتريد تسلسله مباشرةً في ملف DDUF بدلاً من الحاجة إلى تسلسل كل مكوّن على القرص أولاً ثم كملف DDUF. فيما يلي مثال على كيفية تسلسل `StableDiffusionPipeline` كـ DDUF:

```python
# Export state_dicts one by one from a loaded pipeline 
>>> from diffusers import DiffusionPipeline
>>> from typing import Generator, Tuple
>>> import safetensors.torch
>>> from huggingface_hub import export_entries_as_dduf
>>> pipe = DiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
... # ... do some work with the pipeline

>>> def as_entries(pipe: DiffusionPipeline) -> Generator[Tuple[str, bytes], None, None]:
...     # Build a generator that yields the entries to add to the DDUF file.
...     # The first element of the tuple is the filename in the DDUF archive (must use UNIX separator!). The second element is the content of the file.
...     # Entries will be evaluated lazily when the DDUF file is created (only 1 entry is loaded in memory at a time)
...     yield "vae/config.json", pipe.vae.to_json_string().encode()
...     yield "vae/diffusion_pytorch_model.safetensors", safetensors.torch.save(pipe.vae.state_dict())
...     yield "text_encoder/config.json", pipe.text_encoder.config.to_json_string().encode()
...     yield "text_encoder/model.safetensors", safetensors.torch.save(pipe.text_encoder.state_dict())
...     # ... add more entries here

>>> export_entries_as_dduf(dduf_path="stable-diffusion-v1-4.dduf", entries=as_entries(pipe))
```

**ملاحظة:** في الممارسة العملية، يوفر `diffusers` طريقةً لتسلسل خط الأنابيب مباشرةً في ملف DDUF. المقطع أعلاه يُقدَّم كمثال فقط.

### كيف تقرأ ملف DDUF؟

```python
>>> import json
>>> import safetensors.torch
>>> from huggingface_hub import read_dduf_file

# Read DDUF metadata
>>> dduf_entries = read_dduf_file("FLUX.1-dev.dduf")

# Returns a mapping filename <> DDUFEntry
>>> dduf_entries["model_index.json"]
DDUFEntry(filename='model_index.json', offset=66, length=587)

# Load model index as JSON
>>> json.loads(dduf_entries["model_index.json"].read_text())
{'_class_name': 'FluxPipeline', '_diffusers_version': '0.32.0.dev0', '_name_or_path': 'black-forest-labs/FLUX.1-dev', 'scheduler': ['diffusers', 'FlowMatchEulerDiscreteScheduler'], 'text_encoder': ['transformers', 'CLIPTextModel'], 'text_encoder_2': ['transformers', 'T5EncoderModel'], 'tokenizer': ['transformers', 'CLIPTokenizer'], 'tokenizer_2': ['transformers', 'T5TokenizerFast'], 'transformer': ['diffusers', 'FluxTransformer2DModel'], 'vae': ['diffusers', 'AutoencoderKL']}

# Load VAE weights using safetensors
>>> with dduf_entries["vae/diffusion_pytorch_model.safetensors"].as_mmap() as mm:
...     state_dict = safetensors.torch.load(mm)
```

### المساعدات[[huggingface_hub.export_entries_as_dduf]]

#### huggingface_hub.export_entries_as_dduf[[huggingface_hub.export_entries_as_dduf]]

```python
huggingface_hub.export_entries_as_dduf(dduf_path: str | os.PathLike, entries: Iterable)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_dduf.py#L160)

**المعاملات:**

dduf_path (`str` أو `os.PathLike`) : المسار إلى ملف DDUF الذي سيتم كتابته.

entries (`Iterable[tuple[str, Union[str, Path, bytes]]]`) : قابل تكرار من الإدخالات التي سيتم كتابتها في ملف DDUF. كل إدخال هو مجموعة مرتبة (tuple) تحتوي على اسم الملف والمحتوى. يجب أن يكون اسم الملف هو المسار إلى الملف داخل أرشيف DDUF. يمكن أن يكون المحتوى نصًا أو pathlib.Path يمثل مسارًا إلى ملف على القرص المحلي، أو المحتوى مباشرةً على شكل bytes.

**يرفع:** `-`

- - -- `DDUFExportError`: إذا حدث أي خطأ أثناء التصدير (مثل اسم إدخال غير صالح، أو غياب 'model_index.json'، إلخ).

اكتب ملف DDUF من قائمة قابلة للتكرار من العناصر.

هذا مساعد على مستوى أدنى من [export_folder_as_dduf()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.export_folder_as_dduf) يتيح مرونة أكبر عند تسلسل البيانات. على وجه التحديد، لا تحتاج إلى حفظ البيانات على القرص قبل تصديرها في ملف DDUF.

مثال:
```python
# Export specific files from the local disk.
>>> from huggingface_hub import export_entries_as_dduf
>>> export_entries_as_dduf(
...     dduf_path="stable-diffusion-v1-4-FP16.dduf",
...     entries=[ # List entries to add to the DDUF file (here, only FP16 weights)
...         ("model_index.json", "path/to/model_index.json"),
...         ("vae/config.json", "path/to/vae/config.json"),
...         ("vae/diffusion_pytorch_model.fp16.safetensors", "path/to/vae/diffusion_pytorch_model.fp16.safetensors"),
...         ("text_encoder/config.json", "path/to/text_encoder/config.json"),
...         ("text_encoder/model.fp16.safetensors", "path/to/text_encoder/model.fp16.safetensors"),
...         # ... add more entries here
...     ]
... )
```

```python
# Export state_dicts one by one from a loaded pipeline
>>> from diffusers import DiffusionPipeline
>>> from typing import Generator, Tuple
>>> import safetensors.torch
>>> from huggingface_hub import export_entries_as_dduf
>>> pipe = DiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
... # ... do some work with the pipeline

>>> def as_entries(pipe: DiffusionPipeline) -> Generator[tuple[str, bytes], None, None]:
...     # Build a generator that yields the entries to add to the DDUF file.
...     # The first element of the tuple is the filename in the DDUF archive (must use UNIX separator!). The second element is the content of the file.
...     # Entries will be evaluated lazily when the DDUF file is created (only 1 entry is loaded in memory at a time)
...     yield "vae/config.json", pipe.vae.to_json_string().encode()
...     yield "vae/diffusion_pytorch_model.safetensors", safetensors.torch.save(pipe.vae.state_dict())
...     yield "text_encoder/config.json", pipe.text_encoder.config.to_json_string().encode()
...     yield "text_encoder/model.safetensors", safetensors.torch.save(pipe.text_encoder.state_dict())
...     # ... add more entries here

>>> export_entries_as_dduf(dduf_path="stable-diffusion-v1-4.dduf", entries=as_entries(pipe))
```

#### huggingface_hub.export_folder_as_dduf[[huggingface_hub.export_folder_as_dduf]]

```python
huggingface_hub.export_folder_as_dduf(dduf_path: str | os.PathLike, folder_path: str | os.PathLike)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_dduf.py#L249)

**المعاملات:**

dduf_path (`str` أو `os.PathLike`) : المسار إلى ملف DDUF الذي سيتم كتابته.

folder_path (`str` أو `os.PathLike`) : المسار إلى المجلد الذي يحتوي على نموذج الانتشار.

تصدير مجلد كملف DDUF.

Aيستخدم [export_entries_as_dduf()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.export_entries_as_dduf) في الخلفية.

مثال:
```python
>>> from huggingface_hub import export_folder_as_dduf
>>> export_folder_as_dduf(dduf_path="FLUX.1-dev.dduf", folder_path="path/to/FLUX.1-dev")
```

#### huggingface_hub.read_dduf_file[[huggingface_hub.read_dduf_file]]

```python
huggingface_hub.read_dduf_file(dduf_path: os.PathLike | str)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_dduf.py#L91)

**المعاملات:**

dduf_path (`str` أو `os.PathLike`) : المسار إلى ملف DDUF الذي سيتم قراءته.

**يعيد:** `dict[str, DDUFEntry]`

قاموس من [DDUFEntry](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.DDUFEntry) مفهرس باسم الملف.

**يرفع:** `-`

- - -- `DDUFCorruptedFileError`: إذا كان ملف DDUF تالفًا (أي لا يتبع تنسيق DDUF).

اقرأ ملف DDUF وأعدّ قاموسًا من الإدخالات.

يتم قراءة البيانات الوصفية فقط، دون تحميل البيانات في الذاكرة.

مثال:
```python
>>> import json
>>> import safetensors.torch
>>> from huggingface_hub import read_dduf_file

# Read DDUF metadata
>>> dduf_entries = read_dduf_file("FLUX.1-dev.dduf")

# Returns a mapping filename <> DDUFEntry
>>> dduf_entries["model_index.json"]
DDUFEntry(filename='model_index.json', offset=66, length=587)

# Load model index as JSON
>>> json.loads(dduf_entries["model_index.json"].read_text())
{'_class_name': 'FluxPipeline', '_diffusers_version': '0.32.0.dev0', '_name_or_path': 'black-forest-labs/FLUX.1-dev', ...

# Load VAE weights using safetensors
>>> with dduf_entries["vae/diffusion_pytorch_model.safetensors"].as_mmap() as mm:
...     state_dict = safetensors.torch.load(mm)
```

#### huggingface_hub.DDUFEntry[[huggingface_hub.DDUFEntry]]

```python
huggingface_hub.DDUFEntry(filename: str, length: int, offset: int, dduf_path: Path)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_dduf.py#L36)

**المعاملات:**

filename (str) : اسم الملف في أرشيف DDUF.

offset (int) : إزاحة الملف داخل أرشيف DDUF.

length (int) : طول الملف في أرشيف DDUF.

dduf_path (str) : المسار إلى أرشيف DDUF (للاستخدام الداخلي).

كائن يمثل إدخال ملف في ملف DDUF.

راجع [read_dduf_file()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.read_dduf_file) لمعرفة كيفية قراءة ملف DDUF.

#### as_mmap[[huggingface_hub.DDUFEntry.as_mmap]]

```python
as_mmap()
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_dduf.py#L58)

افتح الملف كملف مُرمَّز في الذاكرة.

مفيد لتحميل safetensors مباشرة من الملف.

مثال:
```py
>>> import safetensors.torch
>>> with entry.as_mmap() as mm:
...     tensors = safetensors.torch.load(mm)
```

#### read_text[[huggingface_hub.DDUFEntry.read_text]]

```python
read_text(encoding: str = 'utf-8')
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_dduf.py#L75)

اقرأ الملف كنص.

مفيد لعناصر '.txt' و '.json'.

مثال:
```py
>>> import json
>>> index = json.loads(entry.read_text())
```

### الأخطاء[[huggingface_hub.errors.DDUFError]]

#### huggingface_hub.errors.DDUFError[[huggingface_hub.errors.DDUFError]]

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/errors.py#L521)

استثناء أساسي للأخطاء المتعلقة بتنسيق DDUF.

#### huggingface_hub.errors.DDUFCorruptedFileError[[huggingface_hub.errors.DDUFCorruptedFileError]]

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/errors.py#L525)

يُستثنى عند تلف ملف DDUF.

#### huggingface_hub.errors.DDUFExportError[[huggingface_hub.errors.DDUFExportError]]

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/errors.py#L529)

استثناء أساسي للأخطاء أثناء تصدير DDUF.

#### huggingface_hub.errors.DDUFInvalidEntryNameError[[huggingface_hub.errors.DDUFInvalidEntryNameError]]

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/errors.py#L533)

يُستثنى عند عدم صحة اسم العنصر.

## حفظ المتجهات

يأخذ الدليل الرئيسي في وحدة `serialization` كمدخل كائن `nn.Module` من torch ويحفظه على القرص. يتولى هذا الدليل منطق حفظ الموترات المشتركة (انظر [شرح safetensors](https://huggingface.co/docs/safetensors/torch_shared_tensors)) وكذلك منطق تقسيم قاموس الحالة إلى أجزاء، باستخدام [split_torch_state_dict_into_shards()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.split_torch_state_dict_into_shards) في الخلفية. في الوقت الحالي، يُدعم إطار `torch` فقط.

إذا كنت ترغب في حفظ قاموس حالة (e.g. تعيين بين أسماء الطبقات والموترات ذات الصلة) بدلاً من `nn.Module`، يمكنك استخدام [save_torch_state_dict()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.save_torch_state_dict) الذي يوفر نفس الميزات. وهذا مفيد على سبيل المثال إذا كنت تريد تطبيق منطق مخصص على قاموس الحالة قبل حفظه.

### save_torch_model[[huggingface_hub.save_torch_model]]

#### huggingface_hub.save_torch_model[[huggingface_hub.save_torch_model]]

```python
huggingface_hub.save_torch_model(model: torch.nn.Module, save_directory: str | pathlib.Path, filename_pattern: str | None = None, force_contiguous: bool = True, max_shard_size: int | str = '5GB', metadata: dict[str, str] | None = None, safe_serialization: bool = True, is_main_process: bool = True, shared_tensors_to_discard: list[str] | None = None)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L47)

**المعاملات:**

model (`torch.nn.Module`) : النموذج الذي سيتم حفظه على القرص.

save_directory (`str` أو `Path`) : المجلد الذي سيتم حفظ النموذج فيه.

filename_pattern (`str`, *اختياري*) : النمط لتوليد أسماء الملفات التي سيتم حفظ النموذج فيها. يجب أن يكون النمط نصًا يمكن تنسيقه باستخدام `filename_pattern.format(suffix=...)` وأن يحتوي على الكلمة المفتاحية `suffix`. القيمة الافتراضية هي `"model{suffix}.safetensors"` أو `pytorch_model{suffix}.bin` اعتمادًا على معامل `safe_serialization`.

force_contiguous (`boolean`، *اختياري*) : إجبار حفظ state_dict على شكل تينسورات متصلة. لا يؤثر هذا على صحة النموذج، لكنه قد يغيّر الأداء إذا كان تخطيط التينسور قد اختير خصيصًا لهذا السبب. القيمة الافتراضية هي `True`.

max_shard_size (`int` أو `str`، *اختياري*) : الحد الأقصى لحجم كل شريحة، بالبايت. القيمة الافتراضية هي 5 غيغابايت.

metadata (`dict[str, str]`، *اختياري*) : معلومات إضافية تُحفظ مع النموذج. سيتم إضافة بعض البيانات الوصفية لكل متجهات (tensors) مُسقط. لن تكون هذه المعلومات كافية لاستعادة البنية المشتركة بأكملها، لكنها قد تساعد في فهم الأمور.

safe_serialization (`bool`, *اختياري*) : ما إذا كان سيتم الحفظ بصيغة safetensors، وهي السلوك الافتراضي. إذا كان `False`، تُحفظ الشرائح بصيغة pickle. يُوصى بالتسلسل الآمن لأسباب أمنية. الحفظ بصيغة pickle أصبح غير مدعوم وسيُزال في إصدار مستقبلي.

is_main_process (`bool`, *اختياري*) : ما إذا كانت العملية التي تستدعي هذا هي العملية الرئيسية أم لا. مفيد عند التدريب الموزع مثل TPU والحاجة إلى استدعاء هذه الدالة من جميع العمليات. في هذه الحالة، اضبط `is_main_process=True` فقط على العملية الرئيسية لتجنب حالات السباق. القيمة الافتراضية هي True.

shared_tensors_to_discard (`list[str]`، *اختياري*) : قائمة بأسماء المصفوفات التي يجب حذفها عند حفظ المصفوفات المشتركة. إذا لم يتم تقديمها وتم اكتشاف المصفوفات المشتركة، فسيتم حذف الاسم الأول أبجديًا.

يحفظ نموذج torch معيّنًا على القرص، مع معالجة مشاكل التقسيم (sharding) والمُتغيّرات المشتركة (shared tensors).

انظر أيضًا إلى [save_torch_state_dict()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.save_torch_state_dict) لحفظ قاموس الحالة بمرونة أكبر.

لمزيد من المعلومات حول مشاركة الموترات، راجع [هذا الدليل](https://huggingface.co/docs/safetensors/torch_shared_tensors).

يتم تقسيم قاموس حالة النموذج إلى أجزاء بحيث يكون حجم كل جزء أصغر من حجم محدد. تُحفظ الأجزاء في `save_directory` باستخدام `filename_pattern` المحدد. إذا كان النموذج كبيراً جداً بحيث لا يتسع في جزء واحد، يُحفظ ملف فهرس في `save_directory` للإشارة إلى مكان حفظ كل متجه. يستخدم هذا المساعد [split_torch_state_dict_into_shards()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.split_torch_state_dict_into_shards) في الخلفية. إذا كان `safe_serialization` هو `True`، تُحفظ الأجزاء بصيغة safetensors (وهو الافتراضي). وإلا، تُحفظ الأجزاء بصيغة pickle.

قبل حفظ النموذج، يتم تنظيف `save_directory` من أي ملفات شتات سابقة.

> [!WARNING]
> إذا كان أحد تينسورات النموذج أكبر من `max_shard_size`، فسيُحفظ في شريحة مستقلة ستكون حجمها أكبر من `max_shard_size`.

> [!WARNING]
> إذا كان نموذجك من نوع `transformers.PreTrainedModel`، فيجب عليك تمرير `model._tied_weights_keys` كقيمة لـ `shared_tensors_to_discard` للتعامل بشكل صحيح مع حفظ الموترات المشتركة. يضمن ذلك التخلص من الموترات المكررة الصحيحة أثناء الحفظ.

مثال:

```py
>>> from huggingface_hub import save_torch_model
>>> model = ... # A PyTorch model

# Save state dict to "path/to/folder". The model will be split into shards of 5GB each and saved as safetensors.
>>> save_torch_model(model, "path/to/folder")

# Load model back
>>> from huggingface_hub import load_torch_model  # TODO
>>> load_torch_model(model, "path/to/folder")
>>>
```

### save_torch_state_dict[[huggingface_hub.save_torch_state_dict]]

#### huggingface_hub.save_torch_state_dict[[huggingface_hub.save_torch_state_dict]]

```python
huggingface_hub.save_torch_state_dict(state_dict: dict, save_directory: str | pathlib.Path, filename_pattern: str | None = None, force_contiguous: bool = True, max_shard_size: int | str = '5GB', metadata: dict[str, str] | None = None, safe_serialization: bool = True, is_main_process: bool = True, shared_tensors_to_discard: list[str] | None = None)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L141)

**المعاملات:**

state_dict (`dict[str, torch.Tensor]`) : قاموس الحالة الذي سيتم حفظه.

save_directory (`str` أو `Path`) : المجلد الذي سيتم حفظ النموذج فيه.

filename_pattern (`str`, *اختياري*) : النمط لتوليد أسماء الملفات التي سيتم حفظ النموذج فيها. يجب أن يكون النمط نصًا يمكن تنسيقه باستخدام `filename_pattern.format(suffix=...)` وأن يحتوي على الكلمة المفتاحية `suffix`. القيمة الافتراضية هي `"model{suffix}.safetensors"` أو `pytorch_model{suffix}.bin` اعتمادًا على معامل `safe_serialization`.

force_contiguous (`boolean`، *اختياري*) : إجبار حفظ state_dict على شكل تينسورات متصلة. لا يؤثر هذا على صحة النموذج، لكنه قد يغيّر الأداء إذا كان تخطيط التينسور قد اختير خصيصًا لهذا السبب. القيمة الافتراضية هي `True`.

max_shard_size (`int` أو `str`، *اختياري*) : الحد الأقصى لحجم كل شريحة، بالبايت. القيمة الافتراضية هي 5 غيغابايت.

metadata (`dict[str, str]`، *اختياري*) : معلومات إضافية تُحفظ مع النموذج. سيتم إضافة بعض البيانات الوصفية لكل متجهات (tensors) مُسقط. لن تكون هذه المعلومات كافية لاستعادة البنية المشتركة بأكملها، لكنها قد تساعد في فهم الأمور.

safe_serialization (`bool`, *اختياري*) : ما إذا كان سيتم الحفظ بصيغة safetensors، وهي السلوك الافتراضي. إذا كان `False`، تُحفظ الشرائح بصيغة pickle. يُوصى بالتسلسل الآمن لأسباب أمنية. الحفظ بصيغة pickle أصبح غير مدعوم وسيُزال في إصدار مستقبلي.

is_main_process (`bool`, *اختياري*) : ما إذا كانت العملية التي تستدعي هذا هي العملية الرئيسية أم لا. مفيد عند التدريب الموزع مثل TPU والحاجة إلى استدعاء هذه الدالة من جميع العمليات. في هذه الحالة، اضبط `is_main_process=True` فقط على العملية الرئيسية لتجنب حالات السباق. القيمة الافتراضية هي True.

shared_tensors_to_discard (`list[str]`، *اختياري*) : قائمة بأسماء المصفوفات التي يجب حذفها عند حفظ المصفوفات المشتركة. إذا لم يتم تقديمها وتم اكتشاف المصفوفات المشتركة، فسيتم حذف الاسم الأول أبجديًا.

احفظ قاموس حالة النموذج على القرص، مع معالجة مشاكل التجزئة والمُتغيّرات المشتركة.

انظر أيضًا إلى [save_torch_model()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.save_torch_model) لحفظ نموذج PyTorch مباشرة.

لمزيد من المعلومات حول مشاركة الموترات، راجع [هذا الدليل](https://huggingface.co/docs/safetensors/torch_shared_tensors).

يتم تقسيم قاموس حالة النموذج إلى أجزاء بحيث يكون حجم كل جزء أصغر من حجم محدد. تُحفظ الأجزاء في `save_directory` باستخدام `filename_pattern` المحدد. إذا كان النموذج كبيراً جداً بحيث لا يتسع في جزء واحد، يُحفظ ملف فهرس في `save_directory` للإشارة إلى مكان حفظ كل متجه. يستخدم هذا المساعد [split_torch_state_dict_into_shards()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.split_torch_state_dict_into_shards) في الخلفية. إذا كان `safe_serialization` هو `True`، تُحفظ الأجزاء بصيغة safetensors (وهو الافتراضي). وإلا، تُحفظ الأجزاء بصيغة pickle.

قبل حفظ النموذج، يتم تنظيف `save_directory` من أي ملفات شتات سابقة.

> [!WARNING]
> إذا كان أحد تينسورات النموذج أكبر من `max_shard_size`، فسيُحفظ في شريحة مستقلة ستكون حجمها أكبر من `max_shard_size`.

> [!WARNING]
> إذا كان نموذجك من نوع `transformers.PreTrainedModel`، فيجب عليك تمرير `model._tied_weights_keys` كقيمة لـ `shared_tensors_to_discard` للتعامل بشكل صحيح مع حفظ الموترات المشتركة. يضمن ذلك التخلص من الموترات المكررة الصحيحة أثناء الحفظ.

مثال:

```py
>>> from huggingface_hub import save_torch_state_dict
>>> model = ... # A PyTorch model

# Save state dict to "path/to/folder". The model will be split into shards of 5GB each and saved as safetensors.
>>> state_dict = model_to_save.state_dict()
>>> save_torch_state_dict(state_dict, "path/to/folder")
```

يحتوي وحدة `serialization` أيضًا على أدوات مساعدة منخفضة المستوى لتقسيم قاموس الحالة إلى عدة أجزاء، مع إنشاء فهرس مناسب أثناء العملية. هذه الأدوات متاحة لمصفوفات `torch` وهي مصممة بحيث يسهل توسيعها لتشمل أي أطر عمل أخرى للتعلم الآلي.

### split_torch_state_dict_into_shards[[huggingface_hub.split_torch_state_dict_into_shards]]

#### huggingface_hub.split_torch_state_dict_into_shards[[huggingface_hub.split_torch_state_dict_into_shards]]

```python
huggingface_hub.split_torch_state_dict_into_shards(state_dict: dict, filename_pattern: str = 'model{suffix}.safetensors', max_shard_size: int | str = '5GB')
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L302)

**المعاملات:**

state_dict (`dict[str, torch.Tensor]`) : قاموس الحالة الذي سيتم حفظه.

filename_pattern (`str`, *اختياري*) : النمط لتوليد أسماء الملفات التي سيتم حفظ النموذج فيها. يجب أن يكون النمط نصًا يمكن تنسيقه باستخدام `filename_pattern.format(suffix=...)` وأن يحتوي على الكلمة المفتاحية `suffix`. القيمة الافتراضية هي `"model{suffix}.safetensors"`.

max_shard_size (`int` أو `str`، *اختياري*) : الحد الأقصى لحجم كل شريحة، بالبايت. القيمة الافتراضية هي 5 غيغابايت.

**يعيد:** `StateDictSplit`

كائن `StateDictSplit` يحتوي على الشرائح والفهرس لاسترجاعها.

قسّم قاموس حالة النموذج إلى أجزاء بحيث يكون حجم كل جزء أصغر من حجم محدد.

تُحدَّد الشرائح عن طريق التكرار على `state_dict` بترتيب مفاتيحه. لم يُجرَ أي تحسين لجعل كل شريحة قريبة قدر الإمكان من الحد الأقصى للحجم المُمرَّر. على سبيل المثال، إذا كان الحد 10 غيغابايت وكان لدينا متجهات بحجم [6 غيغابايت، 6 غيغابايت، 2 غيغابايت، 6 غيغابايت، 2 غيغابايت، 2 غيغابايت] فستُقسَّم إلى [6 غيغابايت]، [6+2 غيغابايت]، [6+2+2 غيغابايت] وليس [6+2+2 غيغابايت]، [6+2 غيغابايت]، [6 غيغابايت].

> [!TIP]
> لحفظ قاموس حالة النموذج على القرص، راجع [save_torch_state_dict()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.save_torch_state_dict). يستخدم هذا الدوال المساعدة `split_torch_state_dict_into_shards` في الخلفية.

> [!WARNING]
> إذا كان أحد تينسورات النموذج أكبر من `max_shard_size`، فسيُحفظ في شريحة مستقلة ستكون حجمها أكبر من `max_shard_size`.

مثال:
```py
>>> import json
>>> import os
>>> from safetensors.torch import save_file as safe_save_file
>>> from huggingface_hub import split_torch_state_dict_into_shards

>>> def save_state_dict(state_dict: dict[str, torch.Tensor], save_directory: str):
...     state_dict_split = split_torch_state_dict_into_shards(state_dict)
...     for filename, tensors in state_dict_split.filename_to_tensors.items():
...         shard = {tensor: state_dict[tensor] for tensor in tensors}
...         safe_save_file(
...             shard,
...             os.path.join(save_directory, filename),
...             metadata={"format": "pt"},
...         )
...     if state_dict_split.is_sharded:
...         index = {
...             "metadata": state_dict_split.metadata,
...             "weight_map": state_dict_split.tensor_to_filename,
...         }
...         with open(os.path.join(save_directory, "model.safetensors.index.json"), "w") as f:
...             f.write(json.dumps(index, indent=2))
```

### split_state_dict_into_shards_factory[[huggingface_hub.split_state_dict_into_shards_factory]]

هذا هو المصنع الأساسي الذي تُشتق منه كل أداة مساعدة خاصة بإطار عمل. عملياً، لا يُتوقع منك استخدام هذا المصنع مباشرةً إلا إذا كنت بحاجة إلى تكييفه مع إطار عمل غير مدعوم بعد. في حال كان ذلك هو الحال، يرجى إعلامنا من خلال [فتح مشكلة جديدة](https://github.com/huggingface/huggingface_hub/issues/new) في مستودع `huggingface_hub`.

#### huggingface_hub.split_state_dict_into_shards_factory[[huggingface_hub.split_state_dict_into_shards_factory]]

```python
huggingface_hub.split_state_dict_into_shards_factory(state_dict: dict, get_storage_size: Callable, filename_pattern: str, get_storage_id: Callable = <function <lambda> at 0x7f9673968670>, max_shard_size: int | str = '5GB')
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_base.py#L50)

**المعاملات:**

state_dict (`dict[str, Tensor]`) : قاموس الحالة الذي سيتم حفظه.

get_storage_size (`Callable[[Tensor], int]`) : دالة تُرجع حجم المصفوفة عند حفظها على القرص بالبايت.

get_storage_id (`Callable[[Tensor], Optional[Any]]`، *اختياري*) : دالة تُرجع معرّفًا فريدًا لتخزين الموتر. يمكن لموترات مختلفة متعددة أن تتشارك نفس التخزين الأساسي. يُضمن أن يكون هذا المعرّف فريدًا وثابتًا لتخزين هذا الموتر طوال فترة حياته. قد يكون لمخزني موترات ذات فترات حياة غير متداخلة نفس المعرّف.

filename_pattern (`str`, *اختياري*) : النمط لتوليد أسماء الملفات التي سيتم حفظ النموذج فيها. يجب أن يكون النمط نصًا يمكن تنسيقه باستخدام `filename_pattern.format(suffix=...)` وأن يحتوي على الكلمة المفتاحية `suffix`

max_shard_size (`int` أو `str`، *اختياري*) : الحد الأقصى لحجم كل شريحة، بالبايت. القيمة الافتراضية هي 5 غيغابايت.

**يعيد:** `StateDictSplit`

كائن `StateDictSplit` يحتوي على الشرائح والفهرس لاسترجاعها.

قسّم قاموس حالة النموذج إلى أجزاء بحيث يكون حجم كل جزء أصغر من حجم محدد.

تُحدَّد الشرائح عن طريق التكرار على `state_dict` بترتيب مفاتيحه. لم يُجرَ أي تحسين لجعل كل شريحة قريبة قدر الإمكان من الحد الأقصى للحجم المُمرَّر. على سبيل المثال، إذا كان الحد 10 غيغابايت وكان لدينا متجهات بحجم [6 غيغابايت، 6 غيغابايت، 2 غيغابايت، 6 غيغابايت، 2 غيغابايت، 2 غيغابايت] فستُقسَّم إلى [6 غيغابايت]، [6+2 غيغابايت]، [6+2+2 غيغابايت] وليس [6+2+2 غيغابايت]، [6+2 غيغابايت]، [6 غيغابايت].

> [!WARNING]
> إذا كان أحد تينسورات النموذج أكبر من `max_shard_size`، فسيُحفظ في شريحة مستقلة ستكون حجمها أكبر من `max_shard_size`.

## تحميل المتجهات

تدعم أدوات التحميل كلا من نقاط التفتيش أحادية الملف ومقسمة الأجزاء، سواء كانت بصيغة safetensors أو pickle. يستقبل [load_torch_model()](/docs/huggingface_hub/v2.4.0/ar/package_reference/serialization#huggingface_hub.load_torch_model) كمدخلات كائن `nn.Module` ومسار نقطة التفتيش (سواء كان ملفاً واحداً أو مجلداً)، ثم يحمّل الأوزان إلى النموذج.

> [!WARNING]
> تتخذ كلا الدالتين المساعدة افتراضيًا `safe=True`، مما يعني أن نقطة الحفظ تُفكّ ترميزها دائمًا باستخدام مُحمّل safetensors — بغض النظر عن اسم الملف. يتطلب تحميل نقطة حفظ pickle الموافقة صراحةً، لأن فكّ ترميز pickle ينفّذ أكوادًا اعتباطية عند وقت التحميل:
> ```py
> >>> from huggingface_hub import load_state_dict_from_file, load_torch_model
>
> # Raises: the file is not safetensors
> >>> load_state_dict_from_file("path/to/pytorch_model.bin")
> >>> load_torch_model(model, "path/to/pytorch_model.bin")
>
> # Explicit opt-in
> >>> load_state_dict_from_file("path/to/pytorch_model.bin", safe=False)
> >>> load_torch_model(model, "path/to/pytorch_model.bin", safe=False)
> ```
> يُعيَّن مسار pickle افتراضيًا إلى `weights_only=True` أيضًا، أي مُفكّك الترميز المقيد في torch. يحتاج نقطة تفتيش تحتوي على كائنات غير متجهات (حالات المُحسّن، نموذج كامل، ...) إلى `weights_only=False` بالإضافة إلى `safe=False`.

### load_torch_model[[huggingface_hub.load_torch_model]]

#### huggingface_hub.load_torch_model[[huggingface_hub.load_torch_model]]

```python
huggingface_hub.load_torch_model(model: torch.nn.Module, checkpoint_path: str | os.PathLike, strict: bool = False, safe: bool = True, weights_only: bool = True, map_location: typing.Union[str, ForwardRef('torch.device'), NoneType] = None, mmap: bool = False, filename_pattern: str | None = None)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L375)

**المعاملات:**

model (`torch.nn.Module`) : النموذج الذي سيتم تحميل نقطة التفتيش فيه.

checkpoint_path (`str` أو `os.PathLike`) : المسار إلى ملف نقطة التفتيش أو المجلد الذي يحتوي على نقاط التفتيش.

strict (`bool`، *اختياري*، القيمة الافتراضية `False`) : ما إذا كان سيتم فرض المطابقة الصارمة بين المفاتيح في قاموس حالة النموذج والمفاتيح في نقطة الحفظ. وكما هو الحال مع `torch.nn.Module.load_state_dict` ، يتم إجراء الفحص بعد تحميل نقطة الحفظ، لذا قد يكون النموذج قد تم تحديثه جزئيًا عند حدوث الخطأ.

safe (`bool`، *اختياري*، القيمة الافتراضية `True`) : إذا كان `safe` هو True، فسيتم تحميل ملفات safetensors. إذا كان `safe` هو False، فستحاول الدالة أولاً تحميل ملفات safetensors إذا كانت متاحة، وإلا فستلجأ إلى تحميل ملفات pickle. يُرفض `filename_pattern` الذي لا يصف ملفات safetensors عندما يكون `safe=True`.

weights_only (`bool`، *اختياري*، القيمة الافتراضية `True`) : إذا كانت القيمة True، يتم تحميل أوزان النموذج فقط دون حالات المُحسِّن (optimizer) وبيانات الوصف الأخرى، باستخدام أداة فك الترميز المقيدة (restricted unpickler) الخاصة بـ torch. اضبطها على False للسماح بأهداف بايثون (Python objects) عشوائية في نقطة الحفظ (pickle checkpoint) (يؤدي هذا إلى تنفيذ أكواد عشوائية عند وقت التحميل). لا يؤثر هذا الإعداد على PyTorch < 1.13، الذي لا يحتوي على أداة فك ترميز مقيدة ويفك الترميز دائمًا دون قيود.

map_location (`str` أو `torch.device`، *اختياري*) : كائن `torch.device` أو نص أو قاموس يحدد كيفية إعادة تعيين مواقع التخزين. يشير إلى الموقع الذي يجب تحميل جميع المتجهات (tensors) فيه.

mmap (`bool`، *اختياري*، القيمة الافتراضية `False`) : ما إذا كان سيتم استخدام تحميل الملفات عبر خرائط الذاكرة. يمكن أن يحسّن خرائط الذاكرة أداء التحميل للنماذج الكبيرة في PyTorch >= 2.1.0 مع نقاط التفتيش القائمة على zipfile.

filename_pattern (`str`, *اختياري*) : النمط للبحث عن ملف الفهرس. يجب أن يكون النمط نصًا يمكن تنسيقه باستخدام `filename_pattern.format(suffix=...)` وأن يحتوي على الكلمة المفتاحية `suffix`. القيمة الافتراضية هي `"model{suffix}.safetensors"`.

**يعيد:** `NamedTuple`

سجل مُسمّى (named tuple) يحتوي على حقول `missing_keys` و`unexpected_keys`.
- `missing_keys` هو قائمة من نوع str تحتوي على المفاتيح المفقودة، أي المفاتيح الموجودة في النموذج لكنها غير موجودة في نقطة الحفظ.
- `unexpected_keys` هو قائمة من نوع str تحتوي على المفاتيح غير المتوقعة، أي المفاتيح الموجودة في نقطة الحفظ (checkpoint) لكنها غير موجودة في النموذج.

**يرفع:** ``FileNotFoundError`` أو ``ImportError`` أو ``ValueError``

- [`FileNotFoundError`](https://docs.python.org/3/library/exceptions.html#FileNotFoundError) -- إذا لم يكن ملف نقطة التفتيش أو المجلد موجودًا.
- [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) -- إذا لم يكن حزمة safetensors أو torch مثبتة عند محاولة تحميل ملف .safetensors أو نقطة تحقق PyTorch على التوالي.
- [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) -- إذا تعذّر تحديد صيغة نقطة التفتيش.

تحميل نقطة تحقق إلى نموذج، مع التعامل مع نقاط التحقق المجزأة وغير المجزأة.

مثال:
```python
>>> from huggingface_hub import load_torch_model
>>> model = ... # A PyTorch model
>>> load_torch_model(model, "path/to/checkpoint")
```

### load_state_dict_from_file[[huggingface_hub.load_state_dict_from_file]]

#### huggingface_hub.load_state_dict_from_file[[huggingface_hub.load_state_dict_from_file]]

```python
huggingface_hub.load_state_dict_from_file(checkpoint_file: str | os.PathLike, map_location: typing.Union[str, ForwardRef('torch.device'), NoneType] = None, weights_only: bool = True, mmap: bool = False, safe: bool = True)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L633)

**المعاملات:**

checkpoint_file (`str` أو `os.PathLike`) : المسار إلى ملف نقطة التفتيش (checkpoint) الذي سيتم تحميله. يمكن أن يكون ملف نقطة تفتيش بصيغة safetensors أو pickle (`.bin`).

map_location (`str` أو `torch.device`، *اختياري*) : كائن `torch.device` أو نص أو قاموس يحدد كيفية إعادة تعيين مواقع التخزين. يشير إلى الموقع الذي يجب تحميل جميع المتجهات (tensors) فيه.

weights_only (`bool`، *اختياري*، القيمة الافتراضية `True`) : إذا كانت القيمة True، يتم تحميل أوزان النموذج فقط دون حالات المُحسِّن (optimizer) وبيانات الوصف الأخرى، باستخدام أداة unpickler المقيدة في torch. اضبطها على False للسماح بأهداف Python اعتباطية في نقطة التحقق (checkpoint) من نوع pickle (هذا يؤدي إلى تنفيذ أكواد اعتباطية عند وقت التحميل). لا يؤثر هذا الإعداد عند تحميل ملفات safetensors، ولا على إصدارات PyTorch < 1.13 التي لا تحتوي على أداة unpickler مقيدة — حيث تقوم تلك الإصدارات دائمًا بعمل unpickle دون قيود مع تسجيل تحذير.

mmap (`bool`، *اختياري*، القيمة الافتراضية `False`) : ما إذا كان سيتم استخدام تحميل الملفات عبر خرائط الذاكرة. يمكن أن يحسّن خرائط الذاكرة أداء التحميل للنماذج الكبيرة في PyTorch >= 2.1.0 مع نقاط التفتيش القائمة على zipfile. لا يؤثر عند تحميل ملفات safetensors، لأن مكتبة `safetensors` تستخدم خرائط الذاكرة افتراضيًا.

safe (`bool`، *اختياري*، القيمة الافتراضية `True`) : إذا كانت القيمة True، يتم تحميل نقطة التفتيش دائمًا بصيغة safetensors، بغض النظر عن اسمها. أي صيغة أخرى (مثل ملف pickle `.bin`) تثير `ValueError` بدلاً من فك التسلسل: فمحطات التفتيش من نوع pickle يمكن أن تنفذ أكوادًا اعتباطية عند التحميل. إذا كانت القيمة False، يتم تحميل الملف بصيغة safetensors إذا كان اسمه يشير إلى ذلك، وإلا يتم تحميله باستخدام `torch.load`.

**يعيد:** `Union[dict[str, "torch.Tensor"], Any]`

نقطة التفتيش المحمّلة.
- لملفات safetensors: تُرجع دائمًا قاموسًا يربط أسماء المعاملات بالمُتجهات (tensors).
- لملفات pickle: يعيد أي كائن Python تم تجميده (غالبًا ما يكون state dict، لكنه قد يكون نموذجًا كاملًا، أو حالة المُحسِّن optimizer، أو أي كائن Python آخر).

**يستثني:** ``FileNotFoundError`` أو ``ImportError`` أو ``OSError`` أو ``ValueError``

- [`FileNotFoundError`](https://docs.python.org/3/library/exceptions.html#FileNotFoundError) -- إذا لم يكن ملف نقطة التفتيش موجودًا.
- [`ImportError`](https://docs.python.org/3/library/exceptions.html#ImportError) -- إذا لم يكن حزمة safetensors أو torch مثبتة عند محاولة تحميل ملف .safetensors أو نقطة تحقق PyTorch على التوالي.
- [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) -- إذا كان تنسيق ملف نقطة الحفظ غير صالح أو إذا لم يتم تنزيل ملفات git-lfs بشكل صحيح.
- [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) -- إذا كان مسار ملف نقطة الحفظ فارغًا أو غير صالح، أو إذا تعذّر تجريد التسلسل له كـ safetensors بينما `safe=True` (مرّر `safe=False` للسماح بنقاط حفظ pickle).

يحمّل ملف نقطة التفتيش، مع التعامل مع صيغ نقاط التفتيش الخاصة بـ safetensors و pickle.

مثال:
```python
>>> from huggingface_hub import load_state_dict_from_file

# Load a safetensors checkpoint (safe by default)
>>> state_dict = load_state_dict_from_file("path/to/model.safetensors", safe=True)
>>> model.load_state_dict(state_dict)

# Load a pickle checkpoint. `safe=False` is required: pickle files can execute arbitrary code.
>>> state_dict = load_state_dict_from_file("path/to/model.bin", safe=False, map_location="cpu")
>>> model.load_state_dict(state_dict)
```

## أدوات مساعدة للتّنسورات

### get_torch_storage_id[[huggingface_hub.get_torch_storage_id]]

#### huggingface_hub.get_torch_storage_id[[huggingface_hub.get_torch_storage_id]]

```python
huggingface_hub.get_torch_storage_id(tensor: torch.Tensor)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L878)

إرجاع معرّف فريد لتخزين المصفوفة.

يمكن أن تتشارك عدة متجهات (tensors) مختلفة في نفس التخزين الأساسي. يُضمن أن يكون هذا المعرّف فريدًا وثابتًا لتخزين هذا المتجه طوال فترة حياته. قد يكون لتخزينَي متجهين لا تتداخل فترتا حياتهما نفس المعرّف. في حالة المتجهات الوهمية (meta tensors)، نعيد None لأننا لا نستطيع تحديد ما إذا كانت تتشارك في نفس التخزين.

مأخوذة من https://github.com/huggingface/transformers/blob/1ecf5f7c982d761b4daaa96719d162c324187c64/src/transformers/pytorch_utils.py#L278.

### get_torch_storage_size[[huggingface_hub.get_torch_storage_size]]

#### huggingface_hub.get_torch_storage_size[[huggingface_hub.get_torch_storage_size]]

```python
huggingface_hub.get_torch_storage_size(tensor: torch.Tensor)
```

[المصدر](https://github.com/huggingface/huggingface_hub/blob/v2.4.0/src/huggingface_hub/serialization/_torch.py#L895)

مأخوذة من https://github.com/huggingface/safetensors/blob/08db34094e9e59e2f9218f2df133b7b4aaff5a99/bindings/python/py_src/safetensors/torch.py#L31C1-L41C59

