unsloth/docker/unsloth_ipython_startup.py
Daniel Han c9ff52ba04 docker: Colab-grade JupyterLab and Studio UX for the Blackwell image
Stacks a Colab-like JupyterLab and Studio experience on top of the
existing Blackwell image. Additive only: the training stack, CUDA/torch
pinning, and the Studio/JupyterLab/sshd service trio are unchanged.

JupyterLab labextension (prebuilt in a throwaway builder stage, so the
runtime image stays Node-free):
  - Unsloth Dark (Monokai) theme, adaptive light/dark by system preference
  - Colab-style ArrowDown/Up cell navigation
  - top-bar Unsloth logo (stock Jupyter logo disabled and locked)
  - #@title lines render as collapsible Heading-2 form bars
  - Ctrl+A in a cell output selects only that output, not the whole
    notebook (the old behaviour ran notebook:select-all and was laggy)
  - right activity bar hidden by default
  - overrides.json: per-cell run button without auto-advance, labeled
    Restart and Run All, windowing off so collapsing an output does not
    snap to the cell top, news/update prompts suppressed

Studio and login branding: Unsloth favicon, page logo, and a dark
Unsloth login page that rotates through the curated Studio sloth
stickers (fail-soft to the logo).

Notebook organization and Colab compatibility (base image):
  - categorized folder view built from relative symlinks mirroring the
    README sections, rebuilt each boot; real .ipynb files never moved,
    and the symlink tree is invisible to the sync state machine
  - AMD-* notebooks shown only on an AMD/HIP host (autodetected)
  - Docker-only strip of the Colab "Run all on Colab" intro sentence
    from unedited notebooks (upstream notebooks unchanged)
  - hoist %%capture above a leading #@title form so the cell runs
  - the per-cell transformers-sidecar log is silent unless
    UNSLOTH_ENABLE_LOGGING=1

Dependency pinning and naming: the curated notebook extras are pinned to
their resolved versions for reproducible rebuilds; decord is split into
its own fail-soft install (no aarch64 wheel). The lean base image is
renamed from :base to :core.

Adds tests/validate_studio_features.py, a static self-test for the
labextension plugins, overrides keys, and branding wiring.
2026-06-25 16:22:41 +00:00

32 lines
1.4 KiB
Python

"""Baked IPython startup hook (copied to the profile's startup/ dir).
Runs once per kernel. Registers a pre_run_cell event that activates the right
transformers sidecar before the first model cell, using the version the
notebook's own install cell asked for (recorded by the pip/uv shim). Safe no-op
outside IPython, when no version was requested, or once transformers is imported.
"""
try:
import os
# Tell the pip/uv shim it's running inside a notebook kernel, so a cell's
# `!pip install ...` / `!uv pip install ...` (which inherits this env) gets
# the safe-install behaviour. Unset everywhere else => shim is a passthrough.
os.environ["UNSLOTH_NB_SHIM"] = "1"
import unsloth_nb_compat
unsloth_nb_compat.register_ipython()
except Exception as _e: # never break a kernel because of the helper
import sys
print(f"[unsloth-nb] startup hook skipped: {_e!r}", file = sys.stderr)
# Colab cell-magic compatibility (hoist `%%capture` above a leading `#@title`
# form so it fires instead of raising UsageError). Independent try/except so a
# failure here never disables the transformers-sidecar hook above and vice versa.
try:
import unsloth_colab_compat
unsloth_colab_compat.register_ipython()
except Exception as _e: # never break a kernel because of the helper
import sys
print(f"[unsloth-nb] colab-compat hook skipped: {_e!r}", file = sys.stderr)