Puro-2B Pretraining Data: The Recipe Behind a 2B Model
8
11 commits
4 linked in READMEs
updated Aug 28, 2026
This is the materialized pretraining data release for Puro-2B-Base, a 2B base model trained from scratch on consumer-grade RTX 5090 GPUs.
The repository contains the component-level data pools used to construct the two Puro-2B pretraining phases, together with the tokenizer used for token accounting. It is organized for inspection, selective streaming, and recipe reconstruction rather than as a small train/test benchmark.
| Domain | Phase 1 | Phase 1 share | Phase 2 | Phase 2 share |
|---|---|---|---|---|
| English | 321B | 73.2% | 558B | 59.4% |
| Mathematics | 31.6B | 7.2% | 171B | 18.3% |
| Chinese | 51.3B | 11.7% | 88.5B | 9.4% |
| Code | 34.6B | 7.9% | 108B | 11.5% |
| SFT / instruction-formatted | 0 | 0.0% | 12.7B | 1.3% |
| Materialized pool | 439B | 100.0% | 938B | 100.0% |
Token counts are computed with the bundled tokenizer and measure materialized token exposure, not unique upstream content. Dataset-family rows may aggregate overlapping configurations.
The production model consumed approximately 439B tokens in Phase 1 and 961B additional tokens in Phase 2. The Phase 2 training count is larger than the 938B stationary Phase 2 pool because the opening transition replays Phase 1 data while introducing the Phase 2 stream. Replay is a training-schedule operation, not additional independent source data.
.
βββ phase1/ # Component data used to build the Phase 1 mixture
βββ phase2/ # Component data used to build the Phase 2 mixture
βββ qwen2_tokenizer/ # Tokenizer files used for token accounting
βββ README.md
The release defines two Hugging Face configurations, phase1 and phase2.
Each configuration exposes one train split because both phases are
pretraining corpora. Directory names such as train, validation, test, or
benchmark inside individual source components preserve upstream organization;
they are not Puro-2B evaluation splits.
Files are grouped by source component. Their filesystem order is not the final curriculum order used by the production run. The transition, replay, curriculum bucket construction, deterministic seeds, and global uniform reshuffle are recipe operations documented in the technical report and implemented in the data-processing pipeline.
Released Parquet records use a common schema:
| Field | Type | Description |
|---|---|---|
text | string | Normalized text presented to the tokenizer. |
token_count | int64 | Number of tokens under the bundled tokenizer. |
domain_category | string | Semantic domain, such as English, Chinese, math, code, or instruction-formatted data. |
source_component_id | string | Stable identifier for the materialized source component. |
Source-specific metadata not represented by these fields should be recovered from the upstream dataset and the Puro data-processing manifests.
The full repository is hundreds of gigabytes. Streaming or selecting individual components is recommended for exploration.
from datasets import load_dataset
phase1 = load_dataset(
"thu-pacman/Puro-2B",
"phase1",
split="train",
streaming=True,
)
example = next(iter(phase1))
print(example["source_component_id"], example["token_count"])
print(example["text"][:500])
Load Phase 2 by changing the configuration name:
phase2 = load_dataset(
"thu-pacman/Puro-2B",
"phase2",
split="train",
streaming=True,
)
For a single component, load its Parquet files directly:
from datasets import load_dataset
open_web_math = load_dataset(
"parquet",
data_files={
"train": (
"hf://datasets/thu-pacman/Puro-2B/"
"phase2/open-web-math/*.parquet"
)
},
split="train",
streaming=True,
)
For reproducible experiments, pin the dataset revision to a commit hash and
record the selected component paths, filtering rules, and shuffle seed.
The Puro-2B pipeline separates recipe selection from shard materialization:
Because the proxy study has no matched base-mixture-only continuation, its candidate profiles should be interpreted as recipe signals rather than isolated causal effects.
| Domain | Representative source families |
|---|---|
| English | Nemotron-CC-v2, FineWeb-Edu, Cosmopedia-v2, DCLM, ArXiv, FineWiki |
| Chinese | FineWeb-Edu-CN, ChineseWebText2.0, merged Chinese web corpora, Baidu Baike, FineWiki-CN, UN documents, Alpaca-Zh |
| Mathematics | UltraData-Math, SwallowMath-v2, Nemotron-CC-Math, MegaMath-Web-Pro, OpenWebMath, FineMath, AutoMathText, NuminaMath-CoT, FineProofs |
| Code | MegaMath-Code, Nemotron Synthetic Code, Swallow-Code-v2, CoderForge, StackExchange, Python and GitHub corpora, Codeforces-CoTs, Jupyter Agent |
| Instruction-formatted | Nemotron Terminal Corpus, JiuZhang3.0, Tulu 3 SFT, ToolMind, ToolBench, SlimOrca, LongAlpaca, OpenThoughts Agent |
See the technical report source for the component-level token counts, materialization modes, upstream identifiers, proxy protocol, and license audit.
The dataset card uses the other license designation because the recipe
combines components with different upstream terms. Apache 2.0 applies only to
project-authored documentation, metadata, manifests, and processing artifacts
explicitly released under that license. It does not replace the licenses,
copyrights, privacy rights, or terms attached to third-party source content.
Important boundaries include:
Users are responsible for checking the upstream terms of the components they download and for determining whether their intended use is permitted. The technical report's component inventory is the starting point for that review.
This is large-scale pretraining data collected from heterogeneous public and synthetic sources. It may contain personal information, copyrighted material, incorrect claims, duplicated content, offensive language, security-sensitive code, or social and cultural biases. Filtering reduces some problems but does not eliminate them.
The release does not claim exhaustive benchmark decontamination. Some source families provide decontaminated subsets, but that property should not be generalized to every component. Users should run task-specific contamination, privacy, safety, and licensing checks before training or deploying a model.
Please cite our technical report if you find our work useful:
@misc{luo2026puro2b,
title={Puro-2B: Poor Lab's Qwen2-1.5B Trained on RTX 5090 within $5090},
author={Kairong Luo and Jiarui Cui and Yaorui Yin and Shengqi Chen and Yiming Yang and Linxiang Gao and Yanmohan Wang and Mingzhe Zhang and Kaiyue Wen and Kaifeng Lyu and Wenguang Chen},
year={2026},
eprint={2608.27370},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2608.27370},
}
7 commits
4 commits
Puro-2B Pretraining Data: The Recipe Behind a 2B Model
8
11 commits
4 linked in READMEs
updated Aug 28, 2026
This is the materialized pretraining data release for Puro-2B-Base, a 2B base model trained from scratch on consumer-grade RTX 5090 GPUs.
The repository contains the component-level data pools used to construct the two Puro-2B pretraining phases, together with the tokenizer used for token accounting. It is organized for inspection, selective streaming, and recipe reconstruction rather than as a small train/test benchmark.
| Domain | Phase 1 | Phase 1 share | Phase 2 | Phase 2 share |
|---|---|---|---|---|
| English | 321B | 73.2% | 558B | 59.4% |
| Mathematics | 31.6B | 7.2% | 171B | 18.3% |
| Chinese | 51.3B | 11.7% | 88.5B | 9.4% |
| Code | 34.6B | 7.9% | 108B | 11.5% |
| SFT / instruction-formatted | 0 | 0.0% | 12.7B | 1.3% |
| Materialized pool | 439B | 100.0% | 938B | 100.0% |
Token counts are computed with the bundled tokenizer and measure materialized token exposure, not unique upstream content. Dataset-family rows may aggregate overlapping configurations.
The production model consumed approximately 439B tokens in Phase 1 and 961B additional tokens in Phase 2. The Phase 2 training count is larger than the 938B stationary Phase 2 pool because the opening transition replays Phase 1 data while introducing the Phase 2 stream. Replay is a training-schedule operation, not additional independent source data.
.
βββ phase1/ # Component data used to build the Phase 1 mixture
βββ phase2/ # Component data used to build the Phase 2 mixture
βββ qwen2_tokenizer/ # Tokenizer files used for token accounting
βββ README.md
The release defines two Hugging Face configurations, phase1 and phase2.
Each configuration exposes one train split because both phases are
pretraining corpora. Directory names such as train, validation, test, or
benchmark inside individual source components preserve upstream organization;
they are not Puro-2B evaluation splits.
Files are grouped by source component. Their filesystem order is not the final curriculum order used by the production run. The transition, replay, curriculum bucket construction, deterministic seeds, and global uniform reshuffle are recipe operations documented in the technical report and implemented in the data-processing pipeline.
Released Parquet records use a common schema:
| Field | Type | Description |
|---|---|---|
text | string | Normalized text presented to the tokenizer. |
token_count | int64 | Number of tokens under the bundled tokenizer. |
domain_category | string | Semantic domain, such as English, Chinese, math, code, or instruction-formatted data. |
source_component_id | string | Stable identifier for the materialized source component. |
Source-specific metadata not represented by these fields should be recovered from the upstream dataset and the Puro data-processing manifests.
The full repository is hundreds of gigabytes. Streaming or selecting individual components is recommended for exploration.
from datasets import load_dataset
phase1 = load_dataset(
"thu-pacman/Puro-2B",
"phase1",
split="train",
streaming=True,
)
example = next(iter(phase1))
print(example["source_component_id"], example["token_count"])
print(example["text"][:500])
Load Phase 2 by changing the configuration name:
phase2 = load_dataset(
"thu-pacman/Puro-2B",
"phase2",
split="train",
streaming=True,
)
For a single component, load its Parquet files directly:
from datasets import load_dataset
open_web_math = load_dataset(
"parquet",
data_files={
"train": (
"hf://datasets/thu-pacman/Puro-2B/"
"phase2/open-web-math/*.parquet"
)
},
split="train",
streaming=True,
)
For reproducible experiments, pin the dataset revision to a commit hash and
record the selected component paths, filtering rules, and shuffle seed.
The Puro-2B pipeline separates recipe selection from shard materialization:
Because the proxy study has no matched base-mixture-only continuation, its candidate profiles should be interpreted as recipe signals rather than isolated causal effects.
| Domain | Representative source families |
|---|---|
| English | Nemotron-CC-v2, FineWeb-Edu, Cosmopedia-v2, DCLM, ArXiv, FineWiki |
| Chinese | FineWeb-Edu-CN, ChineseWebText2.0, merged Chinese web corpora, Baidu Baike, FineWiki-CN, UN documents, Alpaca-Zh |
| Mathematics | UltraData-Math, SwallowMath-v2, Nemotron-CC-Math, MegaMath-Web-Pro, OpenWebMath, FineMath, AutoMathText, NuminaMath-CoT, FineProofs |
| Code | MegaMath-Code, Nemotron Synthetic Code, Swallow-Code-v2, CoderForge, StackExchange, Python and GitHub corpora, Codeforces-CoTs, Jupyter Agent |
| Instruction-formatted | Nemotron Terminal Corpus, JiuZhang3.0, Tulu 3 SFT, ToolMind, ToolBench, SlimOrca, LongAlpaca, OpenThoughts Agent |
See the technical report source for the component-level token counts, materialization modes, upstream identifiers, proxy protocol, and license audit.
The dataset card uses the other license designation because the recipe
combines components with different upstream terms. Apache 2.0 applies only to
project-authored documentation, metadata, manifests, and processing artifacts
explicitly released under that license. It does not replace the licenses,
copyrights, privacy rights, or terms attached to third-party source content.
Important boundaries include:
Users are responsible for checking the upstream terms of the components they download and for determining whether their intended use is permitted. The technical report's component inventory is the starting point for that review.
This is large-scale pretraining data collected from heterogeneous public and synthetic sources. It may contain personal information, copyrighted material, incorrect claims, duplicated content, offensive language, security-sensitive code, or social and cultural biases. Filtering reduces some problems but does not eliminate them.
The release does not claim exhaustive benchmark decontamination. Some source families provide decontaminated subsets, but that property should not be generalized to every component. Users should run task-specific contamination, privacy, safety, and licensing checks before training or deploying a model.
Please cite our technical report if you find our work useful:
@misc{luo2026puro2b,
title={Puro-2B: Poor Lab's Qwen2-1.5B Trained on RTX 5090 within $5090},
author={Kairong Luo and Jiarui Cui and Yaorui Yin and Shengqi Chen and Yiming Yang and Linxiang Gao and Yanmohan Wang and Mingzhe Zhang and Kaiyue Wen and Kaifeng Lyu and Wenguang Chen},
year={2026},
eprint={2608.27370},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2608.27370},
}
7 commits
4 commits