The auto mixed-precision branch now gates bf16 on unsloth_zoo's
device_is_bf16_supported() (CUDA/XPU/HIP) instead of torch.cuda.is_bf16_supported(),
which is only patched on CUDA. This keeps V100/T4 on fp16 while leaving AMD (HIP)
and Intel (XPU) behavior unchanged. Falls back to the torch call on older
unsloth_zoo.
Exercise the real SFTTrainer mixed-precision template from rl.py source against
mocked inputs: normal models get float32 weights + fp16 forward, FORCE_FLOAT32
models stay pure float32, no bf16 on no-bf16 hardware, and bf16 GPUs are
unchanged. Covers issue #4082.