Studio: thread vision_image_size into DeepSeek OCR + writable MLX ndarray

- trainer.py: DeepSeek OCR collator now honors the new vision_image_size
  setting as image_size. Falls back to 640 when null. base_size stays at
  1024 and crop_mode stays True so the Gundam preset's dynamic cropping
  of large documents keeps working.
- worker.py: _resize_mlx_vlm_image returns np.array(image, copy=True)
  instead of np.asarray(image). The PIL view from np.asarray is not
  writable, which makes HF VLM processors emit "The given NumPy array
  is not writable, and PyTorch does not support non-writable tensors..."
  when they call torch.from_numpy. copy=True keeps the same shape and
  dtype but produces a writable buffer.
This commit is contained in:
Daniel Han 2026-05-24 13:47:07 +00:00
commit dd1a209777
2 changed files with 18 additions and 4 deletions

View file

@ -3057,10 +3057,23 @@ class UnslothTrainer:
logger.info("Configuring DeepSeek OCR data collator...\n")
FastVisionModel.for_training(self.model)
# Honor user-selected Image Size. Keep base_size + crop_mode
# at the Gundam preset (1024 / True) so dynamic cropping of
# large documents still works.
vision_image_size = training_args.get("vision_image_size")
deepseek_image_size = (
640 if vision_image_size is None
else int(vision_image_size)
)
if vision_image_size is not None:
logger.info(
f"DeepSeek OCR image resize: "
f"{deepseek_image_size} (per-crop tile size)\n"
)
data_collator = DeepSeekOCRDataCollator(
tokenizer = self.tokenizer,
model = self.model,
image_size = 640,
image_size = deepseek_image_size,
base_size = 1024,
crop_mode = True,
train_on_responses_only = training_args.get(

View file

@ -984,9 +984,10 @@ def _resize_mlx_vlm_image(image, resize):
if new_size != image.size:
resampling = getattr(Image, "Resampling", Image).LANCZOS
image = image.resize(new_size, resampling)
# mlx-vlm's internal collator square-resizes PIL images. Return an ndarray
# so Studio's max-dimension resize is the final resize, like trainer.py.
return np.asarray(image)
# mlx-vlm's internal collator square-resizes PIL images. Return a writable
# ndarray so Studio's max-dimension resize is the final one (like
# trainer.py) and HF processors don't warn on non-writable views.
return np.array(image, copy = True)
def _resize_mlx_vlm_images(value, resize):