# キャッシュ

キャッシュは、🤗 Datasets が非常に効率的である理由の一つです。以前にダウンロードおよび処理されたデータセットを保存しておき、再度使用する際にキャッシュから直接読み込むことで、データセットを最初からダウンロードし直すことや、処理関数を再適用することを回避します。Python セッションを閉じて別のセッションを開始した後も、🤗 Datasets はキャッシュからデータセットを直接読み込みます。

## 指紋

キャッシュは、データセットに適用された変換をどのように追跡しているのでしょうか。🤗 Datasets は、キャッシュファイルにフィンガープリントを割り当てます。フィンガープリントは、データセットの現在の状態を保持します。初期のフィンガープリントは、Arrow テーブルのハッシュ、またはディスク上のデータセットの場合は Arrow ファイルのハッシュを使用して計算されます。その後のフィンガープリントは、直前の状態のフィンガープリントと、最後に適用された変換のハッシュを組み合わせることで計算されます。

> [!TIP]
> Transforms は、[Dataset.map()](/docs/datasets/v5.2.0/ja/package_reference/main_classes#datasets.Dataset.map) や [Dataset.shuffle()](/docs/datasets/v5.2.0/ja/package_reference/main_classes#datasets.Dataset.shuffle) のような、[How-to Process](./process) ガイドに記載されている処理手法のいずれかを指します。

実際のフィンガープリントは次のようになります:

```py
>>> from datasets import Dataset
>>> dataset1 = Dataset.from_dict({"a": [0, 1, 2]})
>>> dataset2 = dataset1.map(lambda x: {"a": x["a"] + 1})
>>> print(dataset1._fingerprint, dataset2._fingerprint)
d19493523d95e2dc 5b86abacd4b42434
```

変換がハッシュ可能であるためには、[dill](https://dill.readthedocs.io/en/latest/)または[pickle](https://docs.python.org/3/library/pickle)によってピクルス化可能である必要があります。

非ハッシュ可能なtransformを使用すると、🤗 Datasetsは代わりにランダムなフィンガープリントを使用し、警告を出力します。非ハッシュ可能なtransformは、以前のtransformとは異なるものとみなされます。その結果、🤗 Datasetsはすべてのtransformを再計算します。これを避けるには、transformがpickleまたはdillでシリアライズ可能であることを確認してください！

🤗 Datasets がすべてを再計算する例として、キャッシュが無効化されている場合が挙げられます。この場合、キャッシュファイルは毎回生成され、一時ディレクトリに書き込まれます。Python セッションが終了すると、一時ディレクトリ内のキャッシュファイルは削除されます。これらのキャッシュファイルには、フィンガープリントの代わりにランダムなハッシュが割り当てられます。

> [!TIP]
> キャッシュが無効な場合、変換後のデータセットを保存するには[Dataset.save_to_disk()](/docs/datasets/v5.2.0/ja/package_reference/main_classes#datasets.Dataset.save_to_disk)を使用してください。そうしないと、セッション終了時に削除されます。

## ハッシュ化

`map` に渡される関数と、`map` のパラメータ（`batch_size`、`remove_columns` など）をハッシュ化することで、データセットのフィンガープリントが更新されます。

[fingerprint.Hasher](/docs/datasets/v5.2.0/ja/package_reference/main_classes#datasets.fingerprint.Hasher) を使用して、任意の Python オブジェクトのハッシュを確認できます。

```py
>>> from datasets.fingerprint import Hasher
>>> my_func = lambda example: {"length": len(example["text"])}
>>> print(Hasher.hash(my_func))
'3d35e2b3e94c81d6'
```

ハッシュは、`dill`ピクルサーを使用してオブジェクトをダンプし、そのダンプされたバイト列をハッシュ化することで計算されます。ピクルサーは、関数内で使用されているすべての変数を再帰的にダンプするため、関数内で使用されているオブジェクトに変更を加えると、ハッシュが変更されます。

ある関数がセッション間で同じハッシュ値を持たない場合、その関数の変数の少なくとも1つに、決定論的でないPythonオブジェクトが含まれていることを意味します。この場合、ハッシュ値が変更された原因となったオブジェクトを特定するために、疑わしいと思われるオブジェクトのハッシュを計算してみてください。例えば、要素の順序がセッション間で決定論的でないリストを使用している場合、そのリストのハッシュ値もセッション間で一致しなくなります。

