[Train] Handle Arrow-backed pandas dtypes in LightGBM examples#63427
[Train] Handle Arrow-backed pandas dtypes in LightGBM examples#63427pseudo-rnd-thoughts wants to merge 8 commits into
Conversation
Signed-off-by: Mark Towers <mark@anyscale.com>
There was a problem hiding this comment.
Code Review
This pull request introduces the use of convert_dtypes() across LightGBM trainer implementations, documentation examples, and tests to ensure compatibility with Arrow-backed pandas DataFrames from Ray Data. It also re-enables the test_trainer_restore test. The review feedback recommends simplifying the code by removing redundant materialize() calls and omitting the explicit dtype_backend argument to maintain compatibility with pandas versions prior to 2.0.0. Additionally, the reviewer suggests applying these fixes to the legacy LightGBM trainer and warns about potential performance overhead when using convert_dtypes() on very large datasets.
Signed-off-by: Mark Towers <mark@anyscale.com>
Signed-off-by: Mark Towers <mark@anyscale.com>
Signed-off-by: Mark Towers <mark@anyscale.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 17abd91. Configure here.
| elif pa.types.is_unsigned_integer(arrow_dtype): | ||
| dtype_mapping[column] = f"UInt{arrow_dtype.bit_width}" | ||
| elif pa.types.is_floating(arrow_dtype): | ||
| dtype_mapping[column] = f"Float{arrow_dtype.bit_width}" |
There was a problem hiding this comment.
Float16 arrow dtype causes TypeError in normalize function
Low Severity
pa.types.is_floating returns True for float16 (half-float) Arrow types, so the function generates "Float16" as the target pandas dtype. However, pandas only supports Float32 and Float64 as nullable float extension types — there is no Float16. This causes a TypeError at the df.astype(dtype_mapping) call if any column has pd.ArrowDtype(pa.float16()). The pa.types.is_float16() check could be used to skip or handle this case separately.
Reviewed by Cursor Bugbot for commit 17abd91. Configure here.
Signed-off-by: Mark Towers <mark@anyscale.com>


Description
#63017 updated Ray Data's Arrow-to-pandas conversion to preserve Arrow-backed pandas dtypes, such as
int64[pyarrow], so dtypes can roundtrip more faithfully.This exposed an incompatibility with LightGBM's pandas input path. Ray Train's LightGBM examples and legacy trainer code convert Ray Data shards to pandas before constructing
lightgbm.Dataset. With Arrow-backed Ray Data inputs, those pandas DataFrames can now contain Arrow-backed dtypes, and LightGBM rejects them during pandas dtype validation even when the logical column type is numeric.This PR updates the LightGBM paths to normalize pandas DataFrames to NumPy-nullable pandas dtypes before passing them to LightGBM. It also updates documentation and examples to show the same conversion for user-authored LightGBM training loops.
Changes
LightGBMTrainerpath before constructinglightgbm.Dataset.convert_dtypes(dtype_backend="numpy_nullable")afterto_pandas().ray.data.from_items(...).