2. データサンプリング

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

データサンプリング

データサンプリングは、GPTのような大規模言語モデル(LLM)のトレーニングのためにデータを準備する際の重要なプロセスです。これは、モデルが前の単語に基づいて次の単語(またはトークン)を予測する方法を学ぶために使用する入力とターゲットのシーケンスにテキストデータを整理することを含みます。適切なデータサンプリングは、モデルが言語パターンや依存関係を効果的に捉えることを保証します。

Tip

この第二段階の目標は非常にシンプルです:入力データをサンプリングし、通常はデータセットを特定の長さの文に分け、期待される応答も生成してトレーニングフェーズのために準備します。

データサンプリングが重要な理由

GPTのようなLLMは、前の単語によって提供されるコンテキストを理解することによってテキストを生成または予測するようにトレーニングされています。これを達成するためには、トレーニングデータは、モデルが単語のシーケンスとその後の単語との関係を学べるように構造化されている必要があります。この構造化されたアプローチにより、モデルは一般化し、一貫性があり文脈に関連したテキストを生成することができます。

データサンプリングの主要概念

  1. トークン化: テキストをトークン(例:単語、サブワード、または文字)と呼ばれる小さな単位に分解すること。
  2. シーケンスの長さ(max_length): 各入力シーケンス内のトークンの数。
  3. スライディングウィンドウ: トークン化されたテキスト上でウィンドウを移動させることによって重複する入力シーケンスを作成する方法。
  4. ストライド: 次のシーケンスを作成するためにスライディングウィンドウが前方に移動するトークンの数。

ステップバイステップの例

データサンプリングを説明するために、例を見ていきましょう。

例文

"Lorem ipsum dolor sit amet, consectetur adipiscing elit."

トークン化

基本的なトークナイザーを使用して、テキストを単語と句読点に分割すると仮定します:

Tokens: ["Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit."]

パラメータ

  • 最大シーケンス長 (max_length): 4 トークン
  • スライディングウィンドウストライド: 1 トークン

入力とターゲットシーケンスの作成

  1. スライディングウィンドウアプローチ:
  • 入力シーケンス: 各入力シーケンスは max_length トークンで構成されます。
  • ターゲットシーケンス: 各ターゲットシーケンスは、対応する入力シーケンスの直後に続くトークンで構成されます。
  1. シーケンスの生成:
ウィンドウ位置入力シーケンスターゲットシーケンス
1["Lorem", "ipsum", "dolor", "sit"]["ipsum", "dolor", "sit", "amet,"]
2["ipsum", "dolor", "sit", "amet,"]["dolor", "sit", "amet,", "consectetur"]
3["dolor", "sit", "amet,", "consectetur"]["sit", "amet,", "consectetur", "adipiscing"]
4["sit", "amet,", "consectetur", "adipiscing"]["amet,", "consectetur", "adipiscing", "elit."]
  1. 結果の入力とターゲット配列:
  • 入力:
[
["Lorem", "ipsum", "dolor", "sit"],
["ipsum", "dolor", "sit", "amet,"],
["dolor", "sit", "amet,", "consectetur"],
["sit", "amet,", "consectetur", "adipiscing"],
]
  • ターゲット:
[
["ipsum", "dolor", "sit", "amet,"],
["dolor", "sit", "amet,", "consectetur"],
["sit", "amet,", "consectetur", "adipiscing"],
["amet,", "consectetur", "adipiscing", "elit."],
]

視覚的表現

トークン位置トークン
1Lorem
2ipsum
3dolor
4sit
5amet,
6consectetur
7adipiscing
8elit.

ストライド1のスライディングウィンドウ:

  • 最初のウィンドウ (位置 1-4): [“Lorem”, “ipsum”, “dolor”, “sit”] → ターゲット: [“ipsum”, “dolor”, “sit”, “amet,”]
  • 2番目のウィンドウ (位置 2-5): [“ipsum”, “dolor”, “sit”, “amet,”] → ターゲット: [“dolor”, “sit”, “amet,”, “consectetur”]
  • 3番目のウィンドウ (位置 3-6): [“dolor”, “sit”, “amet,”, “consectetur”] → ターゲット: [“sit”, “amet,”, “consectetur”, “adipiscing”]
  • 4番目のウィンドウ (位置 4-7): [“sit”, “amet,”, “consectetur”, “adipiscing”] → ターゲット: [“amet,”, “consectetur”, “adipiscing”, “elit.”]

ストライドの理解

  • ストライド1: ウィンドウは毎回1トークン前進し、非常に重複したシーケンスを生成します。これにより、文脈関係の学習が向上する可能性がありますが、類似のデータポイントが繰り返されるため、過学習のリスクが高まる可能性があります。
  • ストライド2: ウィンドウは毎回2トークン前進し、重複を減らします。これにより冗長性と計算負荷が減少しますが、文脈のニュアンスを見逃す可能性があります。
  • max_lengthに等しいストライド: ウィンドウは全ウィンドウサイズ分前進し、重複のないシーケンスを生成します。これによりデータの冗長性が最小限に抑えられますが、シーケンス間の依存関係を学習するモデルの能力が制限される可能性があります。

ストライド2の例:

同じトークン化されたテキストと max_length 4を使用して:

  • 最初のウィンドウ (位置 1-4): [“Lorem”, “ipsum”, “dolor”, “sit”] → ターゲット: [“ipsum”, “dolor”, “sit”, “amet,”]
  • 2番目のウィンドウ (位置 3-6): [“dolor”, “sit”, “amet,”, “consectetur”] → ターゲット: [“sit”, “amet,”, “consectetur”, “adipiscing”]
  • 3番目のウィンドウ (位置 5-8): [“amet,”, “consectetur”, “adipiscing”, “elit.”] → ターゲット: [“consectetur”, “adipiscing”, “elit.”, “sed”] (続きがあると仮定)

コード例

https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb からのコード例を通じて、これをよりよく理解しましょう。

# Download the text to pre-train the LLM
import urllib.request
url = ("https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt")
file_path = "the-verdict.txt"
urllib.request.urlretrieve(url, file_path)

with open("the-verdict.txt", "r", encoding="utf-8") as f:
raw_text = f.read()

"""
Create a class that will receive some params lie tokenizer and text
and will prepare the input chunks and the target chunks to prepare
the LLM to learn which next token to generate
"""
import torch
from torch.utils.data import Dataset, DataLoader

class GPTDatasetV1(Dataset):
def __init__(self, txt, tokenizer, max_length, stride):
self.input_ids = []
self.target_ids = []

# Tokenize the entire text
token_ids = tokenizer.encode(txt, allowed_special={"<|endoftext|>"})

# Use a sliding window to chunk the book into overlapping sequences of max_length
for i in range(0, len(token_ids) - max_length, stride):
input_chunk = token_ids[i:i + max_length]
target_chunk = token_ids[i + 1: i + max_length + 1]
self.input_ids.append(torch.tensor(input_chunk))
self.target_ids.append(torch.tensor(target_chunk))

def __len__(self):
return len(self.input_ids)

def __getitem__(self, idx):
return self.input_ids[idx], self.target_ids[idx]


"""
Create a data loader which given the text and some params will
prepare the inputs and targets with the previous class and
then create a torch DataLoader with the info
"""

import tiktoken

def create_dataloader_v1(txt, batch_size=4, max_length=256,
stride=128, shuffle=True, drop_last=True,
num_workers=0):

# Initialize the tokenizer
tokenizer = tiktoken.get_encoding("gpt2")

# Create dataset
dataset = GPTDatasetV1(txt, tokenizer, max_length, stride)

# Create dataloader
dataloader = DataLoader(
dataset,
batch_size=batch_size,
shuffle=shuffle,
drop_last=drop_last,
num_workers=num_workers
)

return dataloader


"""
Finally, create the data loader with the params we want:
- The used text for training
- batch_size: The size of each batch
- max_length: The size of each entry on each batch
- stride: The sliding window (how many tokens should the next entry advance compared to the previous one). The smaller the more overfitting, usually this is equals to the max_length so the same tokens aren't repeated.
- shuffle: Re-order randomly
"""
dataloader = create_dataloader_v1(
raw_text, batch_size=8, max_length=4, stride=1, shuffle=False
)

data_iter = iter(dataloader)
first_batch = next(data_iter)
print(first_batch)

# Note the batch_size of 8, the max_length of 4 and the stride of 1
[
# Input
tensor([[   40,   367,  2885,  1464],
[  367,  2885,  1464,  1807],
[ 2885,  1464,  1807,  3619],
[ 1464,  1807,  3619,   402],
[ 1807,  3619,   402,   271],
[ 3619,   402,   271, 10899],
[  402,   271, 10899,  2138],
[  271, 10899,  2138,   257]]),
# Target
tensor([[  367,  2885,  1464,  1807],
[ 2885,  1464,  1807,  3619],
[ 1464,  1807,  3619,   402],
[ 1807,  3619,   402,   271],
[ 3619,   402,   271, 10899],
[  402,   271, 10899,  2138],
[  271, 10899,  2138,   257],
[10899,  2138,   257,  7026]])
]

# With stride=4 this will be the result:
[
# Input
tensor([[   40,   367,  2885,  1464],
[ 1807,  3619,   402,   271],
[10899,  2138,   257,  7026],
[15632,   438,  2016,   257],
[  922,  5891,  1576,   438],
[  568,   340,   373,   645],
[ 1049,  5975,   284,   502],
[  284,  3285,   326,    11]]),
# Target
tensor([[  367,  2885,  1464,  1807],
[ 3619,   402,   271, 10899],
[ 2138,   257,  7026, 15632],
[  438,  2016,   257,   922],
[ 5891,  1576,   438,   568],
[  340,   373,   645,  1049],
[ 5975,   284,   502,   284],
[ 3285,   326,    11,   287]])
]

高度なサンプリング戦略 (2023-2025)

1. 温度ベースの混合重み付け

最先端のLLMは、単一のコーパスでトレーニングされることはほとんどありません。代わりに、いくつかの異種データソース(コード、ウェブ、学術論文、フォーラムなど)からサンプリングします。各ソースの相対的な割合は、下流のパフォーマンスに強く影響を与える可能性があります。最近のオープンソースモデルであるLlama 2は、コーパスiから文書を引き出す確率が温度に基づくサンプリングスキームを導入しました。

p(i) = \frac{w_i^{\alpha}}{\sum_j w_j^{\alpha}}

wi – コーパス i の生トークン割合
α (“温度”) – (0,1] の値。 α < 1 は分布を平坦にし、より小さな高品質コーパスに重みを与えます。

Llama 2 は α = 0.7 を使用し、α を減少させることで知識重視のタスクで評価スコアが向上する一方で、トレーニングミックスを安定させることを示しました。同じ手法が Mistral (2023) と Claude 3 にも採用されています。

from collections import Counter

def temperature_sample(corpus_ids, alpha=0.7):
counts = Counter(corpus_ids)           # number of tokens seen per corpus
probs  = {c: c_count**alpha for c, c_count in counts.items()}
Z = sum(probs.values())
probs = {c: p/Z for c, p in probs.items()}
# Now draw according to probs to fill every batch

### 2. Sequence Packing / Dynamic Batching
GPU memory is wasted when every sequence in a batch is padded to the longest example.  "Packing" concatenates multiple shorter sequences until the **exact** `max_length` is reached and builds a parallel `attention_mask` so that tokens do not attend across segment boundaries.  Packing can improve throughput by 20–40 % with no gradient change and is supported out-of-the-box in

* PyTorch `torchtext.experimental.agents.PackedBatch`
* HuggingFace `DataCollatorForLanguageModeling(pad_to_multiple_of=…)`

Dynamic batching frameworks (e.g. FlashAttention 2, vLLM 2024) combine sequence packing with just-in-time kernel selection, enabling thousand-token context training at 400+ K tokens/s on A100-80G.

### 3. Deduplication & Quality Filtering
Repeated passages cause memorization and provide an easy channel for data-poisoning.  Modern pipelines therefore:

1. MinHash/FAISS near-duplicate detection at **document** and **128-gram** level.
2. Filter documents whose perplexity under a small reference model is > µ + 3σ (noisy OCR, garbled HTML).
3. Block-list documents that contain PII or CWE keywords using regex & spaCy NER.

The Llama 2 team deduplicated with 8-gram MinHash and removed ~15 % of CommonCrawl before sampling.  OpenAI’s 2024 "Deduplicate Everything" paper demonstrates ≤0.04 duplicate ratio reduces over-fitting and speeds convergence.

## Security & Privacy Considerations During Sampling

### Data-Poisoning / Backdoor Attacks
Researchers showed that inserting <1 % backdoored sentences can make a model obey a hidden trigger ("PoisonGPT", 2023).  Recommended mitigations:

* **Shuffled mixing** – make sure adjacent training examples originate from different sources; this dilutes gradient alignment of malicious spans.
* **Gradient similarity scoring** – compute cosine similarity of example gradient to batch average; outliers are candidates for removal.
* **Dataset versioning & hashes** – freeze immutable tarballs and verify SHA-256 before each training run.

### Membership-Inference & Memorization
Long overlap between sliding-window samples increases the chance that rare strings (telephone numbers, secret keys) are memorized.  OpenAI’s 2024 study on ChatGPT memorization reports that raising stride from 1 × `max_length` to 4 × reduces verbatim leakage by ≈50 % with negligible loss in perplexity.

Practical recommendations:

* Use **stride ≥ max_length** except for <1B parameter models where data volume is scarce.
* Add random masking of 1-3 tokens per window during training; this lowers memorization while preserving utility.

---

## References

- [Build a Large Language Model from Scratch (Manning, 2024)](https://www.manning.com/books/build-a-large-language-model-from-scratch)
- [Llama 2: Open Foundation and Fine-Tuned Chat Models (2023)](https://arxiv.org/abs/2307.09288)
- [PoisonGPT: Assessing Backdoor Vulnerabilities in Large Language Models (BlackHat EU 2023)](https://arxiv.org/abs/2308.12364)

> [!TIP]
> AWSハッキングを学び、実践する:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> GCPハッキングを学び、実践する:<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Azureハッキングを学び、実践する:<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>HackTricksをサポートする</summary>
>
> - [**サブスクリプションプラン**](https://github.com/sponsors/carlospolop)を確認してください!
> - **💬 [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**テレグラムグループ**](https://t.me/peass)に参加するか、**Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**をフォローしてください。**
> - **[**HackTricks**](https://github.com/carlospolop/hacktricks)および[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud)のGitHubリポジトリにPRを提出してハッキングトリックを共有してください。**
>
> </details>