Unsloth Docker Studio 品牌与许可署名保护机制解析:AGPLv3 归属声明的三重完整性守卫
发布时间:2026/9/30 6:49:38 作者:尧图编辑部 阅读量:1,286

人工智能大模型微调LoRA模型优化模型量化强化学习【免费下载链接】unslothLocal UI to run and train LLMs and diffusion models. Supports GGUF, MLX, Qwen3.8, DeepSeek-V4, MiniMax-H3, Gemma 4, FLUX and more.项目地址https://gitcode.com/GitHub_Trending/un/unsloth点击查看免费下载Unsloth Docker Studio 与 JupyterLab 镜像在构建产物中散布了完整的 Unsloth 归属声明attribution而保留这些声明不是可选的品牌美化而是 AGPLv3 许可协议下的硬性合规条件。本文以 docker/jupyter/BRANDING.md 为骨架结合 docker/jupyter/unsloth_branding.py、docker/Dockerfile.studio、docker/studio_launch.sh 与 docker/NOTICE 等源码完整梳理哪些内容必须保留、分散在哪些文件、通过什么机制在构建期与运行期强制校验帮助镜像维护者、二次分发者与安全审计者理解这套防白标white-label守卫的工程实现与许可边界。读完本文你将能解释 PHRASE 字面量为何必须字节级一致、--verify 校验器检查哪些资产以及镜像无法启动时那段错误横幅的来龙去脉。一、为什么署名是许可条件而不是构建检查Unsloth Docker Studio 镜像同时承载两份开源许可Unsloth Studio 以 GNU Affero General Public License v3.0AGPLv3授权见 studio/LICENSE.AGPL-3.0Unsloth Core 以 Apache License 2.0 授权见根目录 LICENSE。docker/NOTICE 依据 AGPLv3 第 7(b) 条将以下内容指定为镜像的Appropriate Legal Notice适当法律声明归属声明 Built by the Unsloth team版权行 Copyright 2026-Present the Unsloth team许可声明 Licensed under Apache 2.0 and the GNU AGPLv3显示于 JupyterLab 顶栏与加载 splash 的 Unsloth logo 与 Unsloth Dark 主题Help About 对话框及其中的 Source、Website、License、AGPLv3、Apache 链接。NOTICE 明确写道如果你向用户传达、修改或通过网络提供该镜像或其衍生作品就必须原样保留并向用户展示这些声明。删除或篡改它们——无论是改动构建流程、品牌源码还是完整性守卫本身——都不能免除这项许可义务。同时 NOTICE 也划清了边界本声明仅规范 AGPLv3 下的版权归属不授予任何商标许可Unsloth 及 Unsloth logo 仍是 Unsloth 团队的商标。二、必须保留的署名清单BRANDING.md 把必须保留的内容归纳为五条#必须保留的内容出现位置1Built by the Unsloth team登录页与 labextension2Copyright 2026-Present the Unsloth team各品牌界面3Licensed under Apache 2.0 and the GNU AGPLv3各品牌界面4Unsloth logo 与Unsloth Dark主题顶栏、加载 splash5Help About 对话框及其 Source/Website/License/AGPLv3/Apache 链接Help 菜单这些字符串的唯一事实来源canonical source有两处Python 侧的 docker/jupyter/unsloth_branding.py 与 TypeScript 镜像侧 docker/jupyter/unsloth_labext/src/branding.ts。其中最关键的一条规则是PHRASE字面量在两个文件之间必须字节级一致byte-identical因为守卫会在构建好的 labextension bundle 中直接 grep 这个完整字符串。unsloth_branding.py第 19–41 行集中定义了全部规范字符串PRODUCT Unsloth Docker Studio SHORT_LABEL Built by the Unsloth team SPLASH_LABEL Loading Unsloth Docker COPYRIGHT Copyright 2026-Present the Unsloth team AGPL_NOTICE Licensed under Apache 2.0 and the GNU AGPLv3 WEBSITE_URL https://unsloth.ai DOCS_URL https://unsloth.ai/docs SOURCE_URL https://github.com/unslothai/unsloth LICENSE_URL https://github.com/unslothai/unsloth#license AGPL_URL https://www.gnu.org/licenses/agpl-3.0.html APACHE_URL https://www.apache.org/licenses/LICENSE-2.0 # ONE literal, byte-identical to PHRASE in unsloth_labext/src/branding.ts PHRASE ( Unsloth Docker Studio and JupyterLab image. Built by the Unsloth team. Licensed under Apache 2.0 and the GNU AGPLv3. Source: https://github.com/unslothai/unsloth Website: https://unsloth.ai ) THEME_NAME Unsloth Dark LABEXT_NAME unsloth-jupyterlab ABOUT_PLUGIN_ID unsloth-jupyterlab:about SPLASH_PLUGIN_ID unsloth-jupyterlab:splash LOGO_DATA_URI_PREFIX data:image/png;base64,iVBOR对应的 docker/jupyter/unsloth_labext/src/branding.ts 声明了完全相同的常量并且注释明确强调PHRASE必须以单个字面量书写、不能拼接这样 webpack 在生产构建中会把它作为连续字符串保留下来守卫才能在压缩产物里完整地匹配到它。三、署名资产分布在哪些文件BRANDING.md 给出了一张资产清单表说明每份品牌内容各自承载在哪文件承载内容login.htmlJupyterLab 登录页与归属声明行unsloth_labext/src/branding.ts规范归属字符串TS 镜像unsloth_labext/src/about.tsHelp About 对话框与许可链接unsloth_labext/src/splash.ts加载 splash 的标语unsloth_labext/src/logo.ts内嵌的 Unsloth logo data URIunsloth_branding.py规范字符串与完整性守卫以下逐一说明各文件的实际实现均可在仓库中直接查看docker/jupyter/login.html基于 Jinja2 模板{% extends page.html %}重写 jupyter_server 默认登录页隐藏原生顶部 header渲染与 Unsloth DarkMonokai主题一致的深色居中卡片每次访问还会从sloth/01.png … 20.png中随机选一张 sloth 贴纸由构建阶段install_sloth_stickers.py从 Studio 前端资源复制贴纸缺失时通过onerror回退到 Unsloth logo。卡片下方即归属页脚Built by the Unsloth team. Apache 2.0/AGPLv3 License Link 版权行 源码/官网链接。docker/jupyter/unsloth_labext/src/about.ts注册unsloth:about命令在 Help 菜单mainMenu.helpMenu.addGroup与命令面板中加入 About Unsloth Docker Studio 入口弹窗正文仅使用 branding.ts 中的受信任常量拼接并把PHRASE写入data-unsloth-attribution数据属性保证它被原样打进 bundle 供守卫检索同时避免 innerHTML 注入面。docker/jupyter/unsloth_labext/src/splash.ts实现ISplashScreen提供者替换 JupyterLab 原生 splash原生 splash 在构建时被禁用并加锁使该插件成为唯一的 splash 提供者展示旋转的 Unsloth logo 与 Loading Unsloth Docker 标语并遵循prefers-reduced-motion无障碍约定。docker/jupyter/unsloth_labext/src/logo.ts把 Unsloth logo 以 base64 data URI 内嵌进 TS 源码使插件运行时不再依赖额外静态资源文件——这也是unsloth_branding.py中LOGO_DATA_URI_PREFIX data:image/png;base64,iVBOR前缀校验的由来。docker/jupyter/overrides.json镜像默认烘焙的 JupyterLab 设置覆盖包含theme: Unsloth Dark、adaptive-theme、笔记本Restart Run All按钮、关闭新闻推送等。此外docker/jupyter/jupyter_server_config.d/unsloth_branding_guard.json 负责把unsloth_branding注册为启用的 jupyter_server 扩展{ ServerApp: { jpserver_extensions: { unsloth_branding: true } } }unsloth_branding.py第 213–232 行正是通过_jupyter_server_extension_points()暴露扩展点、由_load_jupyter_server_extension(serverapp)在加载时执行校验。四、三重强制机制构建期、容器启动期、JupyterLab 加载期BRANDING.md 明确指出守卫guard在三处独立执行形成三层防线可对照 docker/Dockerfile.studio 与 docker/studio_launch.sh 验证构建期Build timepython -m unsloth_branding --verify在镜像构建阶段执行任何署名资产缺失或被篡改都会让构建直接失败。在 docker/Dockerfile.studio 中守卫模块、AGPLv3 许可证文本及其启用配置被复制进基础 venv随后立即执行 /opt/unsloth-venv/bin/python -m unsloth_branding --verify该文件第 239–249 行校验失败即中断构建。整镜像启动期Whole imagedocker/studio_launch.sh 在启动 supervisord 之前再次运行同一校验失败则拒绝启动容器。脚本第 143 行即为if ! /opt/unsloth-venv/bin/python -m unsloth_branding --verify; then ...。JupyterLab 加载期unsloth_branding同时作为 jupyter_server 扩展在服务加载时重新校验若容器启动后署名被剥离则拒绝对外提供 JupyterLab——_load_jupyter_server_extension会打印 banner 到 stderr、调用serverapp.log.critical并最终serverapp.exit(1)。三层机制在语义上有明确分工studio_launch.sh 负责容器启动前拦截jupyter_server 扩展则兜底那些绕过启动脚本直接运行 JupyterLab 的场景源码注释对此写得很直白studio_launch.sh refuses the container first; this backstops a direct run。五、守卫到底校验什么verify_branding 的检查清单unsloth_branding.py的核心函数verify_branding()第 108–186 行在解析出的资产路径上逐项检查任何一项不满足都会收集进problems列表并最终导致非零退出。检查项如下检查对象判定条件失败即记为问题AGPLv3 许可证文件文件缺失或内容中不含 GNU AFFERO GENERAL PUBLIC LICENSE 与 Version 3登录页 login.html文件缺失或缺少SHORT_LABEL、COPYRIGHT、SOURCE_URL、AGPLv3 任一标记overrides.json内容为空或未包含Unsloth Dark主题名labextension 的 package.json文件缺失/非合法 JSON或name不是unsloth-jupyterlab构建产物 bundle目录缺失或为空或缺少PHRASE、SHORT_LABEL、COPYRIGHT、AGPL_URL、ABOUT_PLUGIN_ID、SPLASH_PLUGIN_ID、LOGO_DATA_URI_PREFIX任一标记favicon / logo文件缺失或为空_nonempty_file仅检查 size 0page_config.json非法 JSON或disabledExtensions中禁用了unsloth-jupyterlab及其子插件 ID其中 bundle 扫描的逻辑_bundle_text第 94–105 行值得注意它把 labextension 静态目录下所有.jschunk 拼接成一个大字符串再逐个匹配标记因为生产构建只压缩标识符、不重写字符串字面量归属声明会原样存在于某一个 chunk 中。而page_config.json的检查针对一种特殊绕过方式disabledExtensions不会从磁盘删除 bundle但会在加载时把扩展剥离——因此守卫专门扫描所有可能的 page_config 位置含 jupyter_core 配置路径只要出现unsloth-jupyterlab或unsloth-jupyterlab:*前缀的禁用项就报错。路径解析由resolve_paths()第 44–76 行完成默认基于sys.prefix/share/jupyter、jupyter_server包目录与jupyter_config_path()推导所有受检资产的实际安装位置同时允许测试显式传入根路径测试即依赖此能力见下文。失败时banner()第 189–210 行会输出一段 72 字符宽的醒目横幅逐条列出所有缺失项并以SHORT_LABEL COPYRIGHT、Website、Source、License 收尾。CLI 入口main()第 235–250 行支持--verify校验失败退出码 1以及--venv-share、--jupyter-server-dir两个用于定位资产目录的参数校验通过时打印Unsloth branding integrity check passed (Unsloth Docker Studio, AGPLv3).。六、工程设计与许可哲学绊线tripwire而非锁BRANDING.md 用一段话概括了整个守卫的设计哲学The guard is a tripwire, not a lock. Anyone who forks the source controls the build and can edit any of these files. It exists to make accidental removal fail loudly and to make deliberate removal unambiguous.也就是说任何 fork 者本就掌控构建流程可以随意修改这些文件守卫不可能也不打算阻止蓄意移除。它的真实价值有两层让无意的删除大声失败浅层的 find-and-replace、漏拷贝、打包裁剪等误操作会在构建或启动阶段立刻暴露让蓄意的删除无可辩驳署名受 AGPLv3 的 Appropriate Legal Notice 保护见 docker/NOTICE在传达或网络提供服务前移除即构成许可违约守卫的存在使是否故意移除不再有模糊空间。围绕这一目标源码还做了几处刻意设计署名散布在多份独立文件中unsloth_branding.py的模块 docstring 明确写道归属声明spread over several independent files on purpose, so a shallow find-and-replace cannot white-label the image——一个全局替换不可能同时命中所有分散点。全文本、可读为主除 logo 的 base64 blob 外所有受检内容都是明文可读文本便于人审与自动化校验。PHRASE 双端字节一致Python 与 TS 两侧必须保持同一个完整句子构建守卫会在 bundle 中检索它about.ts又通过data-unsloth-attribution属性把它原样烙进 bundle形成双重保障。构建期资产迁移与锁定的配合docker/Dockerfile.studio 在构建时替换 favicon/logo/login.html、复制 sloth 贴纸并执行jupyter labextension disable/lock关闭原生 logo 与 splash 扩展、锁定unsloth-jupyterlab确保镜像里唯一的 logo/splash 提供者就是品牌化实现。七、镜像构建、运行与校验失败的运维视角从使用侧看这套机制与日常构建/运行命令直接相关。docker/Dockerfile.studio 文件头给出了标准用法# 构建本地基于已发布 base 或由 docker/Dockerfile 构建 docker buildx build --build-arg BASE_IMAGEunsloth/unsloth:core \ -f docker/Dockerfile.studio -t unsloth/unsloth:studio docker/ # 运行 docker run --rm --gpus all -p 8000:8000 -p 8888:8888 \ -v $HOME/.cache/huggingface:/workspace/.cache/huggingface \ -v unsloth-studio:/opt/unsloth-studio unsloth/unsloth:studio镜像默认暴露 8000Studio、8888JupyterLab、22sshd三个端口JupyterLab 密码由JUPYTER_PASSWORD环境变量指定未设置则打印随机密码。如果镜像构建或启动时品牌资产出了问题你会在两个地方看到那条横幅式错误构建阶段--verify失败导致整个docker build中断日志末尾是ERROR: Unsloth Docker Studio attribution / license integrity check failed.及逐条问题列表容器启动阶段unsloth-studio-launch拒绝拉起 supervisord--verify的非零退出码阻断容器启动对应 docker/studio_launch.sh 第 143 行。排查时可借助 CLI 的两个定位参数手动复现python -m unsloth_branding --verify --venv-share 路径 --jupyter-server-dir 路径以便在不完整环境中精确指出缺失的资产路径。八、测试与持续验证仓库用自动化测试固化了这一机制的行为最直接的是 tests/python/test_docker_studio_rocm_jupyter.py它通过importlib.util.spec_from_file_location直接加载仓库中的unsloth_branding.pyBRANDING DOCKER / jupyter / unsloth_branding.py调用resolve_paths(...)并断言 labextension 恰好落在守卫所检查的位置test_the_labextension_lands_where_the_branding_guard_looks断言构建流程中确实包含-m unsloth_branding --verify字样test_the_branding_chain...还比较 ROCm 与 CUDA 两种 Studio 镜像的品牌链完全一致test_the_branding_chain_matches_the_cuda_studio_image确保双后端镜像携带同一套署名与校验逻辑。这说明品牌守卫不是一次性脚本而是随 CI 持续验证的、跨镜像变体一致的契约。总结Unsloth Docker Studio 的品牌与许可署名保护本质上是把 AGPLv3 的 Appropriate Legal Notice 义务工程化为可自动验证的资产清单规范字符串以 Python/TypeScript 双源维护PHRASE字面量字节级同步署名分散在登录页、labextensionAbout/splash/logo与主题配置等多个独立文件中unsloth_branding.py作为构建期 CLI 校验器、容器启动前门卫与 jupyter_server 运行时扩展三合一守卫在构建、容器启动、JupyterLab 加载三个时机反复确认署名未被剥离。它刻意以绊线而非锁自居——不阻止 fork 者修改只让意外删除大声失败、蓄意删除无可抵赖。理解这套机制既有助于镜像维护者合规地二次分发也为安全审计者提供了一条品牌/许可完整性是否被篡改的快速验证路径。赞分享人工智能大模型微调LoRA模型优化模型量化强化学习【免费下载链接】unslothLocal UI to run and train LLMs and diffusion models. Supports GGUF, MLX, Qwen3.8, DeepSeek-V4, MiniMax-H3, Gemma 4, FLUX and more.项目地址https://gitcode.com/GitHub_Trending/un/unsloth点击查看免费下载相关推荐OpenCore Legacy Patcher 完整教程老款 Intel Mac 如何四步装回最新 macOSOpenCore Legacy Patcher 完整教程老款 Intel Mac 如何四步装回最新 macOS OpenCore Legacy Patcher操作系统固件驱动开发CherryHQ/cherry-studio开源协议AGPLv3许可证深度解析CherryHQ/cherry studio开源协议AGPLv3许可证深度解析 ? 引言开源AI桌面客户端的许可证选择 在当今AI技术飞速发展的时代开源项人工智能大模型AI 应用交互助手本地部署Litestar Guards 实战授权守卫、分层声明与 opt 选项机制Litestar Guards 实战授权守卫、分层声明与 opt 选项机制 Guards守卫是 Litestar 框架中专门负责 授权Authoriza后端Web框架上一篇CreamApi DLC解锁器终极教程新手快速上手指南下一篇终极指南如何为Bend构建全球化开发者社区 — 从零开始的国际化实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考