Children forked after a run generate identical sampler data
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 25/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- numpy, python
調査の方向性
Start at engine/sampling_gen/utils.py:36, where check_random_state(None) selects NumPy's global generator, and trace Faker and distribution sampling paths used by preview() and create(). Use the issue's multiprocessing reproduction to compare fork and spawn, preserving in-process seeding tested by scripts/benchmarks/benchmark_engine_v2.py. Done means forked workers produce independent sampler data while explicit process-local seeding remains repeatable; note that linked PR #1077 already targets this issue.
索引モデルが issue の本文から書いたものです。
説明
Priority Level
Medium (Annoying but has workaround)
Describe the bug
Every child forked after the parent has run preview() or create() generates the same sampler data. Nothing fails or warns; a fork pool of N workers returns N copies of one dataset's sampler columns.
Samplers draw from numpy's global RandomState (check_random_state(None) returns np.random.mtrand._rand, engine/sampling_gen/utils.py:36) and from Faker's shared Random (faker.generator.random, used by every Faker(locale) instance). A fork copies their state, and nothing reseeds it: CPython reseeds the stdlib random module in a forked child, but not numpy's global generator or Faker's. Each child therefore draws the same sequence.
Before #1069 the forked child hung on its first run (#1068), so this was not reachable. With that fix merged, any fork pool created after a first run hits it. fork is the Linux default on Python 3.10–3.13.
Affected: every sampler that draws from scipy/numpy (category, uniform, gaussian, and the other distribution samplers), person_from_faker, and distribution-valued inference parameters (temperature, top_p), which also use numpy's global generator. Not affected: UUIDs, managed-dataset person sampling (DuckDB), and code using the stdlib random module.
Steps/Code to reproduce bug
No model provider needed:
import multiprocessing as mp
import data_designer.config as dd
from data_designer.interface import DataDesigner
def preview(_: int = 0) -> list:
builder = dd.DataDesignerConfigBuilder()
builder.add_column(dd.SamplerColumnConfig(
name="category", sampler_type=dd.SamplerType.CATEGORY,
params=dd.CategorySamplerParams(values=list("abcdefgh"))))
builder.add_column(dd.SamplerColumnConfig(
name="uniform", sampler_type=dd.SamplerType.UNIFORM,
params=dd.UniformSamplerParams(low=0, high=1000)))
df = DataDesigner().preview(builder, num_records=4).dataset
return [f"{c}:{u:.1f}" for c, u in zip(df["category"], df["uniform"])]
if __name__ == "__main__":
preview() # a parent run, e.g. checking the config before fanning out
for method in ("fork", "spawn"):
with mp.get_context(method).Pool(3) as pool:
rows = pool.map(preview, range(3))
print(f"{method:<5} distinct worker outputs: {len(set(map(tuple, rows)))} of 3")
for r in rows:
print(" ", r)
Output on main (2c9b66ef, CPython 3.14.0, numpy 2.4.3, Faker 20.1.0, Linux):
fork distinct worker outputs: 1 of 3
['b:965.9', 'c:719.3', 'h:599.7', 'a:869.9']
['b:965.9', 'c:719.3', 'h:599.7', 'a:869.9']
['b:965.9', 'c:719.3', 'h:599.7', 'a:869.9']
spawn distinct worker outputs: 3 of 3
['h:910.8', 'g:252.2', 'g:270.8', 'b:558.7']
['g:1.1', 'a:485.1', 'e:968.6', 'a:27.8']
['a:624.4', 'f:66.1', 'g:708.3', 'e:586.6']
Expected behavior
Forked children generate independent sampler data, as spawn children do.
Agent Diagnostic / Prior Investigation
Found by an agent sweeping the codebase for process-global state after #1069. It confirmed:
numpy.randomis not reseeded after fork once the parent has drawn from it. numpy seeds the global generator lazily, so children forked before any draw happen to differ.faker.generator.randomis not reseeded after fork, andFaker(locale).random is faker.generator.random.- The stdlib
randommodule is reseeded after fork by CPython.
The repo's own benchmark (scripts/benchmarks/benchmark_engine_v2.py:585-586) seeds random and numpy.random for repeatable sampler output, so a fix should keep in-process seeding working.
Additional context
Workaround: use mp.get_context("spawn") or "forkserver", or call numpy.random.seed() and faker.Faker.seed() with no argument at the start of each forked worker.
Related: #1068, #1069.
- 主要言語
- Python
- スター
- 2.4k
- フォーク
- 234
- 平均マージ
- 22時間 5分
- マージ済み PR(30日)
- 70
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
NVIDIA-NeMo/DataDesigner のほかの issue
-
`ValidationColumnConfig` misaligns rows and discards the whole batch after an upstream row is dropped対応中かも @suryapilla が今日担当しました。 オープンtriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
NVIDIA-NeMo/DataDesigner#1073 · コメント 4 件 ·
メンテナーはふだん 1 日以内に返信
-
docs: required_columns description is incomplete for LLM and multimodal columns対応中かも @rksharma-owg が 7 日前に担当しました。 オープンbug triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
NVIDIA-NeMo/DataDesigner#1002 · コメント 4 件 ·
メンテナーはふだん 1 日以内に返信
-
enforce \from future import annotations` via ruff FA102 rule`対応中かも @chethanuk が 42 日前に担当しました。 オープンtask
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
NVIDIA-NeMo/DataDesigner#760 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
NVIDIA-NeMo/DataDesigner#1079 ·
メンテナーはふだん 1 日以内に返信
-
task
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
NVIDIA-NeMo/DataDesigner#1056 ·
メンテナーはふだん 1 日以内に返信
NVIDIA-NeMo/DataDesigner の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
aws-samples/sample-per-model-bedrock#464 ·
メンテナーはふだん 1 日以内に返信
-
lesson-submission pending-review
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
Ikalus1988/MisakaNet#3789 ·
メンテナーはふだん 1 日以内に返信
-
Python Volcengine provider returns failures instead of raising them対応中かも @Ricardo-M-L が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 79/100
agent-infra/sandbox#248 ·
-
[Bug] cloud JSON directory loading assumes a Key field in fsspec listings対応中かも @Ricardo-M-L が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
hiyouga/LlamaFactory#10910 ·
メンテナーはふだん 1 日以内に返信
-
Bundled uv is never updated and trusts the compromised eMudhra certificates対応中かも @FabienDanieau が今日担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100