Buckets:

mishig's picture
|
download
raw
33.2 kB

モデル

🤗 Diffusers は、人気のあるアルゴリズム向けの事前学習済みモデルと、カスタムの拡散システムを構築するためのモジュールを提供します。モデルの主な機能は、分布 pθ(xt−1∣xt)p_{\theta}(x_{t-1}|x_{t}) でモデル化されるように、入力サンプルのノイズを除去することです。

すべてのモデルは、ModelMixinクラスをベースとして構築されています。このクラスはtorch.nn.Moduleであり、ローカルおよびHugging Face Hubからのモデルの保存と読み込みに関する基本的な機能を提供します。

ModelMixin[[diffusers.ModelMixin]]

diffusers.ModelMixin[[diffusers.ModelMixin]]

diffusers.ModelMixin()

ソース

すべてのモデルの基底クラス。

ModelMixin は、モデル設定の保存を管理し、モデルの読み込み、ダウンロード、保存を行うメソッドを提供します。

  • config_name (str) -- save_pretrained()を呼び出す際にモデルを保存するファイル名。

compile_repeated_blocks[[diffusers.ModelMixin.compile_repeated_blocks]]

compile_repeated_blocks(*args, **kwargs)

ソース

モデル全体をコンパイルするのではなく、頻繁に繰り返し実行されるサブモジュール(Transformer層など)のみをコンパイルします。この手法はリージョナルコンパイル(PyTorchのレシピ https://docs.pytorch.org/tutorials/recipes/regional_compilation.html を参照)とも呼ばれ、torch.compile全体を適用した場合に期待されるランタイムの高速化を維持しつつ、エンドツーエンドのコンパイル時間を大幅に短縮できます。

コンパイル対象のサブモジュールのセットは、モデル定義内の _repeated_blocks 属性の存在によって特定されます。この属性をモデルのサブクラスに、クラス名(文字列)のリスト/タプルとして定義してください。クラス名が一致するすべてのモジュールがコンパイルされます。

検出された各マッチングするサブモジュールは、submodule.compile(*args, **kwargs)を呼び出すことでコンパイルされます。compile_repeated_blocksに指定した位置引数やキーワード引数は、すべてそのままtorch.compileに転送されます。

cuda[[diffusers.ModelMixin.cuda]]

cuda(*args, **kwargs)

ドット区切りパス(例: torch.float32)に対するモック値: 属性アクセスのチェーン、呼び出しはパススルーデコレータとして動作し、repr はドット区切りパスを返し、ベースクラスとして使用するとプレーンな type ベースに置き換えられます(PEP 560 の __mro_entries__)。これにより、実際のサブクラスは通常のメタクラスを保持し、inspect.signature はモックのものではなく実際の __init__ を読み取ります。

dequantize[[diffusers.ModelMixin.dequantize]]

dequantize()

ソース

量子化手法によって量子化されている場合、デクォンタイズをサポートしている場合はモデルをデクォンタイズする可能性があります。

disable_gradient_checkpointing[[diffusers.ModelMixin.disable_gradient_checkpointing]]

disable_gradient_checkpointing()

ソース

現在のモデルの勾配チェックポイント機能を無効にします(他のフレームワークでは、activation checkpointingまたはcheckpoint activationsと呼ばれる場合があります)。

disable_npu_flash_attention[[diffusers.ModelMixin.disable_npu_flash_attention]]

disable_npu_flash_attention()

ソース

torch_npu から NPU フラッシュアテンションを無効にする

disable_xformers_memory_efficient_attention[[diffusers.ModelMixin.disable_xformers_memory_efficient_attention]]

disable_xformers_memory_efficient_attention()

ソース

xFormersからのメモリ効率の高いアテンションを無効にします。

disable_xla_flash_attention[[diffusers.ModelMixin.disable_xla_flash_attention]]

disable_xla_flash_attention()

ソース

torch_xla における flash attention pallals カーネルを無効にします。

enable_gradient_checkpointing[[diffusers.ModelMixin.enable_gradient_checkpointing]]

enable_gradient_checkpointing(gradient_checkpointing_func: typing.Optional[typing.Callable] = None)

ソース

パラメータ:

gradient_checkpointing_func (Callable, 省略可) : グラデーションチェックポイントに使用する関数です。None の場合、PyTorch のデフォルトのチェックポイント関数 (torch.utils.checkpoint.checkpoint) が使用されます。

現在のモデルに対して勾配チェックポイントを有効にします(他のフレームワークでは、activation checkpointingまたはcheckpoint activationsと呼ばれる場合があります)。

enable_group_offload[[diffusers.ModelMixin.enable_group_offload]]

enable_group_offload(onload_device: device, offload_device: device = torch.device(), offload_type: str = 'block_level', num_blocks_per_group: int | None = None, non_blocking: bool = False, use_stream: bool = False, record_stream: bool = False, low_cpu_mem_usage = False, offload_to_disk_path: str | None = None, block_modules: str | None = None, exclude_kwargs: str | None = None)

ソース

現在のモデルに対してグループオフロードを有効にします。

詳細については、apply_group_offloading()を参照してください。

例:

>>> from diffusers import CogVideoXTransformer3DModel

>>> transformer = CogVideoXTransformer3DModel.from_pretrained(
...     "THUDM/CogVideoX-5b", subfolder="transformer", torch_dtype=torch.bfloat16
... )

>>> transformer.enable_group_offload(
...     onload_device=torch.device("cuda"),
...     offload_device=torch.device("cpu"),
...     offload_type="leaf_level",
...     use_stream=True,
... )

enable_layerwise_casting[[diffusers.ModelMixin.enable_layerwise_casting]]

enable_layerwise_casting(storage_dtype: dtype = torch.float8_e4m3fn, compute_dtype: typing.Optional[torch.dtype] = None, skip_modules_pattern: tuple[str, ...] | None = None, skip_modules_classes: tuple[typing.Type[torch.nn.Module], ...] | None = None, non_blocking: bool = False)

ソース

パラメータ:

storage_dtype (torch.dtype) : モデルを保存するためにキャストすべき dtype。

compute_dtype (torch.dtype) : フォワードパス中にモデルの重みをキャストする対象の dtype。

skip_modules_pattern (tuple[str, ...]、省略可) : レイヤワイズキャスト処理中にスキップするモジュールの名前を一致させるためのパターンリスト。Noneに設定すると、モジュールの特定の内部レイヤーや PEFT レイヤーを無視するために、デフォルトのスキップパターンが使用されます。

skip_modules_classes (tuple[Type[torch.nn.Module], ...]、任意) : レイヤワイズキャスト処理中にスキップするモジュールクラスのリスト。

non_blocking (bool、任意、デフォルトはFalse) : Trueの場合、重みのキャスト操作はブロッキングなしで実行されます。

現在のモデルに対してレイヤー単位のキャストを有効にします。

Layerwise castingは、モデルの重みを低精度のdtypeにキャストして保存し、計算時にはオンザフライで高精度のdtypeにアップキャストする技術です。このプロセスにより、モデルの重みによるメモリフットプリントを大幅に削減できますが、出力の品質が若干低下する可能性があります。品質の低下の多くは無視できるレベルであり、主に正規化層やモジュレーション層での重みキャストに起因します。

デフォルトでは、diffusers のほとんどのモデルは _skip_layerwise_casting_patterns 属性を設定し、パッチ埋め込み、位置埋め込み、正規化レイヤーを無視します。これは、これらのレイヤーが品質に対して精度が重要である可能性が高いためです。この動作を変更したい場合は、_skip_layerwise_casting_patterns 属性を None に設定するか、apply_layerwise_casting() をカスタム引数で呼び出してください。

例:

enable_layerwise_casting()を使用する場合:

>>> from diffusers import CogVideoXTransformer3DModel

>>> transformer = CogVideoXTransformer3DModel.from_pretrained(
...     "THUDM/CogVideoX-5b", subfolder="transformer", torch_dtype=torch.bfloat16
... )

>>> # Enable layerwise casting via the model, which ignores certain modules by default
>>> transformer.enable_layerwise_casting(storage_dtype=torch.float8_e4m3fn, compute_dtype=torch.bfloat16)

enable_npu_flash_attention[[diffusers.ModelMixin.enable_npu_flash_attention]]

enable_npu_flash_attention()

ソース

torch_npu から NPU フラッシュアテンションを有効にする

enable_xformers_memory_efficient_attention[[diffusers.ModelMixin.enable_xformers_memory_efficient_attention]]

enable_xformers_memory_efficient_attention(attention_op: typing.Optional[typing.Callable] = None)

ソース

パラメータ:

attention_op (Callable、任意) : xFormers の memory_efficient_attention() 関数の op 引数として使用するために、デフォルトの None オペレーターをオーバーライドします。

xFormersからメモリ効率の高いアテンションを有効にします。

このオプションを有効にすると、GPU メモリ使用量の低下と、推論時の処理速度の向上が期待できます。ただし、学習時の処理速度の向上は保証されません。

> ⚠️ メモリ効率の良いアテンションとスライスされたアテンションの両方が有効な場合、メモリ効率 attention は > に優先します。

例:

>>> import torch
>>> from diffusers import UNet2DConditionModel
>>> from xformers.ops import MemoryEfficientAttentionFlashAttentionOp

>>> model = UNet2DConditionModel.from_pretrained(
...     "stabilityai/stable-diffusion-2-1", subfolder="unet", torch_dtype=torch.float16
... )
>>> model = model.to("cuda")
>>> model.enable_xformers_memory_efficient_attention(attention_op=MemoryEfficientAttentionFlashAttentionOp)

enable_xla_flash_attention[[diffusers.ModelMixin.enable_xla_flash_attention]]

enable_xla_flash_attention(partition_spec: typing.Optional[typing.Callable] = None, **kwargs)

ソース

torch_xla 用の flash attention pallals カーネルを有効にします。

from_pretrained[[diffusers.ModelMixin.from_pretrained]]

from_pretrained(pretrained_model_name_or_path: str | os.PathLike | None, **kwargs)

ソース

パラメータ:

pretrained_model_name_or_path (str または os.PathLike、省略可) : 以下のいずれかです: - Hub にホストされている事前学習済みモデルの model id(例: google/ddpm-celebahq-256)を表す文字列。 - save_pretrained() で保存されたモデルの重みを含む ディレクトリ(例: ./my_model_directory)へのパス。

cache_dir (str | os.PathLike、任意) : 標準のキャッシュを使用しない場合、ダウンロードした事前学習済みモデルの構成がキャッシュされるディレクトリのパス。

dtype (torch.dtype、任意) : デフォルトの torch.dtype を上書きし、別の dtype でモデルを読み込みます。

force_download (bool, 任意, デフォルトは False) : モデルの重みと設定ファイルの(再)ダウンロードを強制するかどうか。キャッシュされたバージョンが存在する場合でも、それを上書きします。

proxies (dict[str, str]、省略可) : プロトコルまたはエンドポイントごとに使用するプロキシサーバーの辞書です。例えば、{'http': 'foo.bar:3128', 'http://hostname': 'foo.bar:4012'} のように指定します。これらのプロキシは、各リクエストで使用されます。

output_loading_info (bool、任意、デフォルトはFalse) : 欠落キー、予期しないキー、エラーメッセージを含む辞列も返すかどうかを指定します。

local_files_only(bool、任意、デフォルトはFalse) : ローカルに保存されたモデルの重みと設定ファイルのみを読み込むかどうかを指定します。Trueに設定すると、モデルは Hub からダウンロードされません。

token (str または bool、省略可能) : リモートファイルの HTTP ベアラ認証に使用するトークン。True の場合、diffusers-cli login で生成されたトークン(~/.huggingface に保存)が使用されます。

revision (str、任意、デフォルトは"main") : 使用する特定のモデルバージョンです。ブランチ名、タグ名、コミット ID、または Git で許可されている任意の識別子を使用できます。

subfolder (str、任意、デフォルトは "") : Hub またはローカル上のより大きなモデルリポジトリ内での、モデルファイルのサブフォルダの場所。

mirror (str, 任意) : 中国でモデルをダウンロードする場合、アクセシビリティの問題を解決するためのミラーソースを指定します。ソースの鮮度や安全性を保証するものではなく、詳細についてはミラーサイトをご参照ください。

device_map (int | str | torch.device または dict[str, int | str | torch.device]、省略可) : 各サブモジュールをどのデバイスに配置するかを指定するマップです。すべてのパラメータ/バッファ名に対して定義する必要はありません。特定のモジュール名がマップに含まれている場合、そのモジュールのすべてのサブモジュールは同じデバイスに送信されます。デフォルトは None で、モデルは CPU にロードされます。 例: py >>> from diffusers import AutoModel >>> import torch >>> # This works. >>> model = AutoModel.from_pretrained( ... "stabilityai/stable-diffusion-xl-base-1.0", subfolder="unet", device_map="cuda" ... ) >>> # This also works (integer accelerator device ID). >>> model = AutoModel.from_pretrained( ... "stabilityai/stable-diffusion-xl-base-1.0", subfolder="unet", device_map=0 ... ) >>> # Specifying a supported offloading strategy like "auto" also works. >>> model = AutoModel.from_pretrained( ... "stabilityai/stable-diffusion-xl-base-1.0", subfolder="unet", device_map="auto" ... ) >>> # Specifying a dictionary as `device_map` also works. >>> model = AutoModel.from_pretrained( ... "stabilityai/stable-diffusion-xl-base-1.0", ... subfolder="unet", ... device_map={"": torch.device("cuda")}, ... ) device_map="auto" を設定すると、🤗 Accelerate が最も最適化された device_map を自動的に計算します。各オプションの詳細については、デバイスマップの設計 を参照してください。より具体的な例については、Diffusers 固有のドキュメント も参照できます。

max_memory (Dict, 省略可) : 最大メモリに対するデバイスの識別子の辞書です。未設定の場合、各 GPU の利用可能な最大メモリと、利用可能な CPU RAM がデフォルトとして使用されます。

offload_folder (str または os.PathLike、省略可能) : device_map に "disk" という値が含まれる場合の、重みのオフロード先パス。

offload_state_dict (bool, 任意) : Trueの場合、CPU state dictの重みとチェックポイントの最大のシャードの合計がCPU RAMに収まらない場合に、CPU RAMの枯渇を避けるため、CPU state dictを一時的にハードドライブにオフロードします。ディスクオフロードが存在する場合、デフォルトはTrueです。

low_cpu_mem_usage (bool、任意、torch のバージョンが 1.9.0 以上ならデフォルトは True、それ未満なら False) : 重みの初期化を行わず、事前学習済み重みのみを読み込むことでモデルの読み込みを高速化します。また、モデルの読み込み時に CPU メモリ(ピークメモリを含む)をモデルサイズの 1 倍以下に抑えるよう試みます。PyTorch 1.9.0 以上でのみサポートされています。PyTorch の古いバージョンを使用している場合、この引数を True に設定するとエラーが発生します。

variant (str, 任意) : variant ファイル名(例: "fp16" や "ema")から重みをロードします。

use_safetensors (bool, 任意, デフォルトは None) : None に設定されている場合、safetensors の重みが利用可能であり、かつ and safetensors ライブラリがインストールされている場合、それらがダウンロードされます。True に設定されている場合、モデルは safetensors の重みから強制的に読み込まれます。False に設定されている場合、safetensors の重みは読み込まれません。

disable_mmap ('bool', optional, デフォルトは 'False') : Safetensors モデルの読み込み時に mmap を無効にするかどうかを指定します。モデルがネットワークマウントやハードドライブ上にあり、mmap のランダムアクセス(seek)を適切に処理できない可能性がある場合、このオプションを有効にするとパフォーマンスが向上することがあります。

use_flashpack (bool、任意、デフォルトはFalse) : Trueに設定すると、モデルはflashpackの重みから読み込まれます。

flashpack_kwargs(dict[str, Any]、省略可、デフォルトは{}) : flashpack.deserialization.assign_from_fileに渡されるKwargs

事前学習済みモデルの構成から、事前学習済み PyTorch モデルをインスタンス化します。

モデルはデフォルトで評価モードに設定されており、model.eval() が呼び出され、dropout モジュールは無効化されています。モデルを学習するには、model.train() を呼び出して学習モードに戻してください。

> プライベートモデルやゲート付きモデルを使用するには、ログインしてください hf > auth login を使用します。また、ファイアウォールが設定された環境でこの方法を使用するために、特別な "offline-mode" を有効にすることもできます。

例:

from diffusers import UNet2DConditionModel

unet = UNet2DConditionModel.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", subfolder="unet")

以下のエラーメッセージが表示された場合、下流タスク用に重みをファインチューニングする必要があります。

Some weights of UNet2DConditionModel were not initialized from the model checkpoint at stable-diffusion-v1-5/stable-diffusion-v1-5 and are newly initialized because the shapes did not match:
- conv_in.weight: found shape torch.Size([320, 4, 3, 3]) in the checkpoint and torch.Size([320, 9, 3, 3]) in the model instantiated
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.

get_memory_footprint[[diffusers.ModelMixin.get_memory_footprint]]

get_memory_footprint(return_buffers = True)

ソース

パラメータ:

return_buffers (bool、任意、デフォルトはTrue) : メモリフットプリントの計算において、バッファテンソルのサイズを返すかどうかを指定します。バッファとは、勾配を必要とせず、パラメータとして登録されていないテンソルです。例えば、バッチノルム層の平均値や標準偏差などが該当します。詳細は以下を参照してください: https://discuss.pytorch.org/t/what-pytorch-means-by-buffers/120266/2

モデルのメモリフットプリントを取得します。現在のモデルのメモリフットプリントをバイト単位で返します。現在のモデルのメモリフットプリントをベンチマークし、テストを設計する際に便利です。PyTorch のディスカッションから着想を得た解決策です: https://discuss.pytorch.org/t/gpu-memory-that-model-uses/56822/2

num_parameters[[diffusers.ModelMixin.num_parameters]]

num_parameters(only_trainable: bool = False, exclude_embeddings: bool = False)

ソース

パラメータ:

only_trainable (bool, 任意, デフォルトは False) : 学習可能なパラメータの数のみを返すかどうか。

exclude_embeddings (bool, 任意, デフォルトは False) : 埋め込みパラメータ以外のパラメータ数のみを返すかどうか。

戻り値: int

パラメータの数。

モジュール内の(学習可能な、または埋め込み以外の)パラメータ数を取得します。

例:

from diffusers import UNet2DConditionModel

model_id = "stable-diffusion-v1-5/stable-diffusion-v1-5"
unet = UNet2DConditionModel.from_pretrained(model_id, subfolder="unet")
unet.num_parameters(only_trainable=True)
859520964

reset_attention_backend[[diffusers.ModelMixin.reset_attention_backend]]

reset_attention_backend()

ソース

モデルのattentionバックエンドをリセットします。以降のforward呼び出しでは、設定されている場合は環境のデフォルト、設定されていない場合はtorchネイティブのscaled dot product attentionが使用されます。

save_pretrained[[diffusers.ModelMixin.save_pretrained]]

save_pretrained(save_directory: str | os.PathLike, is_main_process: bool = True, save_function: typing.Optional[typing.Callable] = None, safe_serialization: bool = True, variant: str | None = None, max_shard_size: int | str = '10GB', push_to_hub: bool = False, use_flashpack: bool = False, **kwargs)

ソース

パラメータ:

save_directory (str または os.PathLike) : モデルとその設定ファイルを保存するディレクトリ。存在しない場合は作成されます。

is_main_process (bool、任意、デフォルトはTrue) : この関数を呼び出したプロセスがメインプロセスかどうかを示します。分散学習時に、すべてのプロセスでこの関数を呼び出す必要がある場合に便利です。この場合、競合状態を避けるために、メインプロセスでのみis_main_process=Trueを設定してください。

save_function (Callable) : 状態辞書を保存するために使用する関数です。分散学習時に torch.save を別のメソッドに置き換える必要がある場合に便利です。環境変数 DIFFUSERS_SAVE_MODE で設定できます。

safe_serialization (bool、任意、デフォルトはTrue) : モデルをsafetensorsで保存するか、pickleを用いた従来の PyTorch の方法で保存するかどうかを指定します。

variant (str, 任意) : 指定した場合、重みはpytorch_model.<variant>.binの形式で保存されます。

max_shard_size (int または str、デフォルトは "10GB") : シャーディングされる前のチェックポイントの最大サイズ。シャーディングされたチェックポイントは、それぞれこのサイズ未満になります。文字列で指定する場合は、数字の後に単位("5GB" など)を続ける必要があります。整数で指定する場合は、単位はバイトです。なお、diffusers の最新バージョンへのアップグレードをユーザーに促すため、この上限は一定期間後に引き下げられます(2024年10月から開始)。これは、Hugging Face エコシステム内の異なるライブラリ(transformers や accelerate など)間で、この引数の共通のデフォルトサイズを確立するためのものです。

push_to_hub (bool、任意、デフォルトはFalse) : モデルを保存した後に Hugging Face Hub にプッシュするかどうかを指定します。repo_id でプッシュ先のリポジトリを指定できます(指定しない場合、save_directory の名前があなたのネームスペース内でデフォルトとして使用されます)。

kwargs (dict[str, Any]、省略可) : push_to_hub() メソッドに渡される追加のキーワード引数。

モデルとその設定ファイルをディレクトリに保存し、from_pretrained()クラスメソッドを使って再読み込みできるようにします。

set_attention_backend[[diffusers.ModelMixin.set_attention_backend]]

set_attention_backend(backend: str)

ソース

パラメータ:

backend (str) : 設定するバックエンドの名前。AttentionBackendName で定義されている利用可能なバックエンドのいずれかである必要があります。利用可能なバックエンドは diffusers.attention_dispatch.AttentionBackendName で確認できます。デフォルトでは、torch ネイティブの scaled dot product attention をバックエンドとして使用します。

モデルのattentionバックエンドを設定します。

set_use_npu_flash_attention[[diffusers.ModelMixin.set_use_npu_flash_attention]]

set_use_npu_flash_attention(valid: bool)

ソース

NPU flash attention のスイッチを設定します。

へ[[diffusers.ModelMixin.to]]

to(*args, **kwargs)

ドット区切りパス(例: torch.float32)に対するモック値: 属性アクセスのチェーン、呼び出しはパススルーデコレータとして動作し、repr はドット区切りパスを返し、ベースクラスとして使用するとプレーンな type ベースに置き換えられます(PEP 560 の __mro_entries__)。これにより、実際のサブクラスは通常のメタクラスを保持し、inspect.signature はモックのものではなく実際の __init__ を読み取ります。

PushToHubMixin[[diffusers.utils.PushToHubMixin]]

diffusers.utils.PushToHubMixin[[diffusers.utils.PushToHubMixin]]

diffusers.utils.PushToHubMixin()

ソース

Hugging Face Hub にモデル、スケジューラ、またはパイプラインをプッシュするための Mixin。

push_to_hub[[diffusers.utils.PushToHubMixin.push_to_hub]]

push_to_hub(repo_id: str, commit_message: str | None = None, private: bool | None = None, token: str | None = None, create_pr: bool = False, safe_serialization: bool = True, variant: str | None = None, subfolder: str | None = None)

ソース

パラメータ:

repo_id (str) : モデル、スケジューラ、またはパイプラインのファイルをプッシュするリポジトリの名前です。組織にプッシュする場合は、組織名を含める必要があります。repo_id はローカルディレクトリへのパス也可以是。

commit_message (str, 任意) : push 時にコミットするメッセージ。デフォルトは "Upload {object}" です。

private (bool, 任意) : リポジトリを非公開にするかどうか。None(デフォルト)の場合、組織のデフォルトが非公開でない限り、リポジトリは公開になります。リポジトリが既に存在する場合、この値は無視されます。

token (str, 任意) : リモートファイルの HTTP ベアラ認証に使用するトークン。hf auth login を実行した際に生成されるトークン(~/.huggingface に保存されます)。

create_pr (bool, 任意, デフォルトは False) : アップロードしたファイルを含む PR を作成するか、直接コミットするかどうかを指定します。

safe_serialization (bool、任意、デフォルトは True) : モデルの重みを safetensors 形式に変換するかどうか。

variant (str, 任意) : 指定した場合、重みはpytorch_model.<variant>.binの形式で保存されます。

モデル、スケジューラー、またはパイプラインのファイルを🤗 Hugging Face Hubにアップロードします。

例:

from diffusers import UNet2DConditionModel

unet = UNet2DConditionModel.from_pretrained("stabilityai/stable-diffusion-2", subfolder="unet")

# Push the `unet` to your namespace with the name "my-finetuned-unet".
unet.push_to_hub("my-finetuned-unet")

# Push the `unet` to an organization with the name "my-finetuned-unet".
unet.push_to_hub("your-org/my-finetuned-unet")

Xet Storage Details

Size:
33.2 kB
·
Xet hash:
ec1aea2c2771ab5407766a97caad9c5aef3084e2f195a9a595f16fa3810b4117

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.