Open cstefansen opened 1 year ago
I think it's caused by the global random engine used inside xgboost. The booster trained in the second iteration is affected by the one from the first iteration as they share the same random engine.
Similar to calling
x = np.random.normal(-3.0e-05, 0.5, (n_rows, n_features))
twice, x
is different even if the np seed is specified.
@trivialfis, to stay with your analogy, it is possible to get reproducible results by saying:
np.random.seed(0)
x1 = np.random.normal(-3.0e-05, 0.5, (n_rows, n_features))
np.random.seed(0)
x2 = np.random.normal(-3.0e-05, 0.5, (n_rows, n_features))
np.testing.assert_equal(x1, x2)
Is there a way to achieve the same reproducibility for XGBoost?
The example in the original repro does in fact produce reproducible (i.e., identical) results in each iteration when run on a CPU. However, when run on a single GPU, the first run is always different from the subsequent runs (I ran this with 1000 iterations, and a got 999 identical models after the first one.)
This seems to be like a seed/rng initialization within the GPU code because once the Python interpreter has run the repro once, it will produce identical results when run again, and to repro I have to restart the Python interpreter to get it to produce a different model on the first iteration.
@trivialfis just want to bump this up. Do you know if there is a way to set the global random engine seed you mentioned? As the example above shows, setting np.random.seed
does not fix the issue. The weird part is only the first run is non-deterministic. The following runs all give same results.
Let me take another look later
Based on https://github.com/dmlc/xgboost/issues/5023 it seems like XGBoost aims to guarantee reproducibility for single GPU training with gpu_hist. That is, training again on the same hardware with the same data and the same seed should give precisely the same model bit for bit.
However, I am consistently seeing different results on the very first training run (on a freshly started Python interpreter - this is important) for the following code:
which results in
This is on Linux with a Tesla T4 and CUDA 11.7.
Is there another seed that needs to be set to ensure that the first run works off of the same seed as the subsequent runs? Or is this potentially a bug?