Co-authored-by: zty624 <164896039+zty624@users.noreply.github.com>
Co-authored-by: yhzx233 <16619108+yhzx233@users.noreply.github.com>
Co-authored-by: Monalissaa <50078799+Monalissaa@users.noreply.github.com>
This commit is contained in:
committed 2026-10-16 03:00:54 +00:00
commit 20f5592077
119 files changed
+5700

No files matched your search

+35
View File
@@ -0,0 +1,35 @@
name: Deploy homepage
on:
push:
branches: [main]
paths:
- 'website/**'
- '.github/workflows/deploy-pages.yml'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: github-pages
cancel-in-progress: false
jobs:
deploy:
if: github.repository == 'OpenMOSS/MOSS-Image'
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v6
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v4
with:
path: website
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
+36
View File
@@ -0,0 +1,36 @@
name: Publish ComfyUI plugin
on:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: publish-comfyui
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install publishing tool
run: python -m pip install comfy-cli
- name: Publish plugin
working-directory: comfyui/moss-image
env:
REGISTRY_ACCESS_TOKEN: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
run: |
test -n "$REGISTRY_ACCESS_TOKEN" || {
echo "Set the REGISTRY_ACCESS_TOKEN repository secret before publishing."
exit 1
}
comfy --skip-prompt --no-enable-telemetry node publish \
--token "$REGISTRY_ACCESS_TOKEN"
+40
View File
@@ -0,0 +1,40 @@
__pycache__/
*.py[cod]
.pytest_cache/
.venv/
*.egg-info/
build/
dist/
outputs/
/AGENTS.md
*.safetensors
*.bin
*.pt
*.pth
*.distcp
.env
.env.*
*credential*
github_ssh_public_key.txt
/tests/
/.github/workflows/tests.yml
/examples/
/docs/
/export_diffusers.py
.ruff_cache/
/ckpt/
/.aws
/.comfyui-tests/
# Local inference environments, configuration and artifacts
.venv*/
*.log
/local/
/models/
/input/
/output/
/user/
/comfyui/local/env.sh
# ComfyUI is installed locally by comfyui/local/setup.sh
/third_party/ComfyUI/
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+285
View File
@@ -0,0 +1,285 @@
<div align="center">
<p>
<img src="assets/lockup-light.svg#gh-light-mode-only" alt="MOSS-Image" width="520">
<img src="assets/lockup-dark.svg#gh-dark-mode-only" alt="MOSS-Image" width="520">
</p>
<p>
<a href="https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base"><img alt="Hugging Face · MOSS-Image-Base" src="https://img.shields.io/badge/🤗%20Hugging%20Face-MOSS--Image--Base-ffc107?style=flat-square"></a>
&nbsp;
<a href="https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT"><img alt="Hugging Face · MOSS-Image-SFT" src="https://img.shields.io/badge/🤗%20Hugging%20Face-MOSS--Image--SFT-ffc107?style=flat-square"></a>
&nbsp;
<a href="https://huggingface.co/spaces/OpenMOSS-Team/MOSS-Image"><img alt="Hugging Face Spaces · Demo" src="https://img.shields.io/badge/🤗%20Spaces-Demo-4f46e5?style=flat-square"></a>
&nbsp;
<a href="https://x.com/Open_MOSS"><img alt="Follow OpenMOSS on X" src="https://img.shields.io/badge/Follow-OpenMOSS-000000?style=flat-square&amp;logo=x&amp;logoColor=white"></a>
&nbsp;
<a href="https://qm.qq.com/q/hphM7VhaDu"><img alt="MOSS-Image QQ 交流群:755535143" src="https://img.shields.io/badge/QQ-755535143-12B7F5?style=flat-square&amp;logo=qq&amp;logoColor=white"></a>
&nbsp;
<a href="https://openmoss.github.io/MOSS-Image/"><img alt="Homepage" src="https://img.shields.io/badge/🌐%20Project-Homepage-2563eb?style=flat-square"></a>
&nbsp;
<a href="paper/MOSS_Image_Technical_Report.pdf"><img alt="Technical Report" src="https://img.shields.io/badge/📄%20Paper-Technical_Report-b31b1b?style=flat-square"></a>
</p>
<p>
<strong>English</strong> &nbsp; | &nbsp; <a href="README_ZH.md">简体中文</a>
</p>
</div>
## News
- **[2026-10-16]** 🎉 We are introducing **MOSS-Image-Base** and **MOSS-Image-SFT**! Code and model weights are publicly available.
**Our key highlights:**
- 📐 **Layout control:** Control the placement of text and visual elements.
- ✍️ **Strong text rendering:** Generate clear, accurate text within images.
- 📜 **Long-prompt support:** Accept text prompts of up to 4K tokens.
- 🎨 **Versatile visual styles:** Create high-quality anime and photorealistic images.
- 🛠️ **Easy to fine-tune:** Adapt the base model to custom tasks and domains.
- ⚡ **Compact and efficient:** Efficient image generation with a 5B backbone.
- 🖥️ **Heterogeneous GPU training**: Trained on alternative GPU platforms.
<a id="user-guide"></a>
## User guide
Start with the **[English user guide](USERGUIDE.md)** or **[中文用户指南](USERGUIDE_ZH.md)**
for recommended inference settings, prompt examples, layout input formats, and
LoRA training guidance.
<a id="comfyui"></a>
## ComfyUI
This repository provides a native MOSS-Image plugin for ComfyUI.
Search for **MOSS-Image** in **ComfyUI Manager** to install the plugin.
We are actively working toward integration into the official ComfyUI repository.
[Installation and usage](comfyui/README.md) · [Example workflow](comfyui/moss-image/example_workflows/moss-image.json)
<a id="prompt-enhancer"></a>
## Prompt enhancer skill
The [MOSS-Image Prompt Enhancer](skills/moss-image-prompt-enhancer/SKILL.md) turns
image ideas into detailed captions or spatial Layout prompts. It is designed for
GPT-6-family agents with local file and Python tools. The bundled script converts
pixel-coordinate drafts into compact JSON with integer centered coordinates;
it does not call an image-generation service.
Install the [skill folder](skills/moss-image-prompt-enhancer) in your agent's skills
directory, then invoke `$moss-image-prompt-enhancer` with your image idea, desired
caption or Layout output, and any canvas dimensions. Paste the compiled result
into MOSS-Image's positive prompt; for Layout, use the same generation dimensions.
![MOSS-Image-Base and MOSS-Image-SFT](assets/teaser.webp)
## Contents
- [News](#news)
- [User guide](#user-guide)
- [ComfyUI](#comfyui)
- [Prompt enhancer skill](#prompt-enhancer)
- [Models](#models)
- [Quick start](#quick-start)
- [Installation](#installation)
- [Python](#python)
- [Gradio](#gradio)
- [Sampling settings](#sampling-settings)
- [Memory and performance](#memory-and-performance)
- [Layout-to-image generation](#layout-generation)
- [Showcase](#showcase)
- [Citation](#citation)
- [License and acknowledgements](#license)
<a id="models"></a>
## 🤗 Models
| Model | Description |
| --- | --- |
| [MOSS-Image-Base](https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base) | Base text-to-image model |
| [MOSS-Image-SFT](https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT) | Fine-tuned from MOSS-Image-Base on curated data |
### Base vs. SFT
In this example, SFT produces clearer text grouping and a more organized whiteboard layout.
| MOSS-Image-Base | MOSS-Image-SFT |
| --- | --- |
| ![MOSS-Image-Base](assets/comparison/base.webp) | ![MOSS-Image-SFT](assets/comparison/sft.webp) |
<!-- MOSS-Image-Base uses a 42-layer diffusion transformer, a Qwen3.5-9B text encoder,
and a FLUX.2 VAE. -->
<a id="quick-start"></a>
## 🚀 Quick start
<a id="installation"></a>
### 🛠️ Installation
```bash
git clone https://github.com/OpenMOSS/MOSS-Image.git
cd MOSS-Image
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
<a id="python"></a>
### 🐍 Python
```python
import torch
from diffusers import DiffusionPipeline
pipe = DiffusionPipeline.from_pretrained(
"OpenMOSS-Team/MOSS-Image-Base",
custom_pipeline="pipeline_moss_image",
trust_remote_code=True,
torch_dtype={"default": torch.bfloat16, "vae": torch.float32},
)
pipe.scheduler = type(pipe.scheduler).from_config(pipe.scheduler.config)
pipe.to("cuda")
image = pipe(
"A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:“\n记得买牛奶和鸡蛋!\n牛奶两盒,鸡蛋一打。\n顺便带一袋面包。”",
height=1456,
width=1456,
num_inference_steps=50,
guidance_scale=3.0,
uncond_skip_layers=[22],
generator=torch.Generator("cpu").manual_seed(42),
).images[0]
image.save("refrigerator_note.png")
```
<a id="gradio"></a>
### 🎨 Gradio
```bash
pip install -e '.[ui]'
python gradio_app.py --model OpenMOSS-Team/MOSS-Image-Base
```
<a id="sampling-settings"></a>
### 🎛️ Sampling settings
| Setting | Default |
| --- | --- |
| Sampler | Flow-matching Euler |
| Steps | 50 |
| CFG | 3 |
| Shift | 5 |
| Layer skipping | Negative-branch skipping at layer 22 |
| Negative prompt (Python API) | Empty |
See the [user guide](USERGUIDE.md) for sampling and prompt recommendations.
<a id="memory-and-performance"></a>
### ⚡ Memory and performance
Select Memory mode in Gradio's Advanced settings:
| Mode | Behavior |
| --- | --- |
| GPU resident | Keep the entire model on GPU |
| Component | Move model components between CPU and GPU as needed |
| Sequential · fallback | Lower memory use with slower inference |
If GPU memory is insufficient, select Sequential or reduce image size.
Compile DiT is disabled by default and unavailable in Sequential mode.
<a id="layout-generation"></a>
## 📐 Layout-to-image generation
MOSS-Image uses JSON layout inputs to control text placement and object arrangement
in complex text-to-image compositions. The image below was generated by MOSS-Image
using layout control.
Layouts can also support controlled editing and user-friendly layout tools.
By editing text, element descriptions, and bounding boxes, users can adjust
image content and composition in a structured way.
[![Layout bounding boxes](assets/showcase/layout-bboxes.webp)](assets/showcase/layout-bboxes.svg)
Paste the layout JSON into Gradio’s Prompt field to specify the scene, text,
objects, and their positions. The following example uses a `summary`/`items` layout for a **1024×1024**
canvas. Save it as `layout.json`:
```json
{
"summary": {
"meta": ["poster"],
"canvas": "single",
"caption": "A minimalist travel poster with a cream background, a blue mountain illustration, and the title EXPLORE at the top."
},
"items": [
{
"label": "text",
"caption": "Large dark-blue uppercase title centered at the top.",
"text": "EXPLORE",
"bbox": [-416, -384, -288, 384]
},
{
"label": "object",
"caption": "A flat blue mountain illustration in the lower center.",
"bbox": [-192, -288, 384, 288]
}
],
"bbox_coord_space": "abs_centralized",
"bbox_format": "yxyx"
}
```
- `summary.caption` describes the overall scene and style.
- `items` describes individual elements: `label`, `caption`, and `bbox`, with
`text` for the words to render.
- `bbox_format: "yxyx"` specifies `[y_min, x_min, y_max, x_max]`.
- `bbox_coord_space: "abs_centralized"` uses pixel coordinates relative to the
canvas center. On a 1024×1024 canvas, each axis runs from −512 to +512;
x increases to the right and y increases downward. For a canvas of width W
and height H, subtract W/2 from ordinary x coordinates and H/2 from y coordinates.
Keep the coordinates consistent with the requested output dimensions. In Gradio,
paste the JSON into the prompt field and set the matching width and height. With
the Python API, pass `json.dumps(layout, ensure_ascii=False)` as the prompt string.
<a id="showcase"></a>
## 🖼️ Showcases
![Examples overview](assets/showcase/overview.webp)
![Examples overview 2](assets/showcase/overview2.webp)
<a id="citation"></a>
## 📝 Citation
If you use MOSS-Image in your research, please cite this repository:
```bibtex
@misc{mossimage2026,
title = {MOSS-Image},
author = {{OpenMOSS Team}},
year = {2026},
howpublished = {\url{https://github.com/OpenMOSS/MOSS-Image}}
}
```
<a id="license"></a>
## 📄 License and acknowledgements
The standalone pipeline code is provided under the [Apache License 2.0](LICENSE).
We thank the Diffusers, Qwen and FLUX teams.
+275
View File
@@ -0,0 +1,275 @@
<div align="center">
<p>
<img src="assets/lockup-light.svg#gh-light-mode-only" alt="MOSS-Image" width="520">
<img src="assets/lockup-dark.svg#gh-dark-mode-only" alt="MOSS-Image" width="520">
</p>
<p>
<a href="https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base"><img alt="Hugging Face · MOSS-Image-Base" src="https://img.shields.io/badge/🤗%20Hugging%20Face-MOSS--Image--Base-ffc107?style=flat-square"></a>
&nbsp;
<a href="https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT"><img alt="Hugging Face · MOSS-Image-SFT" src="https://img.shields.io/badge/🤗%20Hugging%20Face-MOSS--Image--SFT-ffc107?style=flat-square"></a>
&nbsp;
<a href="https://huggingface.co/spaces/OpenMOSS-Team/MOSS-Image"><img alt="Hugging Face Spaces · Demo" src="https://img.shields.io/badge/🤗%20Spaces-Demo-4f46e5?style=flat-square"></a>
&nbsp;
<a href="https://x.com/Open_MOSS"><img alt="Follow OpenMOSS on X" src="https://img.shields.io/badge/Follow-OpenMOSS-000000?style=flat-square&amp;logo=x&amp;logoColor=white"></a>
&nbsp;
<a href="https://qm.qq.com/q/hphM7VhaDu"><img alt="MOSS-Image QQ 交流群:755535143" src="https://img.shields.io/badge/QQ-755535143-12B7F5?style=flat-square&amp;logo=qq&amp;logoColor=white"></a>
&nbsp;
<a href="https://openmoss.github.io/MOSS-Image/"><img alt="Homepage" src="https://img.shields.io/badge/🌐%20Project-Homepage-2563eb?style=flat-square"></a>
&nbsp;
<a href="paper/MOSS_Image_Technical_Report.pdf"><img alt="Technical Report" src="https://img.shields.io/badge/📄%20Paper-Technical_Report-b31b1b?style=flat-square"></a>
</p>
<p>
<a href="README.md">English</a> &nbsp; | &nbsp; <strong>简体中文</strong>
</p>
</div>
<a id="news"></a>
## 动态
- **[2026-10-16]** 🎉 **MOSS-Image-Base** 和 **MOSS-Image-SFT** 正式发布!代码和模型权重已开放。
**核心特点:**
- 📐 **布局控制:** 控制文字与视觉元素的位置。
- ✍️ **文字渲染:** 在图像中生成清晰、准确的文字。
- 📜 **长提示词支持:** 支持最长 4K tokens 的文本提示词。
- 🎨 **多样视觉风格:** 生成高质量的动漫风格与照片级写实图像。
- 🛠️ **易于微调:** 将基础模型适配到自定义任务和领域。
- ⚡ **紧凑高效:** 基于 5B 主干网络,实现高效图像生成。
- 🖥️ **异构 GPU 训练:** 采用替代 GPU 平台训练。
<a id="user-guide"></a>
## 用户指南
推荐推理参数、提示词示例、布局输入格式和 LoRA 训练建议,见
**[中文用户指南](USERGUIDE_ZH.md)** 或 **[English user guide](USERGUIDE.md)**。
<a id="comfyui"></a>
## ComfyUI
本仓库实现了 MOSS-Image 的 ComfyUI 原生插件。
在 **ComfyUI Manager** 中搜索 **MOSS-Image** 即可安装插件。
我们正在积极推进合入 ComfyUI 官方仓库。
[安装与使用](comfyui/README_ZH.md) · [示例工作流](comfyui/moss-image/example_workflows/moss-image.json)
<a id="prompt-enhancer"></a>
## 提示词增强 Skill
[MOSS-Image Prompt Enhancer](skills/moss-image-prompt-enhancer/SKILL.md) 可将图像想法
扩写为详细 caption 或空间 Layout 提示词,面向具备本地文件和 Python 工具的 GPT-6
系列代理设计。随附脚本将像素坐标草稿转换为紧凑 JSON 和整数中心坐标,不调用图像生成服务。
将 [skill 目录](skills/moss-image-prompt-enhancer) 安装到代理的技能目录后,使用
`$moss-image-prompt-enhancer`,提供图像需求、caption 或 Layout 输出要求,以及画布尺寸。
将编译结果粘贴到 MOSS-Image 的正向提示词中;使用 Layout 时,生成尺寸应与草稿一致。
![MOSS-Image-Base 和 MOSS-Image-SFT](assets/teaser.webp)
## 目录
- [动态](#news)
- [用户指南](#user-guide)
- [ComfyUI](#comfyui)
- [提示词增强 Skill](#prompt-enhancer)
- [模型](#models)
- [快速开始](#quick-start)
- [安装](#installation)
- [Python](#python)
- [Gradio](#gradio)
- [采样参数](#sampling-settings)
- [显存与性能](#memory-and-performance)
- [Layout 布局生成](#layout-generation)
- [Showcase](#showcase)
- [引用](#citation)
- [许可与致谢](#license)
<a id="models"></a>
## 🤗 模型
| 模型 | 说明 |
| --- | --- |
| [MOSS-Image-Base](https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base) | 基础文生图模型 |
| [MOSS-Image-SFT](https://huggingface.co/OpenMOSS-Team/MOSS-Image-SFT) | 在精选数据上对 MOSS-Image-Base 微调得到的模型 |
### Base 与 SFT 对比
在这个例子中,SFT 的文字分组更清晰,白板内容的排版更有条理。
| MOSS-Image-Base | MOSS-Image-SFT |
| --- | --- |
| ![MOSS-Image-Base](assets/comparison/base.webp) | ![MOSS-Image-SFT](assets/comparison/sft.webp) |
<!-- MOSS-Image-Base 使用 42 层扩散 Transformer、Qwen3.5-9B 文本编码器和 FLUX.2 VAE。 -->
<a id="quick-start"></a>
## 🚀 快速开始
<a id="installation"></a>
### 🛠️ 安装
```bash
git clone https://github.com/OpenMOSS/MOSS-Image.git
cd MOSS-Image
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
<a id="python"></a>
### 🐍 Python
```python
import torch
from diffusers import DiffusionPipeline
pipe = DiffusionPipeline.from_pretrained(
"OpenMOSS-Team/MOSS-Image-Base",
custom_pipeline="pipeline_moss_image",
trust_remote_code=True,
torch_dtype={"default": torch.bfloat16, "vae": torch.float32},
)
pipe.scheduler = type(pipe.scheduler).from_config(pipe.scheduler.config)
pipe.to("cuda")
image = pipe(
"A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:“\n记得买牛奶和鸡蛋!\n牛奶两盒,鸡蛋一打。\n顺便带一袋面包。”",
height=1456,
width=1456,
num_inference_steps=50,
guidance_scale=3.0,
uncond_skip_layers=[22],
generator=torch.Generator("cpu").manual_seed(42),
).images[0]
image.save("refrigerator_note.png")
```
<a id="gradio"></a>
### 🎨 Gradio
```bash
pip install -e '.[ui]'
python gradio_app.py --model OpenMOSS-Team/MOSS-Image-Base
```
<a id="sampling-settings"></a>
### 🎛️ 采样参数
| 参数 | 默认值 |
| --- | --- |
| 采样器 | Flow-matching Euler |
| 步数 | 50 |
| CFG | 3 |
| Shift | 5 |
| 跳层 | 负向分支跳过第 22 层 |
| 负面提示词(Python API) | 空 |
采样与提示词建议见[用户指南](USERGUIDE_ZH.md)。
<a id="memory-and-performance"></a>
### ⚡ 显存与性能
在 Gradio 的高级设置中选择 Memory mode:
| 模式 | 行为 |
| --- | --- |
| GPU resident | 全模型驻留 GPU |
| Component | 按需在 CPU 与 GPU 之间移动模型组件 |
| Sequential · fallback | 更低显存占用,推理速度较慢 |
显存不足时,选择 Sequential 或减小图像尺寸。
Compile DiT 默认关闭,Sequential 模式下不可用。
<a id="layout-generation"></a>
## 📐 Layout 布局生成
MOSS-Image 通过 JSON layout 输入控制复杂画面中的文字排版与物体布局,下图即为
MOSS-Image 使用布局控制生成的结果。
基于 layout,我们还可以实现受控编辑、用户友好的排版工具等应用。
通过修改文字、元素描述和边界框,用户可以结构化地调整画面内容与布局。
[![布局边界框](assets/showcase/layout-bboxes.webp)](assets/showcase/layout-bboxes.svg)
将布局 JSON 粘贴到 Gradio 的 Prompt 输入框,即可指定场景、文字、物体及其位置。
下面使用 `summary`/`items` 格式,以 **1024×1024** 画布为例,将内容保存为 `layout.json`:
```json
{
"summary": {
"meta": ["poster"],
"canvas": "single",
"caption": "A minimalist travel poster with a cream background, a blue mountain illustration, and the title EXPLORE at the top."
},
"items": [
{
"label": "text",
"caption": "Large dark-blue uppercase title centered at the top.",
"text": "EXPLORE",
"bbox": [-416, -384, -288, 384]
},
{
"label": "object",
"caption": "A flat blue mountain illustration in the lower center.",
"bbox": [-192, -288, 384, 288]
}
],
"bbox_coord_space": "abs_centralized",
"bbox_format": "yxyx"
}
```
- `summary.caption`:整体场景与风格描述。
- `items`:各元素的 `label`、`caption` 和 `bbox`;需要生成文字时使用 `text` 指定内容。
- `bbox_format: "yxyx"`:框坐标顺序为 `[y_min, x_min, y_max, x_max]`。
- `bbox_coord_space: "abs_centralized"`:以画布中心为原点的像素坐标。
对于 1024×1024 画布,两轴范围均为 −512 到 +512,x 向右、y 向下递增。
对于宽 W、高 H 的画布,将常规左上角原点的 x 坐标减去 W/2、y 坐标减去 H/2 即可转换。
框坐标应与指定的输出尺寸一致。在 Gradio 中,将 JSON 粘贴到提示词输入框,
并设置对应的宽高;使用 Python API 时,将 `json.dumps(layout, ensure_ascii=False)`
作为提示词字符串传入。
<a id="showcase"></a>
## 🖼️ Showcase
![示例总览](assets/showcase/overview.webp)
![示例总览 2](assets/showcase/overview2.webp)
<a id="citation"></a>
## 📝 引用
如果你在研究中使用 MOSS-Image,请引用本仓库:
```bibtex
@misc{mossimage2026,
title = {MOSS-Image},
author = {{OpenMOSS Team}},
year = {2026},
howpublished = {\url{https://github.com/OpenMOSS/MOSS-Image}}
}
```
<a id="license"></a>
## 📄 许可与致谢
推理代码采用 [Apache License 2.0](LICENSE)。
感谢 Diffusers、Qwen 和 FLUX 团队。
+111
View File
@@ -0,0 +1,111 @@
# MOSS-Image-Base User Guide
## Inference Parameters
As a base model, MOSS-Image-Base has not undergone any post-training or distillation of inference parameters such as CFG. Our goal is to preserve the training information in full and make it easier for the community to train LoRAs. This also means that users need suitable inference settings to get the best results. Here are our recommendations:
* **Resolution**: We recommend outputs with **1M, 1.5M, or 2M** total pixels. The model can also extrapolate to arbitrary resolutions from 0.25M (`512×512`) to 4M (2K).
* **Aspect Ratio**: We support arbitrary aspect ratios. Gradio’s resolution and aspect-ratio controls calculate dimensions aligned to multiples of 16. In the Python API, or when entering dimensions manually, use positive multiples of 16; invalid dimensions raise an error.
* **Inference Steps**: Best results are achieved with **≥ 50** steps.
* **CFG**: Default **3.0** (recommended range: 3.0–6.0). A value of 3.0 is generally sufficient for long prompts; for short prompts, we recommend increasing it as needed.
* **Shift**: Default **5.0**.
* **Sampler**: **Euler** is the recommended default.
* **SLG (Skip Layer Guidance)**: We have implemented two variants:
* **Standard SLG**: scale 3, 0.01-1.0.
* **Two-Pass Sampling SLG**: We recommend `uncond skip`, with **22** as the recommended skip layer (0-indexed). Layers 22, 24, and 26 can all help improve image quality.
Turning off SLG will make the output image look very realistic, but it may also cause some details to collapse.
## Prompt Guidelines
MOSS-Image-Base supports multiple input formats, including natural language, tag sequences, and JSON layouts.
* **Language**: We recommend **English**, which has the most training data. Chinese and other languages are also supported.
* **Negative Prompt**: Based on our tests, we recommend the following effective negative tags:
```text
nsfw, worst quality, bad anatomy, watermark, jpeg artifact
```
* **Recommended Tag Order**: For the best results with tag sequences, we recommend the order Quality -> Score -> Meta -> Year -> Character -> Series -> Artist -> General. For example:
```text
best quality, highres, hatsune miku, vocaloid, @foo bar, 1girl, blue hair
```
* **Text Layout**: The model can render text and insert line breaks automatically, but the result may not always match your expectations. To improve text accuracy or control line breaks precisely, insert `\n` or actual line breaks directly into the prompt.
Here are some recommended example prompts:
```text
prompt:
一个穿着"MOSI"标志的T恤的中国美女正拿着黑色的马克笔面向镜头微笑。她身后的玻璃板上手写体写着 "一、MOSS-Image的技术路线:5B 的单流 DiT 模型,基于 Muon 训练。二、MOSS-Image的模型特色:1、复杂文字渲染。支持中英渲染、自动布局; 2、使用 Layout 进行精准图像控制,支持文字编辑和物体增减等自由编辑。三、MOSS-Image的后续发展:探索 R2I 参考生图、助力生成式AI发展。"
negative prompt:
worst quality, bad anatomy
```
```text
prompt:
A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:
“记得买牛奶和鸡蛋!
牛奶两盒,鸡蛋一打。
顺便带一袋面包。”
negative prompt:
```
### Layout Prompts (Experimental)
MOSS-Image-Base explores layout control for text-to-image generation and currently supports input in the following JSON format:
```json
{
"summary": {
"meta": ["poster"],
"canvas": "single",
"caption": "A minimalist travel poster with a cream background, a blue mountain illustration, and the title EXPLORE at the top."
},
"items": [
{
"label": "text",
"caption": "Large dark-blue uppercase title centered at the top.",
"text": "EXPLORE",
"bbox": [-416, -384, -288, 384]
},
{
"label": "object",
"caption": "A flat blue mountain illustration in the lower center.",
"bbox": [-192, -288, 384, 288]
}
],
"bbox_coord_space": "abs_centralized",
"bbox_format": "yxyx"
}
```
The fields are defined as follows:
- `summary.caption`: A description of the overall scene and style.
- `items`: Each element's category (`label`), description (`caption`), and bounding box (`bbox`). Use `text` to specify the content when rendering text.
- `bbox_format: "yxyx"`: Coordinates are ordered as `[y_min, x_min, y_max, x_max]`.
- `bbox_coord_space: "abs_centralized"`: Absolute pixel coordinates with the canvas center as the origin (x increases to the right and y increases downward). For example, a 1024×1024 canvas ranges from -512 to +512 on both axes. For a canvas of width W and height H, subtract W/2 and H/2 from conventional top-left-origin x and y coordinates, respectively, to convert to this coordinate system.
> Some recent work uses relative coordinates for layout control. We use absolute pixel coordinates, which we believe are better suited to layout control across different resolutions and aspect ratios.
The model supports combining natural language and structured input.
## Prompt Enhancer and Layout Enhancer
The MOSS-Image series natively supports layouts, enabling many interesting applications and expanding the models' capabilities. This also makes the models more difficult to use.
To address this, we use two approaches to layout enhancement. The training-free approach uses a carefully tuned skill with an LLM to provide basic layout planning. The other approach fine-tunes an open-source LLM directly as a layout enhancer. Stay tuned.
## Post-Training
### LoRA Training Recommendations
We have found that simple SFT can enable features such as GIF generation and reference-based generation in MOSS-Image-Base. Stay tuned.
If you post-train MOSS-Image-Base yourself, keep the text encoder frozen. Do not fine-tune it.
### Few-Step Distillation
We are actively working on few-step distillation methods such as DMD. Stay tuned.
+111
View File
@@ -0,0 +1,111 @@
# MOSS-Image-Base 用户指南
## 推理参数配置
作为纯粹的 Base Model, MOSS-Image-Base 没有做过任何后训练, 也没有做 CFG 等推理参数的蒸馏. 我们的本意是完整保留训练信息, 方便社区训练 LoRA; 但同时, 这也要求用户需要使用合适的参数配置才能发挥出最佳效果. 以下是我们的推荐配置:
* **分辨率 (Resolution)**: 我们推荐使用 **1M、1.5M、2M** 的总像素数输出.此外, 模型可以外推至 0.25M (`512×512`) 到 4M(2K)的任意分辨率输出.
* **长宽比 (Aspect Ratio)**: 我们支持任意长宽比。Gradio 的分辨率和长宽比控件会计算对齐到 16 倍数的尺寸;使用 Python API 或手动输入宽高时,必须提供 16 的正整数倍,否则会报错。
* **推理步数 (Steps)**: **≥ 50** 步时效果最佳.
* **CFG**: 默认 **3.0**(推荐范围 3.0 - 6.0). 常规长 Prompt 用 3.0 即可; 短 Prompt 建议适当调高.
* **Shift**: 默认 **5.0**.
* **采样器 (Sampler)**: 默认推荐 **Euler**.
* **SLG (Skip Layer Guidance)**: 我们实现了两种方式:
* **标准 SLG**: scale 3, 0.01-1.0.
* **二次采样 SLG**: 推荐使用 `uncond skip`, skip layer 推荐为 **22**(0-index). layer 22, 24, 26 都对改善图像质量有帮助.
关闭 SLG 会使输出的图像非常真实, 但是可能会造成细节的崩坏.
## Prompt 规范
MOSS-Image-Base 支持自然语言、Tag 串以及 JSON Layout 等多种输入格式.
* **语言**: 默认推荐**英文**(训练量最多), 同时也支持中文等多语言输入.
* **负面提示词 (Negative Prompt)**: 经过测试, 我们推荐下面这些有效的负面 tag:
```text
nsfw, worst quality, bad anatomy, watermark, jpeg artifact
```
* **Tag 推荐顺序**: 为了在 tag 串中实现最好的性能, 我们推荐使用 Quality -> Score -> Meta -> Year -> Character -> Series -> Artist -> General 的顺序构造. 以下是一个 Example:
```text
best quality, highres, hatsune miku, vocaloid, @foo bar, 1girl, blue hair
```
* **文字排版**: 模型支持生成文字并自动换行, 但未必完全符合预期. 如过需要追求文本的正确率, 或者精确控制换行, 请在 prompt 中手动添加 `\n` 或者直接换行.
推荐的 prompt examples:
```text
prompt:
一个穿着"MOSI"标志的T恤的中国美女正拿着黑色的马克笔面向镜头微笑。她身后的玻璃板上手写体写着 "一、MOSS-Image的技术路线:5B 的单流 DiT 模型,基于 Muon 训练。二、MOSS-Image的模型特色:1、复杂文字渲染。支持中英渲染、自动布局; 2、使用 Layout 进行精准图像控制,支持文字编辑和物体增减等自由编辑。三、MOSS-Image的后续发展:探索 R2I 参考生图、助力生成式AI发展。"
negative prompt:
worst quality, bad anatomy
```
```text
prompt:
A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:
“记得买牛奶和鸡蛋!
牛奶两盒,鸡蛋一打。
顺便带一袋面包。”
negative prompt:
```
### Layout Prompt(实验性功能)
MOSS-Image-Base 探索了文生图中的布局控制,目前支持通过以下 JSON 格式输入:
```json
{
"summary": {
"meta": ["poster"],
"canvas": "single",
"caption": "A minimalist travel poster with a cream background, a blue mountain illustration, and the title EXPLORE at the top."
},
"items": [
{
"label": "text",
"caption": "Large dark-blue uppercase title centered at the top.",
"text": "EXPLORE",
"bbox": [-416, -384, -288, 384]
},
{
"label": "object",
"caption": "A flat blue mountain illustration in the lower center.",
"bbox": [-192, -288, 384, 288]
}
],
"bbox_coord_space": "abs_centralized",
"bbox_format": "yxyx"
}
```
其中,
- `summary.caption`: 整体场景与风格描述。
- `items`:各元素的类别(label)、描述(caption)和位置框(bbox)。生成文字时需用 text 指定内容。
- `bbox_format: "yxyx"`:坐标顺序为 `[y_min, x_min, y_max, x_max]`。
- `bbox_coord_space: "abs_centralized"`:以画布中心为原点的绝对像素坐标(x 向右、y
向下递增)。例如 1024×1024 画布的范围是 -512 到 +512。对于宽 W、高 H 的画布,将常规左上角原点的 x、y 分别减去 W/2 和 H/2 即可转换。
> 我们注意到,一些近期工作采用相对坐标进行布局控制。我们选择使用绝对像素坐标,认为这种表示更适合不同分辨率和长宽比下的布局控制。
模型支持自然语言和结构化语言的混合输入。
## Prompt Enhancer and Layout Enhancer
MOSS-Image 系列原生支持 layout, 这给我们的模型带来了很多有趣的功能, 提升了模型能力的上限, 同时也变相增加了用户使用的困难.
为了解决这个问题, 我们暂时提供了两种 layout enhance 方法. Training free 的方法是使用精心微调的 skill, 使用 LLM 接入来提供简单的 layout 规划功能; 另外一种是直接微调一个开源的 LLM 作为 layout enhancer. 敬请期待.
## 后训练
### LoRA
我们发现通过简单 SFT, MOSS-Image-Base 能够实现诸如 gif 生成, 参考生成等 feature. 敬请期待.
如果你要自己后训练 MOSS-Image-Base, 请保持 Text Encoder 冻结, 不要微调 Text Encoder.
### 少步蒸馏
我们正在积极推进 DMD 等少步蒸馏方法. 敬请期待.
+21
View File
@@ -0,0 +1,21 @@
# Assets
- `images/<name>/`: live Gradio examples, each with `parameters.json` and an image.
The JSON `image` field names the image file, relative to that example directory.
Edit `parameters.seed` to set the example seed; `null` means the original seed is
unknown and selects random generation. Examples retain their recorded prompts, seeds and sampling settings.
The UI polls every two seconds. Editing the selected example reloads its fields;
adding/removing folders updates the gallery. Write complete JSON files atomically
to avoid exposing incomplete edits. Runtime memory/compile settings stay unchanged.
- `samples/`: selected MOSS-Image outputs, each accompanied by its `parameters.json`.
The Gradio app saves each run to `outputs/gradio/<run-id>/`, including PNG images
and a JSON record of the prompt, negative prompt, actual seed, dimensions, sampling
parameters, memory mode, model name, configuration hashes and software versions.
After validating a result, copy its complete run folder into `samples/<sample-name>/`.
Only add real model outputs; do not use placeholder art as a model-quality example.
The model directory is supplied separately so sample metadata does not publish
local filesystem paths. Model configuration hashes do not fingerprint the weights:
keep the exact checkpoint/revision when curating a sample. Seeds alone cannot
ensure identical results across different hardware or library versions.
View File
Whitespace-only changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

View File
Whitespace-only changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"natural roadside environmental photograph with a humorous Chinese notice sign\",\"gen_brief\":\"A relaxed, photorealistic environmental photograph at pedestrian eye level along a quiet rural road. A battered dark green notice sign stands on the gravel-and-grass shoulder, naturally integrated into the landscape and occupying approximately one fifth of the image area. The road fills much of the left and lower frame and curves toward distant trees; sky, irregular foliage and ample foreground provide breathing room. Preserve the main sign body's approximately 30-degree perspective yaw, left edge nearer and right edge receding, plus its 15-degree clockwise lean in the image plane. Keep the camera and horizon level. Two visibly bent, kinked galvanized posts bow right above firmly planted bases and remain attached to the board. The sign has a pronounced LOCALIZED, asymmetric sheet-metal fold, not a uniformly curved or globally bent surface. Most of the left, center and lower board remains approximately flat in its existing orientation. Only an upper-right patch folds toward the camera approximately 35 degrees relative to that main plane, along a diagonal plastic crease running from near (820, 555) at the top edge to near (980, 950) at the right edge. The corner tip projects near (1030, 605). This produces two distinct connected surface orientations, a sharply kinked outline, an irregular crease ridge, small compression wrinkles, chipped paint along the fold and a narrow self-shadow. The bent patch is part of the same continuous metal sheet, not a detached plate, pasted-on triangle or missing chunk. Avoid a smooth cylindrical bow, a symmetrical V-fold, a fold across the entire width or mere additional rigid rotation. Keep the local damage clearly visible but do not fold the printed face shut or hide substantial text. Add restrained edge dents, rusty scratches, exposed dull metal and two small punctures in blank margins. No flames, smoke, weapons or active conflict. Ordinary photographic perspective, soft afternoon daylight, restrained colors, dust and grass at the feet; no strong glare, dramatic spotlight or artificial background blur. The scuffed thin white border follows both the overall perspective and the local crease. The official design contrasts with the humorous essay. The three text objects are a centered white heading and two body columns read down the left column then down the right. Every glyph is printed on the physical metal: most text follows the original yaw and clockwise lean, while the upper-right text fragments crossing the crease bend with the local folded patch. Their baselines change direction at the crease and their local spacing foreshortens naturally; no floating upright text, straight lettering across a bent surface, duplicated words or erased passages. Preserve the near left column's larger scale and far right column's reduced scale. Axis-aligned text boxes are enclosing guides, not visible rectangles; their envelopes may overlap, but actual printed columns remain separate. Approximate base-plane column guides in top-left, top-right, bottom-right, bottom-left order are: left (523, 567), (768, 632), (590, 1299), (345, 1233); right (784, 666), (1010, 726), (848, 1331), (622, 1270). These guide the undamaged layout only; locally warp the upper-right fragments to the folded surface instead of enforcing a single planar projection across the entire sign. The text objects' identity strings are the exact Chinese lettering. Preserve every character and explicit newline, including blank paragraph lines; never print escape sequences literally. Use a bold Chinese sans-serif heading approximately 49 pixels high before rotation, body lettering approximately 12 pixels on the near side decreasing toward the far side, and approximately 16-pixel near-column and 15-pixel far-column line spacing before projection. Keep six paragraphs per column and the entire essay. The heading remains noticeable while the body appears as naturally small, dense information at this distance. Do not enlarge the sign to fill the frame. No additional lettering, logos or watermarks.\",\"elements\":[{\"type\":\"panel\",\"salience\":\"background\",\"identity\":\"An expansive, natural rural roadside setting. Muted blue sky and distant treetops fill the upper area. A quiet gray asphalt road enters from the lower left and bends toward a vanishing point near the center-left, with an irregular gravel shoulder on its right. Layered green trees, shrubs and tall grass frame the scene, especially along the right edge. The foreground includes textured gravel and small weeds. Soft afternoon daylight and gentle foliage shadows create a casual, believable outdoor photograph. Keep the space behind the sign free of intrusive branches.\",\"bbox\":[-880,-584,880,584]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Two visibly bent galvanized metal signposts, still attached behind the lower edge of the Line truncated
"negative_prompt": "nsfw, worst quality, bad anatomy, watermark, jpeg artifact",
"height": 1776,
"width": 1184,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 111769238,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"summary\":{},\"items\":[{\"bbox\":[-824,-472,824,472],\"label\":\"panel\",\"palette\":[\"#D4AF37\",\"#FFFFFF\",\"#B22222\",\"#87CEEB\",\"#2F4F4F\"],\"caption\":\"The entire composition is a single frame representing a live stream interface, blending a high-quality photographic portrait of a woman in Hanfu with dynamic social media UI overlays.\",\"tags\":[\"live stream\",\"Hanfu\",\"Chinese aesthetics\",\"UI overlay\"]},{\"bbox\":[-622,-300,403,383],\"label\":\"subject\",\"palette\":[\"#FFFFFF\",\"#F5F5DC\",\"#8B0000\",\"#2F4F4F\"],\"tags\":[\"woman\",\"Hanfu\",\"traditional clothing\",\"elegant\"]},{\"bbox\":[-345,-83,-72,206],\"label\":\"object\",\"palette\":[\"#FFFDD0\",\"#B22222\",\"#556B2F\"],\"caption\":\"A traditional round Chinese hand fan held by the woman. It is made of pale cream paper with a painting of red plum blossoms and black calligraphic text.\"},{\"bbox\":[-314,-17,-177,51],\"label\":\"text\",\"caption\":\"Black ink calligraphy written on the surface of the round fan.\",\"tags\":[\"calligraphy\",\"Chinese text\"],\"text\":\"浮生若梦\\n但愿长安\"},{\"bbox\":[-190,-300,403,383],\"label\":\"object\",\"palette\":[\"#FFFFFF\",\"#ADD8E6\",\"#8B0000\"],\"caption\":\"Highly detailed Hanfu consisting of a white outer robe with silver embroidery and light blue translucent sleeves, over a deep red inner garment. The material looks like silk and chiffon, draping softly.\"},{\"bbox\":[-622,-217,-243,128],\"label\":\"object\",\"caption\":\"Intricate gold hairpins and floral ornaments, including white and red blossoms, decorating the woman's complex hairstyle.\",\"tags\":[\"hairpins\",\"floral ornaments\",\"gold\"]},{\"bbox\":[212,177,534,322],\"label\":\"object\",\"caption\":\"A large, ornate golden lantern with intricate metal carvings, emitting a warm, bright glow. It sits on a wooden table in the foreground.\",\"tags\":[\"lantern\",\"warm light\",\"golden\"]},{\"bbox\":[365,-48,551,143],\"label\":\"object\",\"caption\":\"A traditional golden bronze incense burner with tripod legs and decorative carvings, positioned centrally on the wooden table.\",\"tags\":[\"incense burner\",\"bronze\",\"antique\"]},{\"bbox\":[463,-421,632,-99],\"label\":\"object\",\"caption\":\"A traditional Chinese bound book with a navy blue cover and light-colored pages, lying flat on the wooden table.\"},{\"bbox\":[-378,242,-163,354],\"label\":\"object\",\"palette\":[\"#ADD8E6\",\"#B22222\",\"#228B22\"],\"tags\":[\"vase\",\"plum blossoms\",\"ceramic\"]},{\"bbox\":[-824,-472,-703,472],\"label\":\"panel\",\"tags\":[\"UI\",\"header\",\"navigation\"]},{\"bbox\":[-816,-389,-761,-271],\"label\":\"text\",\"palette\":[\"#FFFFFF\"],\"caption\":\"Profile information in the top left corner.\",\"text\":\"清月如故\\n286.6万本场点赞\"},{\"bbox\":[-744,268,-672,445],\"label\":\"text\",\"palette\":[\"#FFFFFF\"],\"caption\":\"Event title in the top right corner.\",\"tags\":[\"UI text\",\"event\"],\"text\":\"国风盛典\\n山河入梦 与君共赏\"},{\"bbox\":[-30,-460,203,-152],\"label\":\"panel\",\"palette\":[\"#FFFFFF\",\"#FFC0CB\",\"#FF69B4\"],\"caption\":\"A series of translucent white gift notifications appearing on the left side, showing user names and the gifts they sent.\"},{\"bbox\":[-14,-393,42,-168],\"label\":\"text\",\"palette\":[\"#000000\"],\"caption\":\"First gift notification text.\",\"text\":\"墨染江南\\n送出 玫瑰 x 99\"},{\"bbox\":[56,-393,111,-178],\"label\":\"text\",\"tags\":[\"UI text\",\"gift\"],\"text\":\"长安故人\\n送出 天灯 x 1\"},{\"bbox\":[133,-393,190,-152],\"label\":\"text\",\"tags\":[\"UI text\",\"gift\"],\"text\":\"山河共月\\n送出 心动 x 520\"},{\"bbox\":[240,-446,488,67],\"label\":\"panel\",\"caption\":\"The live chat feed area at the bottom left, showing messages from viewers with their level badges and avatars.\"},{\"bbox\":[250,-435,445,60],\"label\":\"text\",\"tags\":[\"UI text\",\"chat\"],\"text\":\"Lv.28 琴声晚:姐姐好美 ❤️\\nLv.16 一纸相思:这氛围太绝了!\\nLv.32 月下听风:仿佛梦回大唐...\\nLv.18 南风知我意:想和姐姐一起看梅花 🌸\\nLv.25 清梦星河:国风yyds!\"},{\"bbox\":[706,-472,824,472],\"label\":\"panel\",\"palette\":[\"#000000\",\"#FF69B4\",\"#FFFFFF\"],\"caption\":\"The bottom interaction bar, including a text input field, share button, gift button, and like button.\"},{\"bbox\":[-689,-438,-260,-344],\"label\":\"text\",\"palette\":[\"#FFFFFF\"],\"tags\":[\"decorative text\",\"vertical\"],\"text\":\"一扇风华\\n一梦千年\\n\\n人间烟火里\\n总有诗意栖居\"},{\"bbox\":[-650,410,-367,452],\"label\":\"text\",\"palette\":[\"#FFFFFF\"],\"tags\":[\"decorative text\",\"vertical\"],\"text\":\"绣屏藏春\\n桃李人间\"},{\"bbox\":[619,-432,696,-250],\"label\":\"text\",\"tags\":[\"decorative text\",\"poetry\"],\"text\":\"愿以一盏灯火\\n换你三千次停留\"},{\"bbox\":[713,248,780,442],\"label\":\"text\",\"caption\":\"Branding text in the bottom right corner.\",\"tags\Line truncated
"negative_prompt": "worst quality, low quality, blurry, jpeg artifacts",
"height": 1680,
"width": 944,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"Eight-panel weekend comic strip\",\"gen_brief\":\"Create a finished Chinese slice-of-life comic in a very tall 1:8 format, using eight sequential panels and an expressive, lightly textured digital cartoon style. Follow one exhausted office worker whose weekend fishing escape becomes a comic misunderstanding with her boss. Rounded ink contours, elastic expressions, readable speech balloons, and small environmental jokes support a complete setup, escalation, reveal, and payoff. Keep character designs consistent, with a mustard hoodie and short black bob identifying the protagonist. Lighting progresses naturally from office evening through sunny lakeside leisure to Monday morning.\",\"elements\":[{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"Eight-panel continuous weekend comic\",\"shape\":\"Eight equal square panels, slim cream gutters, rounded black borders, expressive cartoon acting, white speech balloons, consistent characters and clear sequential storytelling.\",\"colors\":[{\"color\":\"Warm paper\",\"hex\":\"#FFF7E8\"},{\"color\":\"Ink\",\"hex\":\"#292C35\"},{\"color\":\"Mustard\",\"hex\":\"#E8B64C\"}],\"bbox\":[-2048,-256,2048,256]},{\"type\":\"text\",\"text\":\"周五 18:00|周末摸鱼计划\\n老板:周一的报告,别忘了。\\n小夏:写完了,定时发送!\",\"bbox\":[-2020,-223,-1851,223],\"shape\":\"Hand-lettered black Chinese; compact bold caption, two distinct rounded speech balloons, natural square glyphs.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"周六 09:00\\n工作群:有人在吗?\\n小夏:床上不安全,撤!\",\"bbox\":[-1508,-223,-1347,223],\"shape\":\"Compact black Chinese caption, gray notification lettering, emphatic handwritten dialogue in a white balloon.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"周六 10:30\\n小夏:真正的摸鱼,不看消息。\\n今日目标:一条就够!\",\"bbox\":[-996,-223,-835,223],\"shape\":\"Black rounded Chinese handwriting; modest time caption, relaxed speech balloon, smaller notebook-style goal lettering.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"偏偏这时……\\n来电:老板\\n小夏:都追到湖边了?!\",\"bbox\":[-484,-223,-323,223],\"shape\":\"Small suspense caption, bold phone notification, trembling black dialogue inside a jagged white balloon.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"鱼竿突然一沉!\\n小夏:大鱼!这把稳了!\\n……怎么是顶帽子?\",\"bbox\":[28,-223,189,223],\"shape\":\"Bold action caption, energetic Chinese speech lettering, smaller hesitant final line; generous white balloon interiors.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"帽子的主人,缓缓抬头。\\n老板:电话不接,帽子倒接得挺快。\\n小夏:您来催报告?!\",\"bbox\":[540,-223,725,223],\"shape\":\"Compact narrative caption; clear black Chinese dialogue, dry understated boss lettering and startled employee lettering.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"老板:我就想借点鱼饵。\\n小夏:那群里喊人是……\\n老板:问谁会钓鱼。周末不聊工作!\",\"bbox\":[1052,-223,1237,223],\"shape\":\"Three readable Chinese speech balloons with distinct tails; final sentence slightly bolder, relaxed rounded strokes.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"周一 09:00|报告已自动发送\\n同事:你俩周末对过方案了?\\n小夏:没有,对过鱼饵。\\n老板:报告不错。鱼饵,下次换一种。\",\"bbox\":[1564,-223,1782,223],\"shape\":\"Compact status caption and three speech balloons; black Chinese handwriting, restrained bold punchline, natural glyph proportions.\",\"is_watermark\":false},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Panel one: prepared escape\",\"note\":\"Establishes completed work and the protagonist's weekend intention.\",\"bbox\":[-2036,-244,-1548,244],\"shape\":\"Bob-haired woman in mustard hoodie closes laptop, grins, shoulders fishing bag; bespectacled boss holds mug; office dusk.\",\"colors\":[{\"color\":\"Mustard hoodie\",\"hex\":\"#E8B64C\"},{\"color\":\"Office lavender\",\"hex\":\"#B8B2CE\"},{\"color\":\"Evening coral\",\"hex\":\"#EC8B73\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Panel two: the notification ambush\",\"note\":\"A harmless work notification feels like a weekend invasion.\",\"bbox\":[-1524,-244,-1036,244],\"shape\":\"Same woman bolts from rumpled bed clutching buzzing phone; orange cat steals pillow; slippers fly; curtains glow.\",\"colors\":[{\"color\":\"Cream bedding\",\"hex\":\"#FFF7E8\"},{\"color\":\"Mustard hoodie\",\"hex\":\"#E8B64C\"},{\"color\":\"Cat orange\",\"hex\":\"#D98445\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Panel three: apparent freedom\",\"note\":\"Quiet fishing creates contrast before the interruption.\",\"bbox\":[-1012,-244,-524,244],\"shape\":\"Woman lounLine truncated
"negative_prompt": "worst quality, low quality, blurry, jpeg artifacts",
"height": 4096,
"width": 512,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"chaotic anime ensemble action comedy\",\"gen_brief\":\"A lively Blue Archive campus group photo collapsing into a harmless slapstick disaster, featuring exactly ten distinct named students from the elements, each appearing once. An asymmetric arch-shaped ensemble composition in one continuous sunlit courtyard, viewed slightly from above, not a grid or three horizontal rows. Hina stands closest to the viewer at the lower center as the main visual anchor. Behind her, Karin at upper-left, Mika at upper-center and Koharu at upper-right form an uneven arc of large, clearly separated faces. Mika and Koharu occupy the expanded upper-center and upper-right areas so there are no vacant character slots. Toki leans inward from the left edge beneath Karin; Shiroko reaches into their snack rescue from the left middle-ground. Serika anchors the lower-left corner, while sleeping Hoshino forms a low reclining diagonal between Serika and Hina, partially occluding Shiroko's lower body without covering her face. Koharu leans inward from the upper-right, with Azusa at the lower inner-right and Hifumi at the lower outer-right, forming a compact triangular toy-rescue interaction. Hifumi is in front of Koharu's lower torso. Keep Hina's face below Mika's and between the left and right action groups, with Hina's shoulders in front of their inner edges. Overlap shoulders and lower torsos, never faces; stagger head heights and keep each halo close to its owner. Heads and torsos fill their boxes rather than floating inside unused padding. Naturally crop the nearest lower bodies at the bottom and sides. The courtyard remains continuous, with small glimpses of architecture, steps, sky and blanket between the crowd, no dividing aisles or portrait slots. A curving gust carries blank napkins and papers from the tipping snack tray at left, above Mika's reaching hands, toward one small airborne Peroro plush at right. Pastries and paper trails pass around faces, not across them. Toki and Karin catch snacks, Shiroko reaches for a pastry, and Serika protests. Hina wearily asks everyone to calm down while Mika laughs behind her. Hoshino sleeps through everything. Koharu reaches down-left for the toy above Azusa's open schoolbag while Hifumi watches anxiously. Use varied eyelines, diagonal poses and calm-versus-panicked reactions rather than identical smiles. Exactly ten students, no spectators, duplicates or extra limbs. The single Peroro plush is an inanimate toy. Friendly nonsexual school comedy, no weapons, injuries, dangerous falls or upskirt angles. Crisp expressive anime linework, refined cel shading, pastel colors, warm upper-left sunlight and consistent blue ambient shadows. All ten wear their recognizable default clothing and halos, modified to omit every chest badge, school badge pin, name tag, ID card, badge holder and ID lanyard, even when these belong to the default outfit. No replacement badge-shaped chest patches or chest insignia. Preserve other clothing, neckties, ribbons and scarves. No added captions, speech bubbles, floating labels, watermarks or unrelated logos.\",\"elements\":[{\"type\":\"panel\",\"salience\":\"background\",\"identity\":\"Sunlit Kivotos courtyard framed behind the ten-student ensemble. Small upper-corner glimpses of cyan sky and white campus arches, shallow stone steps, a cropped snack table at the left, and a picnic blanket at the bottom. A few windblown blank papers, napkins, petals, and pastries arc through open gaps above shoulders, never covering faces. No extra spectators, signage, or damage\",\"bbox\":[-592,-888,592,888]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Asuma Toki (Blue Archive), left edge at intermediate depth, lower and farther left than Karin, behind Serika; in her default maid uniform and signature halo, without chest badges or ID accessories, no exoskeleton. Leaning diagonally inward toward Karin, one hand balancing a tipping snack tray and the other catching a cup, deadpan calm expression\",\"bbox\":[-395,-867,254,-393]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Kakudate Karin (Blue Archive), upper-left inner arc, behind Shiroko and above-right of Toki; in her default maid uniform and signature halo, without chest badges or ID accessories. Leaning down-left toward Toki's tipping tray with an empty plate held in both hands to catch a pastry, focused startled expression, hair flowing with her motion\",\"bbox\":[-564,-584,99,-117]},{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"Sorasaki Hina (Blue Archive), dominant lower-center foreground anchor, directly in front of Mika, between Shiroko and Azusa; in her default Prefect Team uniform and signature halo, without chest badges or ID accessories. Large readable head and torso, lower body cropped at the bottom. Turning slightly toward the left snack scramble with a weary exasperated expression, one palm raised to ask everyone to calm down and the other hand touLine truncated
"negative_prompt": "",
"height": 1184,
"width": 1776,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 3072627948,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "多层折叠式纸雕立体绘本,放在一张书桌上,背景纯净突出主题,比例 3:2 横版。翻开的跨页呈现「哪吒闹海」的场景:脚踏风火轮的少年、翻涌的层叠海浪与龙宫剪影,所有元素皆可精细折叠组合,呈现逼真细腻的纸张折叠质感与多层景深。构图统一采用正面视角,整体视觉梦幻唯美,色彩缤纷绚丽,充满奇幻生动的故事氛围。",
"negative_prompt": "worst quality, bad anatomy, ugly face",
"height": 1024,
"width": 1536,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 2570432421,
"uncond_skip_layers": "26",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"Chinese literature textbook photograph\",\"gen_brief\":\"A realistic editorial photograph of an open Chinese senior-school literature textbook on a warm wooden study desk. The printed lesson presents Wang Xizhi's Lanting preface in authentic simplified Chinese, with carefully typeset classical prose and compact explanatory footnotes. Use a nearly overhead camera, natural window light, subtle paper translucency, gently curved pages, and soft binding shadows. The image should feel like an ordinary student's clean textbook snapshot rather than a designed poster, with crisp readable printing and restrained, believable photographic texture.\",\"elements\":[{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"Open Chinese literature textbook\",\"shape\":\"Ivory uncoated paper, gently bowed binding, fine black textbook printing, faint reverse-side ink, layered page edges, understated blue lesson accents.\",\"colors\":[{\"color\":\"Ivory paper\",\"hex\":\"#F5F0E5\"},{\"color\":\"Printing black\",\"hex\":\"#292824\"},{\"color\":\"Muted textbook blue\",\"hex\":\"#496878\"}],\"bbox\":[-685,-544,691,508]},{\"type\":\"text\",\"text\":\"古代散文阅读\",\"bbox\":[-616,-324,-582,-99],\"shape\":\"Small muted-blue Chinese sans-serif characters, restrained tracking and natural square proportions.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"兰亭集序\",\"bbox\":[-542,-116,-465,281],\"shape\":\"Bold black Song-style Chinese title, prominent triangular serifs, evenly spaced natural-width characters.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"王羲之\",\"bbox\":[-446,14,-410,152],\"shape\":\"Small centered black Song-style characters with airy spacing.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"永和九年,岁在癸丑,暮春之初,会于会稽山阴\\n之兰亭,修禊事也。群贤毕至,少长咸集。此地有崇\\n山峻岭,茂林修竹,又有清流激湍,映带左右,引以\\n为流觞曲水,列坐其次。虽无丝竹管弦之盛,一觞一\\n咏,亦足以畅叙幽情。是日也,天朗气清,惠风和畅。\\n仰观宇宙之大,俯察品类之盛,所以游目骋怀,足以\\n极视听之娱,信可乐也。\",\"bbox\":[-357,-319,-90,436],\"shape\":\"Black Song-style body text, regular square glyphs, generous leading, first-line indentation, subtle paper curvature.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"夫人之相与,俯仰一世。或取诸怀抱,悟言一室\\n之内;或因寄所托,放浪形骸之外。虽趣舍万殊,静\\n躁不同,当其欣于所遇,暂得于己,快然自足,不知\\n老之将至;及其所之既倦,情随事迁,感慨系之矣。\\n向之所欣,俯仰之间,已为陈迹,犹不能不以之兴怀;\\n况修短随化,终期于尽!古人云:“死生亦大矣。”\\n岂不痛哉!\",\"bbox\":[-60,-319,207,436],\"shape\":\"Matching black Song-style body text, first-line indentation, measured line spacing and crisp punctuation.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"注释\\n〔永和九年〕公元353年。永和,东晋穆帝年号。\\n〔会稽山阴〕今浙江绍兴。\\n〔修禊〕古代于暮春临水举行的祓除不祥的仪式。\\n〔流觞曲水〕把酒杯浮在弯曲的水道中,任其漂流,\\n停在谁的面前,谁就取来饮酒。\\n〔悟言〕面对面交谈。“悟”同“晤”。\",\"bbox\":[330,-319,546,427],\"shape\":\"Compact black Song-style footnotes; slightly bolder heading, hanging entries, smaller natural-width glyphs and even leading.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"42\",\"bbox\":[615,41,643,82],\"shape\":\"Tiny black serif page number with native numeral proportions.\",\"is_watermark\":false},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Wooden desktop\",\"note\":\"Provides an everyday study setting.\",\"bbox\":[-728,-544,728,544],\"shape\":\"Matte honey-brown wood with restrained grain, minor surface wear and soft natural shadows.\",\"colors\":[{\"color\":\"Warm wood\",\"hex\":\"#B58B61\"},{\"color\":\"Dark wood grain\",\"hex\":\"#896547\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Narrow facing-page strip and binding gutter\",\"note\":\"Makes the photographed page clearly part of an open textbook.\",\"bbox\":[-673,-544,667,-354],\"shape\":\"Curved ivory page sliver, dark soft binding crease, subtly curled paper and thin layered edges; no readable printing.\",\"colors\":[{\"color\":\"Ivory paper\",\"hex\":\"#F5F0E5\"},{\"color\":\"Gutter shadow\",\"hex\":\"#B6AA97\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Textbook running-header rule\",\"note\":\"Restrained printed lesson styling.\",\"bbox\":[-567,-321,-563,435],\"shape\":\"Very thin, straight muted-blue printed rule with slight paper-grain absorption.\",\"colors\":[{\"color\":\"Muted textbook blue\",\"hex\":\"#496878\"}]},{\"type\":\"obj\Line truncated
"negative_prompt": "",
"height": 1456,
"width": 1088,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 1946227359,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "A young anime woman, Kazusa from Blue Archive, stands still at the edge of a crowded Tokyo crosswalk outside a busy train station on a damp, overcast dusk. Her short dark hair with soft magenta inner highlights frames her face, cat ears perked slightly beneath her distinctive glowing pink halo. She wears an oversized charcoal wool coat over a beige knit hoodie, a short pleated black skirt, black crew socks, and scuffed loafers, with a canvas tote bag slung over her shoulder. She holds a wired earphone in one hand as if pausing her music, looking slightly sideways with a quiet, unguarded expression while the evening rush hour flows around her.\n\nIn the immediate foreground, a heavily motion-blurred commuter in a dark coat walks right past the lens, partially framing the edge of the shot and giving it the raw, accidental feel of a candid street photograph. Around and behind Kazusa, a bustling crowd of out-of-focus pedestrians moves across the wet asphalt crosswalk under the muted glow of neon department store signs, traffic signals, and concrete office buildings. The image blends Kazusa’s anime appearance seamlessly into a gritty, photorealistic modern city environment, using natural ambient dusk lighting, shallow depth of field, motion blur on the passing crowd, muted cool tones, and a cinematic sense of stillness amid urban chaos.",
"negative_prompt": "watermark, bad anatomy",
"height": 1776,
"width": 1184,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 3537712559,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"Amateur selfie contact sheet\",\"gen_brief\":\"Create a high-resolution photographic contact sheet of nine fictional amateur selfie mishaps featuring Donald Trump, presented as a coherent three-by-three grid on a portrait canvas. Recognizable facial features, swept blond hair, realistic skin texture, and ordinary clothing establish a consistent subject across varied everyday settings. The humor comes from awkward framing, blinking, accidental obstruction, and poorly timed expressions rather than caricature. Use believable smartphone perspective, mixed natural and indoor lighting, and modest photographic imperfections. Keep the finished collage crisp and carefully balanced while preserving the deliberately unsuccessful snapshot aesthetic of each photograph.\",\"elements\":[{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"Nine-photo contact sheet\",\"shape\":\"Rectangular photographic contact sheet containing exactly nine equal portrait photographs, narrow ivory gutters, clean edges, no captions or graphic embellishments.\",\"colors\":[{\"color\":\"ivory\",\"hex\":\"#F2F0EA\"},{\"color\":\"charcoal\",\"hex\":\"#30343A\"}],\"bbox\":[-680,-384,680,384]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump finger-obstructed selfie\",\"note\":\"An accidental fingertip partially blocks the phone camera.\",\"bbox\":[-661,-373,-231,-131],\"shape\":\"Trump wearing navy jacket and red tie, puzzled expression, foreshortened fingertip veiling part of lens, daylight window, realistic smartphone photography.\",\"colors\":[{\"color\":\"navy\",\"hex\":\"#202D45\"},{\"color\":\"red\",\"hex\":\"#BA3034\"},{\"color\":\"warm skin\",\"hex\":\"#D6A080\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump blinking selfie\",\"note\":\"The shutter catches both eyes closed during a blink.\",\"bbox\":[-661,-121,-231,121],\"shape\":\"Trump in white golf polo, eyes naturally closed, mouth slightly open, sunlit lawn, blond flyaway hair, harsh midday shadows.\",\"colors\":[{\"color\":\"white\",\"hex\":\"#F4F3EC\"},{\"color\":\"grass green\",\"hex\":\"#657849\"},{\"color\":\"golden blond\",\"hex\":\"#C9AD70\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump cropped-hair selfie\",\"note\":\"The camera angle accidentally cuts off most of his hairstyle.\",\"bbox\":[-661,131,-231,373],\"shape\":\"Extreme-close Trump selfie, forehead and hairstyle abruptly cropped, raised eyebrows, navy suit, softly detailed beige hallway, wide-angle facial perspective.\",\"colors\":[{\"color\":\"warm skin\",\"hex\":\"#D6A080\"},{\"color\":\"beige\",\"hex\":\"#C7B8A0\"},{\"color\":\"navy\",\"hex\":\"#202D45\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump low-angle selfie\",\"note\":\"An unintentionally low phone position creates awkward perspective.\",\"bbox\":[-215,-373,215,-131],\"shape\":\"Trump looking down into camera, pronounced chin foreshortening, pursed lips, dark overcoat, visible ceiling tiles and fluorescent fixtures.\",\"colors\":[{\"color\":\"charcoal\",\"hex\":\"#30343A\"},{\"color\":\"ceiling gray\",\"hex\":\"#D1D3CF\"},{\"color\":\"warm skin\",\"hex\":\"#D6A080\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump windblown selfie\",\"note\":\"A gust interrupts his attempt at a composed portrait.\",\"bbox\":[-215,-121,215,121],\"shape\":\"Trump in navy jacket, dramatically wind-tossed blond hair, squinting eyes, tight smile, bright blue sky, distant trees, sharp facial detail.\",\"colors\":[{\"color\":\"sky blue\",\"hex\":\"#91B8D1\"},{\"color\":\"golden blond\",\"hex\":\"#C9AD70\"},{\"color\":\"navy\",\"hex\":\"#202D45\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump tilted selfie\",\"note\":\"An awkward wrist angle leaves the snapshot conspicuously crooked.\",\"bbox\":[-215,131,215,373],\"shape\":\"Trump in open-collar white shirt, hesitant grin, strongly diagonal doorway and wall molding, uneven warm indoor light, believable handheld perspective.\",\"colors\":[{\"color\":\"white\",\"hex\":\"#F4F3EC\"},{\"color\":\"warm beige\",\"hex\":\"#C7B8A0\"},{\"color\":\"wood brown\",\"hex\":\"#785940\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump flash reflection selfie\",\"note\":\"A mirror selfie fails because the flash creates distracting glare.\",\"bbox\":[231,-373,661,-131],\"shape\":\"Trump holding black smartphone, navy suit and red tie, ornate mirror, conspicuous flash starburst, face still recognizable, warm room reflections.\",\"colors\":[{\"color\":\"navy\",\"hex\":\"#202D45\"},{\"color\":\"gold\",\"hex\":\"#B99859\"},{\"color\":\"flash white\",\"hex\":\"#FFFDF4\"}]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Donald Trump interrupted selfie\",\"note\":\"A sip of coffee is caught at an unflattering instant.\",\"bbox\":[231,-121,661,121],\"shape\":\"Trump wearing dark cardigan, plain paper cup pressed Line truncated
"negative_prompt": "worst quality, low quality, blurry, jpeg artifacts, pixelated, cropped, out of frame, cut off",
"height": 1360,
"width": 768,
"steps": 30,
"cfg": 4,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "general, 1girl, best quality, most attractive face, cosplay, amiya (arknights), with \"Rhodes Island\" on her clothes, carring a sword",
"negative_prompt": "worst quality, bad anatomy",
"height": 1536,
"width": 1024,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 0,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "一张极具 YouTube 缩略图风格的夸张宣传画面:场景设置在一座大型露天体育场或竞技场内,背景是明亮的蓝天、环形看台与巨型电子屏幕,大量年轻观众挤满画面,兴奋地欢呼、张嘴大笑,并高举写满数学公式、函数图像和几何草图的白纸,整体营造出“完成超大规模数学挑战后全场庆祝”的戏剧化氛围。\n\n画面正中央是一位拟人化的 ChatGPT 形象,以低机位、中近景英雄式构图占据视觉中心。人物穿着宽松的黑色连帽卫衣,胸前印有青绿色的 OpenAI/ChatGPT 旋结标志,双臂交叉抱在胸前,姿态自信而具有挑战意味。人物的头部被替换成一个大型、圆角、具有明显 3D 体积感的青绿色方形 ChatGPT 图标,正面中央是白色 OpenAI 旋结 Logo;图标表面带有高光和阴影,像一块实体塑料或软质立方体头盔。黑色服装与鲜艳的青绿色头部形成强烈色彩对比,使主体从喧闹背景中明显突出。\n\n画面左上方覆盖着面积很大的漫画式标题文字。最上方以白色粗体、黑色厚描边的倾斜字体写着 **“I SOLVED”**。其下原本有巨大的黄色数字 **“400”**,数字具有黑色描边、立体阴影和高饱和度漫画质感,但被两条粗大的红色手绘笔刷线交叉划掉,形成醒目的红色“X”。被划掉的“400”下方,则用极大的鲜红色数字突出显示 **“722”**,带黑白多层描边和略微倾斜、膨胀的卡通字体效果。最下方继续以白色粗体黑描边文字写着 **“MATH PROBLEMS!”**。整个标题组合传达出一种“原本挑战 400 道题,结果实际解决了 722 道”的夸张升级感。\n\n背景观众几乎全部穿着白色或浅色服装,与中央人物的黑色卫衣形成明显明暗分区。许多人手中的纸张上可以看到不同层次的数学内容:画面左下方一张纸清晰写有高斯积分 \n\\[\n\\int_{-\\infty}^{\\infty}e^{-x^2}dx=\\sqrt{\\pi},\n\\]\n其下还有二次方程求根公式 \n\\[\nx=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}.\n\\]\n画面右侧一张显眼的白纸写有巴塞尔问题结果 \n\\[\n\\sum_{n=1}^{\\infty}\\frac{1}{n^2}=\\frac{\\pi^2}{6}.\n\\]\n靠近下方中央还有写着 \n\\[\n\\frac{dy}{dx}=xy\n\\]\n的微分方程纸张,右下角则可见矩阵、几何三角形、坐标图像、角度关系以及其他手写代数表达式。其余观众的纸上散布积分、函数曲线、坐标轴和复杂推导,使整个背景充满“数学竞赛”与“高难度解题挑战”的视觉符号。\n\n体育场四周的大型青绿色电子屏幕上重复展示白色 OpenAI/ChatGPT 标志,与中央人物头部的配色保持一致。天空与场馆上方还飘散着青绿色、白色和少量深色的方形彩纸,强化庆典和胜利后的狂欢感。人物及前排观众清晰锐利,而远处看台与屏幕略有景深模糊;画面采用高饱和度、高对比度、锐化明显的商业缩略图处理方式,青绿色、红色、黄色、黑色和白色构成主要视觉色板。\n\n整体视觉叙事可以概括为:**一个拟人化 ChatGPT 在体育场级别的数学挑战中“超额完成任务”,原定的 400 道数学题被红色叉号否定,并以醒目的“722”取而代之;周围数百名学生高举数学解答欢呼庆祝,形成一种夸张、热闹、极具点击吸引力的 AI 解题挑战宣传画面。**",
"negative_prompt": "",
"height": 1024,
"width": 1536,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"summary\":{\"meta\":[\"screenshot\",\"video_game_capture\",\"dark_fantasy\",\"elden_ring\"],\"canvas\":\"single\",\"caption\":\"A cinematic 16:9 gameplay screenshot from Elden Ring, rendered with the game's richly textured dark-fantasy realism rather than as promotional artwork. A third-person view follows a lone Tarnished standing on a weathered stone outcrop in Limgrave, wearing scratched steel armor over faded blue cloth, a battered cloak hanging behind their shoulders. Their right hand holds a straight sword pointed toward the ground, and their left carries a worn metal shield. Wind bends the surrounding golden-green grass and stirs the cloak. The spectral golden Erdtree towers beyond the landscape, its radiant trunk and intricate luminous branches illuminating a hazy sky. Rolling hills, broken stone arches, scattered autumnal trees, and ruined fortifications recede through pale atmospheric mist. A narrow dirt road winds past crumbling masonry, where two distant armored soldiers patrol with spears and muted orange torchlight. The scene feels vast, melancholy, and quietly dangerous, with intricate environmental detail, natural material wear, soft volumetric light, and restrained golden highlights against cool gray-green shadows.\\nPreserve the recognizable in-game HUD: slim red, blue, and green status bars at the upper left beside the circular status emblem; a delicate compass at the upper center with the visible letters “N” and “E”; and equipment slots at the lower left showing the equipped shield, straight sword, and glowing red-gold flask. The selected item reads “Flask of Crimson Tears +1” with the quantity “4,” and the weapon skill reads “Square Off.” A small dark rune counter at the lower right reads “1248.” HUD lettering is fine, pale, and subtly shadowed, with weathered ornamental borders around the equipment icons. No title logo, desktop borders, subtitles, or promotional text; this is an immersive moment of ordinary exploration captured directly from gameplay.\"},\"items\":[{\"label\":\"panel\",\"caption\":\"Full-frame over-the-shoulder gameplay view looking slightly downward and outward toward a broad open landscape. A single armored player figure occupies the lower-right-center foreground, framed by tall wind-blown grass, while a vast ruined field and luminous tree recede into atmospheric haze. Foreground stone is sharp and detailed; the midground grass and ruins lose contrast with distance; the sky remains pale and washed-out. HUD overlays remain legible in the four corners, blending with the dark vignette and unobstructed environmental view.\",\"tags\":[\"third-person\",\"gameplay\",\"open_world\",\"fantasy\",\"limgrave\",\"elden_ring\"],\"palette\":[\"#C6BC9C\",\"#6B7A53\",\"#8A7D66\",\"#E9DCA9\",\"#1F1F1F\"],\"bbox\":[-472,-840,472,839]},{\"label\":\"object\",\"caption\":\"Broad open terrain fills the mid- and background, dominated by wind-blown grass in gold-green bands, scattered trees, broken arches, stone walls, and low hills. Paths and clearings create pale strips through the vegetation, while distant ruins appear as dark geometric silhouettes against a hazy sky. The environmental detail sharpens toward the foreground and dissolves into muted gray-green and tan masses behind the player.\",\"tags\":[\"open_field\",\"ruins\",\"grassland\",\"autumnal_trees\",\"broken_arches\"],\"palette\":[\"#8A9671\",\"#B3A478\",\"#656252\",\"#D6CAA0\",\"#9A9280\"],\"bbox\":[-250,-840,304,839]},{\"label\":\"object\",\"caption\":\"Upper-left health, stamina, and magic bars appear as three thin horizontal gauges stacked slightly offset from one another. Red occupies the top gauge, blue the middle, and green the lower portion, each contained in a narrow dark frame with subtle worn texture. The bars are flat, crisp, and overlay the soft background without occluding key scene elements.\",\"tags\":[\"hud\",\"health_bar\",\"stamina_bar\",\"status_ui\",\"overhead_overlay\"],\"palette\":[\"#9C3334\",\"#2E4654\",\"#4F7A3A\",\"#231F1E\",\"#B5B0A3\"],\"bbox\":[-435,-656,-394,-425]},{\"label\":\"object\",\"tags\":[\"spectral_tree\",\"glowing\",\"background\",\"floating_rocks\",\"fantasy_environment\"],\"caption\":\"A towering spectral tree dominates the upper center of the scene, its glowing pale-gold branches spreading like a luminous canopy over broken stone ridges. Luminous foliage masses appear at the crown and along the trunk, while small floating rock fragments hover near the base and sides. The tree is rendered as a bright central mass against a washed sky, creating a strong vertical focal axis and radiating soft light into the surrounding haze.\",\"palette\":[\"#EEDFA9\",\"#D9C787\",\"#C4B796\",\"#B6AC94\"],\"bbox\":[-472,-174,-247,108]},{\"label\":\"object\",\"caption\":\"A lone player character stands with their back to the camera, facing the distant field. They wear a rounded steel helm with a dark visor, segmented metal armor over blue-gray cloth, and a worn brLine truncated
"negative_prompt": "worst quality, bad anatomy",
"height": 944,
"width": 1680,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "26",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"Chinese physics examination paper\",\"gen_brief\":\"A finished Chinese university entrance examination practice paper, rendered as a crisp, straight-on scan of a single A4 sheet. The design follows formal examination typography, with restrained black ink, precise mathematical notation, generous writing margins, and finely drawn physics figures. The paper is clean white under even illumination, without photographic perspective or distracting surface texture. Dense but readable Chinese typesetting, differentiated heading weights, consistent option spacing, and carefully aligned question numbers create an authentic printed assessment. All questions remain unanswered, and the document clearly identifies itself as a practice examination.\",\"elements\":[{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"A4 physics examination sheet\",\"shape\":\"White examination page with black printed typography, fine rules, unmarked answer spaces, and sharp monochrome scientific diagrams.\",\"colors\":[{\"color\":\"paper white\",\"hex\":\"#FFFFFF\"},{\"color\":\"printing black\",\"hex\":\"#181818\"}],\"bbox\":[-744,-528,744,528]},{\"type\":\"text\",\"text\":\"2026年普通高等学校招生全国统一考试(模拟)\",\"bbox\":[-663,-395,-624,395],\"shape\":\"Centered bold Song-style Chinese heading, natural square glyphs, compact spacing, solid black ink.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"物 理\",\"bbox\":[-606,-99,-547,99],\"shape\":\"Large bold Chinese display characters, balanced spacing, clean black print.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"考试时间:75分钟  满分:100分\",\"bbox\":[-523,-233,-492,233],\"shape\":\"Centered regular Song-style text, smaller than title, even baseline.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"姓名:____________ 准考证号:____________________\",\"bbox\":[-469,-388,-438,388],\"shape\":\"Regular black Chinese type with uniform baseline and clear blank underlines.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"注意事项:\\n1.答题前,请将姓名、准考证号填写清楚。\\n2.选择题答案请填涂在答题卡上,非选择题请在答题卡指定区域作答。\\n3.考试结束后,将本试卷和答题卡一并交回。\",\"bbox\":[-401,-428,-281,428],\"shape\":\"Compact Song-style body, bold introductory label, four evenly spaced lines, black ink.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"一、单项选择题:本题共6小题,每小题4分,共24分。\\n每小题给出的四个选项中,只有一项符合题目要求。\",\"bbox\":[-253,-428,-188,428],\"shape\":\"Bold section statement with regular explanatory line, modest leading, natural Chinese proportions.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"1.在国际单位制中,下列物理量的单位属于基本单位的是(  )\\nA.力的单位:牛顿    B.能量的单位:焦耳\\nC.电流的单位:安培   D.电压的单位:伏特\",\"bbox\":[-164,-428,-69,428],\"shape\":\"Black Song-style question text; options in two aligned columns, hanging question-number indentation.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"2.如图,一小物块从固定光滑斜面上由静止释放。\\n斜面倾角为30°,重力加速度为g。物块沿斜面\\n下滑的加速度大小为(  )\\nA.g/4     B.g/2\\nC.√3g/2   D.g\",\"bbox\":[-44,-428,105,196],\"shape\":\"Regular Chinese examination type, clear mathematical symbols, compact two-column options, five evenly spaced lines.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"30°\",\"bbox\":[58,297,85,346],\"shape\":\"Small upright black angle label, clean degree symbol.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"3.质量为m的小球用细线悬挂于O点,在竖直平面内做圆周运动。\\n小球经过最低点时的速度为v,细线长为L,重力加速度为g。\\n此时细线对小球的拉力大小为(  )\\nA.mv²/L       B.mg\\nC.mg+mv²/L     D.mv²/L-mg\",\"bbox\":[132,-428,276,428],\"shape\":\"Consistent Song-style body with italic Latin variables, precise superscripts, two aligned option columns.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"4.一电源的电动势为6.0 V,内阻为1.0 Ω,与阻值为3.0 Ω的\\n定值电阻连接成闭合电路。电源的输出功率为(  )\\nA.2.25 W  B.6.75 W  C.9.00 W  D.12.0 W\",\"bbox\":[302,-428,389,428],\"shape\":\"Regular black Chinese type, spaced units, four evenly separated options on one baseline.\",\"is_watermark\":false},{\"type\":\"text\",\"text\":\"5.某物体沿直线运动,其速度随时间变化的图像\\n如图所示。物体在0~4 s内的位移大小为(  )\\nA.8 m     B.12 m\\nC.16 m    D.32 m\",\"bbox\":Line truncated
"negative_prompt": "",
"height": 1488,
"width": 1056,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "An original, museum-quality white marble sculpture of Artoria Pendragon (Saber) from Fate, conceived with the anatomical discipline, monumental presence, and exquisite craftsmanship of Renaissance sculpture, without copying Michelangelo's David, its pose, or its composition.\n\nPreserve Saber's unmistakable character design: finely carved bangs framing her face, hair gathered into her characteristic braided bun with a ribbon, a distinctive upward-curving forelock rendered as a carefully supported marble curl, and a calm, resolute expression conveying quiet chivalric dignity. Translate her iconic armored dress into monochrome marble: an articulated breastplate, sculpted pauldrons, armored gauntlets, a fitted high-neck bodice, and a long, layered skirt with recognizable decorative borders and richly carved fabric folds. The garments ordinarily associated with blue fabric and silver armor are expressed entirely through marble form, texture, and finish, without pigment. She is fully clothed in a modest, non-revealing outfit; beauty emerges through balanced proportions, natural posture, and the interplay of armor and drapery. No animal ears, halo, school uniform, or scarf.\n\nCreate an original, quietly expressive contrapposto: her weight rests on one leg, the other foot advances slightly beneath the skirt, and her head turns gently away from the torso. Her right gauntleted hand rests lightly on the pommel of Excalibur, held vertically beside her right leg with its tip resting securely on the stone base; her left hand rests naturally beside the skirt. Render Excalibur as a recognizably elegant straight double-edged knightly sword with an ornate crossguard and decorated hilt, carved entirely from the same ivory-white marble, without colored metal or magical glow. Keep the sword visually distinct from her silhouette, with discreet structural connections to the base and neighboring drapery so the sculpture feels physically realizable. Preserve believable anatomy beneath the clothing, relaxed hands, and convincing physical balance. Long folds in the skirt introduce restrained diagonal movement against the crisp planes of the armor.\n\nCarve the entire figure, armor, clothing, and sword from luminous ivory-white marble with subtle natural veining, delicately polished facial planes, crisp edges, and faint chisel traces in recessed folds. Distinguish armor from fabric through smoother reflective stone planes versus softer, gently textured folds, never through paint. No painted skin, plastic surfaces, toy-like proportions, or exaggerated anatomy. Display the complete statue and its stone pedestal in a spacious museum gallery, with warm gray walls and generous negative space. Soft, directional light from high on the left reveals the sculptural volume, with gentle ambient fill preserving shadow detail.\n\nA separate, elegant museum placard beside the pedestal bears the clearly legible text “Artoria Pendragon” and, beneath it, “Saber — Fate”. Vertical 9:16 composition, slightly low viewpoint, restrained perspective, full figure visible from the top of her forelock to the bottom of the pedestal, including the entire sword, with no cropped hair, feet, or base. Photorealistic fine-art sculpture photography: serene, dignified, and materially convincing.",
"negative_prompt": "",
"height": 1360,
"width": 768,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"summary\":{\"meta\":[\"photograph\"],\"canvas\":\"single\",\"caption\":\"A high-quality indoor photograph captures a male and female fitness trainer guiding a male client through a weighted squat exercise in a modern gym. The scene is brightly lit with overhead industrial lights, emphasizing the texture of the gym equipment and the athletic wear. The composition is a medium-wide shot with a shallow depth of field, focusing on the three men while the background of gym machinery and motivational posters is softly blurred. The overall mood is focused and professional, with a neutral color palette punctuated by the trainers' black attire and the green towel.\"},\"items\":[{\"label\":\"panel\",\"caption\":\"A full-canvas shot of a gym session. A client is squatting with a barbell, flanked by two trainers. The background features gym walls with motivational text and various strength training equipment. The lighting is bright and diffuse, creating a professional fitness atmosphere.\",\"tags\":[\"gym\",\"fitness\",\"workout\",\"training\",\"squat\"],\"palette\":[\"#2A2A2A\",\"#7B7B7B\",\"#FFFFFF\",\"#A3B18A\"],\"bbox\":[-888,-592,887,591]},{\"label\":\"object\",\"caption\":\"A man in a focused squat position, wearing a grey heathered t-shirt, black athletic shorts, white crew socks, and white New Balance sneakers. He is supporting a loaded barbell across his upper back and shoulders, looking forward with a concentrated expression. His pose is stable, with knees bent and hips lowered.\",\"tags\":[\"man\",\"client\",\"squatting\",\"athletic_wear\"],\"palette\":[\"#B0B0B0\",\"#1A1A1A\",\"#FFFFFF\",\"#E8C3B9\"],\"bbox\":[-164,-196,766,401]},{\"label\":\"object\",\"caption\":\"A muscular man standing on the left, wearing a black t-shirt with 'MORE TO BE A BETTER YOU' printed in white and black athletic pants. He is leaning forward, observing the client's form and extending his right hand to provide stability or a cue. His gaze is directed downward toward the trainee.\",\"tags\":[\"trainer\",\"man\",\"spotting\",\"fitness_coach\"],\"palette\":[\"#1A1A1A\",\"#D2B48C\",\"#FFFFFF\"],\"bbox\":[-706,-592,736,-138]},{\"label\":\"object\",\"caption\":\"A man standing on the right in a black tank top, black athletic pants, and a black baseball cap. He is leaning slightly forward, watching the client's form, with a neon green towel draped over his left shoulder. His expression is focused and attentive.\",\"tags\":[\"trainer\",\"man\",\"observing\",\"fitness_coach\"],\"palette\":[\"#1A1A1A\",\"#D2B48C\",\"#90EE90\"],\"bbox\":[-565,166,686,591]},{\"label\":\"object\",\"caption\":\"A silver steel barbell resting on the trainee's traps. It is loaded with large black rubber weight plates. A white towel is placed on the bar across the trainee's shoulders for padding. The barbell spans the width of the central composition.\",\"tags\":[\"barbell\",\"weightlifting\",\"equipment\"],\"palette\":[\"#000000\",\"#C0C0C0\",\"#FFFFFF\"],\"bbox\":[-359,-592,201,591]},{\"label\":\"object\",\"caption\":\"A stack of black weight plates on the left side of the barbell, featuring the text 'TECHNOGYM 20 KG' in white. The plates are circular and made of dense rubberized material.\",\"tags\":[\"weight_plate\",\"Technogym\"],\"palette\":[\"#1A1A1A\",\"#FFFFFF\"],\"bbox\":[-219,-592,201,-406]},{\"label\":\"object\",\"caption\":\"A stack of black weight plates on the right side of the barbell, similarly branded 'TECHNOGYM 20 KG'.\",\"tags\":[\"weight_plate\",\"Technogym\"],\"palette\":[\"#1A1A1A\",\"#FFFFFF\"],\"bbox\":[-352,505,-69,591]},{\"label\":\"text\",\"caption\":\"Large, stylized dark grey text painted on a textured concrete-style wall in the background.\",\"tags\":[\"motivational\",\"wall_art\"],\"palette\":[\"#333333\",\"#C0C0C0\"],\"bbox\":[-805,-122,-548,122],\"text\":\"STRONGER\\nHAPPIER\\nA BETTER YOU\"},{\"label\":\"text\",\"caption\":\"Dark grey text on a black wall section in the upper right background.\",\"tags\":[\"motivational\",\"wall_art\"],\"palette\":[\"#333333\",\"#1A1A1A\"],\"bbox\":[-888,300,-731,435],\"text\":\"DISCIPLINE\\nBUILDS\\nFREEDOM\"},{\"label\":\"object\",\"caption\":\"Various silver and black gym machines, including a squat rack and cable stations, blurred in the background to create depth.\",\"tags\":[\"gym_equipment\",\"squat_rack\"],\"palette\":[\"#404040\",\"#C0C0C0\"],\"bbox\":[-666,-327,302,418]},{\"label\":\"text\",\"caption\":\"Small white sans-serif text printed on the chest of the left trainer's black t-shirt.\",\"tags\":[\"clothing_text\"],\"palette\":[\"#FFFFFF\",\"#1A1A1A\"],\"bbox\":[-430,-485,-360,-363],\"text\":\"MORE TO BE\\nA BETTER YOU\"},{\"label\":\"object\",\"caption\":\"A neon green terry cloth towel draped over the right trainer's left shoulder, with small black text printed on it.\",\"tags\":[\"towel\",\"gym_accessory\"],\"palette\":[\"#90EE90\",\"#000000\"],\"bbox\":[-430,385,-191,500]},{\"label\":\"text\",\"caption\":\"Small black text printed vertically on the green towel.Line truncated
"negative_prompt": "",
"height": 1776,
"width": 1184,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "生成4:3黑白悬疑电影剧照,室内一位成年侦探坐在桌边。画面左侧可见半幅百叶窗,窗外强硬光透进来,在人物脸部、白衬衫和后墙上形成同一组方向一致的窄条阴影;条纹随表面转折与遮挡发生合理变化,不能像屏幕贴纸一样跨过人物外轮廓直接贴到所有物体上。人物一半面部明亮,另一半较暗,眼睛仍可见。桌上一只黑色有线电话,听筒放在座机上。无烟雾、无霓虹、无文字、无黑边。",
"negative_prompt": "worst quality, bad anatomy",
"height": 880,
"width": 1184,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 6,
"uncond_skip_layers": "26",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "A hotel room lit only by a warm bedside lamp. The white sheets on the double bed are rumpled, pillows stacked against the headboard. A cosplayer portraying Hanako from Blue Archive lies on her side along the edge of the bed, long pink hair spilling over one shoulder, a loose braid on the other, a white flower clip still pinned near her ear. Green contacts meet the camera. A thin wire-and-LED halo glows pale pink above her head.\nShe is still in Hanako’s white sailor uniform: short sleeves, pink neck ribbon, gold buttons. The pleated skirt rides a little from the pose, showing the tops of white knee-high socks. The small jacket-style bag and prop gun rest at the foot of the bed, out of her hands. One hand props her cheek; the other lightly tugs the end of the ribbon. Knees together, calves crossed, torso leaning slightly forward. Lips parted, ears faintly flushed, gaze held on the lens as if the flash caught her mid-pose.\nBackground is only beige curtains, an unopened bottle of water on the nightstand, and the brown school bag on the carpet.",
"negative_prompt": "",
"height": 1184,
"width": 880,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "24",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "{\"scene_type\":\"Anime-style summer beach ensemble with five characters\",\"gen_brief\":\"Ultra-wide panoramic beach vacation illustration, aspect ratio 4:1. Recompose for a wide banner rather than stretching or vertically cropping a conventional image. Feature Shiroko, Hoshino, Yuuka, Hina, and Yuzu from Blue Archive, preserving their recognizable identity features and individual halos. Shiroko sits at the left eating a popsicle; Hoshino leans forward in the rear center-left, holding a beach ball and waving toward the viewer; Yuuka sits on a beach chair in the rear center-right, holding a blue drink; Hina reclines sideways across the lower center on a beach blanket; Yuzu sits at the far right hugging a penguin plush. Spread the ensemble horizontally with shallow foreground-to-background layering, moderate natural overlap, all five faces clearly visible, and complete halos within the frame. Maintain natural anatomy, consistent head sizes, round props, and comfortable spacing; do not stretch bodies or objects to fill their boxes. All wear opaque, properly fitted summer swimwear with lightweight sun-protective cover-ups. Keep the mood cheerful, cute, and non-sexualized, without emphasizing breasts, buttocks, or crotches. The background contains a broad turquoise sea, blue sky, white clouds, palm trees, and a wooden pier, with a large beach umbrella framing the upper-right area. Keep the horizon near the upper third and foreground props in a narrow lower band. Place watermelon, chilled drinks, a sandcastle, and a small crab in the foreground. Detailed Japanese anime illustration, luminous blue-and-white palette with pink, purple, and orange accents, soft sunlight, natural reflected light, finely rendered hair and fabric folds. No text or watermarks. All bounding boxes use normalized coordinates in [y_min,x_min,y_max,x_max] order. Character boxes approximately encompass their poses and overhead halos; natural overlap between characters is intentional.\",\"elements\":[{\"type\":\"panel\",\"salience\":\"background\",\"identity\":\"Panoramic tropical beach background: blue sky and white clouds above, turquoise seawater with delicate white surf in the middle distance, and warm ivory sand below. Keep distant scenery bright and uncluttered so it does not compete with the characters.\",\"bbox\":[-360,-1440,360,1440]},{\"type\":\"obj\",\"salience\":\"background\",\"identity\":\"Palm trees in the upper-left corner: trunks lean along the left edge, green fronds hang into the frame from above, and a few seaside buildings appear in the distance.\",\"bbox\":[-360,-1440,-21,-921]},{\"type\":\"obj\",\"salience\":\"background\",\"identity\":\"Large white beach umbrella: the canopy stretches from the upper center to the upper-right edge. Its dark pole stands slightly right of center, behind the characters, without crossing any face.\",\"bbox\":[-360,158,108,1368]},{\"type\":\"obj\",\"salience\":\"background\",\"identity\":\"Distant wooden pier and small pavilion on the right, extending horizontally into the blue sea, with low green islands on the horizon.\",\"bbox\":[-170,748,-57,1440]},{\"type\":\"obj\",\"salience\":\"background\",\"identity\":\"Dark folding beach chairs on the left and center-right support Shiroko and Yuuka in their seated poses, mostly obscured by the characters through natural overlap.\",\"bbox\":[-98,-1340,296,735]},{\"type\":\"obj\",\"salience\":\"background\",\"identity\":\"Blue-and-white checkered beach blanket extending from the bottom edge toward the center, with natural folds, serving as the visual base for Hina and the foreground still life.\",\"bbox\":[115,-1095,360,1268]},{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"Shiroko, seated in the left foreground: long silver-gray hair, gray wolf ears, blue eyes, a cyan crossed hair clip, and a cyan geometric halo overhead. She wears black-and-white swimwear with a loose, light-colored sun-protective jacket. Her knees point toward the center as she calmly looks toward the viewer, holding a blue popsicle near her lips. Her face is approximately at 13% of the image width and 36% of its height, measured from the top-left.\",\"bbox\":[-310,-1340,332,-720]},{\"type\":\"obj\",\"salience\":\"primary\",\"identity\":\"Hoshino, in the rear center-left: long pink hair with a prominent upward-curving tuft and a pink ring-shaped halo, winking with a cheerful smile. She wears light-colored ruffled swimwear and an open sun-protective cover-up. Leaning slightly toward the viewer, she reaches one hand forward and toward the upper left in greeting while holding a colorful beach ball with the other arm. Her face is at approximately 32% width and 30% height. She is slightly behind and to the image-right of Shiroko, with her lower body partly obscured by the foreground blanket and Hina.\",\"bbox\":[-335,-764,260,-187]},{\"type\":\"obj\",\"salience\":\"secondary\",\"identity\":\"Colorful inflatable beach ball held by Hoshino, with pale pink, pale yLine truncated
"negative_prompt": "worst quality, bad anatomy",
"height": 720,
"width": 2880,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 88,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "A candid classroom photograph, slightly off-center, with a worn dark green chalkboard filling most of the frame. Uneven window light, soft shadows, chalk dust, eraser streaks, subtle camera grain. Visible board frame and chalk tray, a blurred desk corner in the foreground. Natural, slightly irregular white chalk handwriting—not polished typography or a flat blackboard graphic. Keep all text sharp, fully visible, and free of glare.\n\nThe chalkboard reads exactly:\n\n\"MOSS-Transcribe-Diarize is our flagship SOTA model family\nfor turning real-world long-form audio into structured,\nspeaker- aware transcripts in one pass. Instead of stitching\ntogether separate ASR and diarization systems, these\nmodels jointly perform speech transcription and speaker\ndiarization, producing time-aligned text with precise\ntimestamps and consistent speaker labels such as [S01], [S02], and beyond.\"",
"negative_prompt": "worst quality, bad anatomy, ugly face",
"height": 768,
"width": 1360,
"steps": 50,
"cfg": 3,
"shift": 6,
"num_images": 1,
"seed": 2051794908,
"uncond_skip_layers": "",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "masterpiece, best quality, highres, most attractive face\n生成一个穿JK短裙的少女,长得非常非常好看的那种类型的。",
"negative_prompt": "worst quality, low quality, blurry, jpeg artifacts, bad anatomy",
"height": 1184,
"width": 880,
"steps": 50,
"cfg": 5,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "22",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

+27
View File
@@ -0,0 +1,27 @@
{
"schema_version": 2,
"model_repo": "OpenMOSS-Team/MOSS-Image-Base",
"model": "MOSS-Image-Base",
"parameters": {
"prompt": "A cinematic, photorealistic nighttime scene of a small neighborhood convenience store on a quiet, rain-soaked street. The warmly illuminated storefront occupies the right half of the frame, while the street recedes into soft mist on the left. A lone young adult wearing a charcoal coat stands just outside the entrance beneath a transparent umbrella, seen in three-quarter rear view, gazing through the glass. Amber light reveals shelves inside and spills across the sidewalk, mingling with muted teal neon reflections in shallow puddles. Individual raindrops bead on the umbrella and catch the storefront light; fine streaks of rain remain visible against the darker street. A slightly weathered bicycle leans beside the entrance. Distant apartment windows and a few out-of-focus streetlights add depth without distracting from the figure. Eye-level wide shot, 35mm lens aesthetic, natural perspective, balanced negative space, restrained teal-and-amber color grading, realistic wet asphalt and glass textures, soft highlight bloom, subtle film grain, and gentle atmospheric depth. Quiet, intimate, and nostalgic rather than dramatic; believable lighting, with the figure clearly silhouetted against the warm window. No prominent readable lettering, logos, or watermarks.",
"negative_prompt": "worst quality, bad anatomy",
"height": 944,
"width": 1680,
"steps": 50,
"cfg": 3,
"shift": 5,
"num_images": 1,
"seed": 42,
"uncond_skip_layers": "26",
"slg_layers": "",
"slg_scale": 0,
"slg_start": 0,
"slg_stop": 1,
"max_sequence_length": 4096,
"offload": "none",
"compile_transformer": false
},
"sampler": "Euler",
"recovered_from": "Running Space gallery and example selection",
"image": "image.png"
}
+26
View File
@@ -0,0 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2026.7 427.5" width="2026.7" height="427.5"><g transform="translate(52.5,52.5) scale(0.68617) translate(-229,-277)"><defs><linearGradient id="mg" x1="0" y1="277" x2="0" y2="747" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#3b7fe0"/><stop offset="0.55" stop-color="#4aa5f2"/><stop offset="1" stop-color="#7fe6fb"/></linearGradient><linearGradient id="dg" x1="0" y1="277" x2="0" y2="747" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a9e3fc"/><stop offset="1" stop-color="#c8f6fd"/></linearGradient><clipPath id="lh"><rect x="0" y="0" width="581.06" height="1024"/></clipPath></defs><path d="M235.51,747 A5.64,5.64 0 0 1 230.53,738.71 L472.64,284.47 A14.1,14.1 0 0 1 485.08,277 L530.67,277 A35.25,35.25 0 0 1 565.92,312.25 L565.92,684.02 A28.2,28.2 0 0 1 537.72,712.22 L504.82,712.22 A28.2,28.2 0 0 1 476.62,684.02 L476.62,444.54 L322.04,734.55 A23.5,23.5 0 0 1 301.3,747 Z" fill="url(#mg)"/><rect x="698.98" y="279.87" width="46.48" height="46.48" rx="8.36" fill="#3b7fe0"/>
<rect x="751.2" y="279.87" width="46.48" height="46.48" rx="8.36" fill="#3b7fe0"/>
<rect x="646.76" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#ade5fc"/>
<rect x="698.98" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#3e88e4"/>
<rect x="751.2" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#3e88e4"/>
<rect x="646.76" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#b1e8fc"/>
<rect x="698.98" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#4290e8"/>
<rect x="751.2" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#4290e8"/>
<rect x="594.54" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#b5eafc"/>
<rect x="646.76" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#b5eafc"/>
<rect x="698.98" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#4599ec"/>
<rect x="751.2" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#4599ec"/>
<rect x="594.54" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#b8ecfc"/>
<rect x="646.76" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#b8ecfc"/>
<rect x="698.98" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#49a2f0"/>
<rect x="751.2" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#49a2f0"/>
<rect x="594.54" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#bceffd"/>
<rect x="698.98" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#53b0f4"/>
<rect x="751.2" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#53b0f4"/>
<rect x="594.54" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#c0f1fd"/>
<rect x="698.98" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#62c2f6"/>
<rect x="751.2" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#62c2f6"/>
<rect x="698.98" y="645.43" width="46.48" height="46.48" rx="8.36" fill="#70d4f8"/>
<rect x="751.2" y="645.43" width="46.48" height="46.48" rx="8.36" fill="#70d4f8"/>
<rect x="698.98" y="697.65" width="46.48" height="46.48" rx="8.36" fill="#7fe6fb"/>
<rect x="751.2" y="697.65" width="46.48" height="46.48" rx="8.36" fill="#7fe6fb"/></g><g transform="translate(568.93,288.75)"><g fill="#ffffff"><path d="M16.85 0V-150H63.29L97.5 -65.65H101.4L135.41 -150H182.67V0H149.28V-128.01L154.11 -127.6L114.5 -30.41H82.29L42.48 -127.6L47.67 -128.01V0Z"/><path d="M288.34 4.01Q267.89 4.01 252.84 -3.11Q237.79 -10.22 227.88 -21.86Q217.96 -33.49 213.11 -47Q208.25 -60.51 208.25 -73.15V-77.67Q208.25 -91.64 213.29 -105.28Q218.32 -118.92 228.44 -130.04Q238.56 -141.16 253.51 -147.79Q268.46 -154.42 288.34 -154.42Q308.07 -154.42 323.01 -147.79Q337.96 -141.16 348.08 -130.04Q358.2 -118.92 363.31 -105.28Q368.42 -91.64 368.42 -77.67V-73.15Q368.42 -60.51 363.49 -47Q358.56 -33.49 348.65 -21.86Q338.73 -10.22 323.68 -3.11Q308.63 4.01 288.34 4.01ZM288.34 -27.43Q299.02 -27.43 307.53 -31.13Q316.03 -34.83 322.04 -41.43Q328.05 -48.03 331.18 -56.66Q334.32 -65.29 334.32 -75.21Q334.32 -85.74 331.1 -94.47Q327.89 -103.2 321.88 -109.6Q315.87 -115.99 307.37 -119.49Q298.87 -122.98 288.34 -122.98Q277.65 -122.98 269.15 -119.49Q260.65 -115.99 254.64 -109.6Q248.63 -103.2 245.5 -94.47Q242.36 -85.74 242.36 -75.21Q242.36 -65.29 245.5 -56.66Q248.63 -48.03 254.64 -41.43Q260.65 -34.83 269.15 -31.13Q277.65 -27.43 288.34 -27.43Z"/><path d="M445.12 4.01Q424.73 4.01 410.73 -2.47Q396.73 -8.94 389.51 -20.21Q382.29 -31.49 382.29 -46.03H415.07Q415.07 -40.33 418.2 -35.32Q421.34 -30.31 427.94 -27.33Q434.54 -24.35 445.12 -24.35Q454.52 -24.35 460.92 -26.89Q467.31 -29.43 470.57 -33.83Q473.84 -38.22 473.84 -43.97Q473.84 -51.22 467.67 -55.43Q461.51 -59.64 447.79 -60.77L436.39 -61.75Q413.99 -63.7 400.68 -75.77Q387.38 -87.84 387.38 -107.77Q387.38 -122.31 394.21 -132.74Q401.04 -143.17 413.42 -148.79Q425.8 -154.42 442.55 -154.42Q460.33 -154.42 472.94 -148.36Q485.55 -142.29 492.3 -131.3Q499.06 -120.31 499.06 -105.62H466.28Q466.28 -111.11 463.59 -115.79Q460.89 -120.46 455.63 -123.26Q450.36 -126.06 442.55 -126.06Q435.15 -126.06 430.17 -123.62Q425.19 -121.18 422.67 -116.99Q420.15 -112.81 420.15 -107.77Q420.15 -101.4 424.67 -96.73Q429.2 -92.05 439.57 -91.18L450.98 -90.21Q467.47 -88.82 479.97 -83.12Q492.48 -77.41 499.55 -67.68Q506.61 -57.95 506.61 -43.97Q506.61 -29.59 499.14 -18.75Q491.66 -7.91 477.92 -1.95Q464.18 4.01 445.12 4.01Z"/><path d="M582.17 4.01Q561.78 4.01 547.78 -2.47Q533.78 -8.94 526.57 -20.21Q519.35 -31.49 519.35 -46.03H552.12Q552.12 -40.33 555.26 -35.32Q558.39 -30.31 564.99 -27.33Q571.59 -24.35 582.17 -24.35Q591.58 -24.35 597.97 -26.89Q604.37 -29.43 607.63 -33.83Q610.89 -38.22 610.89 -43.97Q610.89 -51.22 604.73 -55.43Q598.56 -59.64 584.85 -60.77L573.44 -61.75Q551.04 -63.7 537.74 -75.77Q524.43 -87.84 524.43 -107.77Q524.43 -122.31 531.27 -132.74Q538.1 -143.17 550.48 -148.79Q562.86 -154.42 579.61 -154.42Q597.38 -154.42 609.99 -148.36Q622.6 -142.29 629.36 -131.3Q636.11 -120.31 636.11 -105.62H603.34Q603.34 -111.11 600.64 -115.79Q597.95 -120.46 592.68 -123.26Q587.41 -126.06 579.61 -126.06Q572.21 -126.06 567.23 -123.62Q562.24 -121.18 559.73 -116.99Q557.21 -112.81 557.21 -107.77Q557.21 -101.4 561.73 -96.73Q566.25 -92.05 576.63 -91.18L588.03 -90.21Q604.52 -88.82 617.03 -83.12Q629.54 -77.41 636.6 -67.68Q643.66 -57.95 643.66 -43.97Q643.66 -29.59 636.19 -18.75Q628.72 -7.91 614.97 -1.95Q601.23 4.01 582.17 4.01Z"/></g><g fill="#8cc4ff" transform="translate(650.14,0)"><path d="M12.02 -46.95V-67.91H91.85V-46.95Z"/><path d="M124.52 0V-150H149.18V0Z"/><path d="M187.29 0V-110.65H206.4V-63.13H204.14Q204.14 -79.57 208.41 -90.87Q212.67 -102.17 221.15 -108.11Q229.62 -114.04 242.47 -114.04H243.49Q256.39 -114.04 264.91 -108.11Q273.44 -102.17 277.63 -90.87Q281.82 -79.57 281.82 -63.13H275.34Q275.34 -79.57 279.68 -90.87Q284.02 -102.17 292.58 -108.11Q301.13 -114.04 313.97 -114.04H315Q327.89 -114.04 336.55 -108.11Q345.21 -102.17 349.52 -90.87Q353.84 -79.57 353.84 -63.13V0H329.69V-66.63Q329.69 -78.6 323.71 -85.38Q317.72 -92.16 306.99 -92.16Q295.94 -92.16 289.29 -85.07Q282.64 -77.98 282.64 -65.6V0H258.49V-66.63Q258.49 -78.6 252.51 -85.38Q246.52 -92.16 235.79 -92.16Q224.74 -92.16 218.09 -85.07Q211.44 -77.98 211.44 -65.6V0Z"/><path d="M454.16 0V-32.98H450.15V-70.38Q450.15 -80.8 444.86 -86.07Q439.57 -91.34 429.04 -91.34Q423.29 -91.34 416.3 -91.13Q409.32 -90.92 402.59 -90.67Q395.86 -90.41 390.72 -90V-110.75Q395.34 -111.16 400.81 -111.5Q406.28 -111.83 412.11 -111.96Q417.95 -112.09 423.18 -112.09Q440.19 -112.09 451.26 -107.8Q462.33 -103.51 467.8 -94.16Q473.27 -84.81 473.27 -69.3V0ZM418.2 2.88Q405.98 2.88 396.96 -1.36Q387.95 -5.6 383.01 -13.64Q378.08 -21.68 378.08 -32.98Q378.08 -44.95 383.71 -52.78Q389.33 -60.62 399.86 -64.55Q410.39 -68.48 424.88 -68.48H452.72V-52.55H424.26Q413.42 -52.55 407.62 -47.29Q401.82 -42.02 401.82 -33.65Q401.82 -25.33 407.62 -20.21Q413.42 -15.1 424.26 -15.1Q430.74 -15.1 436.46 -17.47Q442.19 -19.83 445.97 -25.45Q449.74 -31.08 450.15 -40.99L456.32 -33.08Q455.29 -21.37 450.67 -13.41Q446.04 -5.45 437.93 -1.28Q429.81 2.88 418.2 2.88Z"/><path d="M549.09 43.41Q541.28 43.41 533.27 42.79Q525.26 42.17 518.22 41.15V20.86Q525.57 21.83 533.86 22.5Line truncated

After

Width:  |  Height:  |  Size: 9.6 KiB

+26
View File
@@ -0,0 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2026.7 427.5" width="2026.7" height="427.5"><g transform="translate(52.5,52.5) scale(0.68617) translate(-229,-277)"><defs><linearGradient id="mg" x1="0" y1="277" x2="0" y2="747" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#3b7fe0"/><stop offset="0.55" stop-color="#4aa5f2"/><stop offset="1" stop-color="#7fe6fb"/></linearGradient><linearGradient id="dg" x1="0" y1="277" x2="0" y2="747" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a9e3fc"/><stop offset="1" stop-color="#c8f6fd"/></linearGradient><clipPath id="lh"><rect x="0" y="0" width="581.06" height="1024"/></clipPath></defs><path d="M235.51,747 A5.64,5.64 0 0 1 230.53,738.71 L472.64,284.47 A14.1,14.1 0 0 1 485.08,277 L530.67,277 A35.25,35.25 0 0 1 565.92,312.25 L565.92,684.02 A28.2,28.2 0 0 1 537.72,712.22 L504.82,712.22 A28.2,28.2 0 0 1 476.62,684.02 L476.62,444.54 L322.04,734.55 A23.5,23.5 0 0 1 301.3,747 Z" fill="url(#mg)"/><rect x="698.98" y="279.87" width="46.48" height="46.48" rx="8.36" fill="#3b7fe0"/>
<rect x="751.2" y="279.87" width="46.48" height="46.48" rx="8.36" fill="#3b7fe0"/>
<rect x="646.76" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#ade5fc"/>
<rect x="698.98" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#3e88e4"/>
<rect x="751.2" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#3e88e4"/>
<rect x="646.76" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#b1e8fc"/>
<rect x="698.98" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#4290e8"/>
<rect x="751.2" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#4290e8"/>
<rect x="594.54" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#b5eafc"/>
<rect x="646.76" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#b5eafc"/>
<rect x="698.98" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#4599ec"/>
<rect x="751.2" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#4599ec"/>
<rect x="594.54" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#b8ecfc"/>
<rect x="646.76" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#b8ecfc"/>
<rect x="698.98" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#49a2f0"/>
<rect x="751.2" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#49a2f0"/>
<rect x="594.54" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#bceffd"/>
<rect x="698.98" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#53b0f4"/>
<rect x="751.2" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#53b0f4"/>
<rect x="594.54" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#c0f1fd"/>
<rect x="698.98" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#62c2f6"/>
<rect x="751.2" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#62c2f6"/>
<rect x="698.98" y="645.43" width="46.48" height="46.48" rx="8.36" fill="#70d4f8"/>
<rect x="751.2" y="645.43" width="46.48" height="46.48" rx="8.36" fill="#70d4f8"/>
<rect x="698.98" y="697.65" width="46.48" height="46.48" rx="8.36" fill="#7fe6fb"/>
<rect x="751.2" y="697.65" width="46.48" height="46.48" rx="8.36" fill="#7fe6fb"/></g><g transform="translate(568.93,288.75)"><g fill="#1d3f8f"><path d="M16.85 0V-150H63.29L97.5 -65.65H101.4L135.41 -150H182.67V0H149.28V-128.01L154.11 -127.6L114.5 -30.41H82.29L42.48 -127.6L47.67 -128.01V0Z"/><path d="M288.34 4.01Q267.89 4.01 252.84 -3.11Q237.79 -10.22 227.88 -21.86Q217.96 -33.49 213.11 -47Q208.25 -60.51 208.25 -73.15V-77.67Q208.25 -91.64 213.29 -105.28Q218.32 -118.92 228.44 -130.04Q238.56 -141.16 253.51 -147.79Q268.46 -154.42 288.34 -154.42Q308.07 -154.42 323.01 -147.79Q337.96 -141.16 348.08 -130.04Q358.2 -118.92 363.31 -105.28Q368.42 -91.64 368.42 -77.67V-73.15Q368.42 -60.51 363.49 -47Q358.56 -33.49 348.65 -21.86Q338.73 -10.22 323.68 -3.11Q308.63 4.01 288.34 4.01ZM288.34 -27.43Q299.02 -27.43 307.53 -31.13Q316.03 -34.83 322.04 -41.43Q328.05 -48.03 331.18 -56.66Q334.32 -65.29 334.32 -75.21Q334.32 -85.74 331.1 -94.47Q327.89 -103.2 321.88 -109.6Q315.87 -115.99 307.37 -119.49Q298.87 -122.98 288.34 -122.98Q277.65 -122.98 269.15 -119.49Q260.65 -115.99 254.64 -109.6Q248.63 -103.2 245.5 -94.47Q242.36 -85.74 242.36 -75.21Q242.36 -65.29 245.5 -56.66Q248.63 -48.03 254.64 -41.43Q260.65 -34.83 269.15 -31.13Q277.65 -27.43 288.34 -27.43Z"/><path d="M445.12 4.01Q424.73 4.01 410.73 -2.47Q396.73 -8.94 389.51 -20.21Q382.29 -31.49 382.29 -46.03H415.07Q415.07 -40.33 418.2 -35.32Q421.34 -30.31 427.94 -27.33Q434.54 -24.35 445.12 -24.35Q454.52 -24.35 460.92 -26.89Q467.31 -29.43 470.57 -33.83Q473.84 -38.22 473.84 -43.97Q473.84 -51.22 467.67 -55.43Q461.51 -59.64 447.79 -60.77L436.39 -61.75Q413.99 -63.7 400.68 -75.77Q387.38 -87.84 387.38 -107.77Q387.38 -122.31 394.21 -132.74Q401.04 -143.17 413.42 -148.79Q425.8 -154.42 442.55 -154.42Q460.33 -154.42 472.94 -148.36Q485.55 -142.29 492.3 -131.3Q499.06 -120.31 499.06 -105.62H466.28Q466.28 -111.11 463.59 -115.79Q460.89 -120.46 455.63 -123.26Q450.36 -126.06 442.55 -126.06Q435.15 -126.06 430.17 -123.62Q425.19 -121.18 422.67 -116.99Q420.15 -112.81 420.15 -107.77Q420.15 -101.4 424.67 -96.73Q429.2 -92.05 439.57 -91.18L450.98 -90.21Q467.47 -88.82 479.97 -83.12Q492.48 -77.41 499.55 -67.68Q506.61 -57.95 506.61 -43.97Q506.61 -29.59 499.14 -18.75Q491.66 -7.91 477.92 -1.95Q464.18 4.01 445.12 4.01Z"/><path d="M582.17 4.01Q561.78 4.01 547.78 -2.47Q533.78 -8.94 526.57 -20.21Q519.35 -31.49 519.35 -46.03H552.12Q552.12 -40.33 555.26 -35.32Q558.39 -30.31 564.99 -27.33Q571.59 -24.35 582.17 -24.35Q591.58 -24.35 597.97 -26.89Q604.37 -29.43 607.63 -33.83Q610.89 -38.22 610.89 -43.97Q610.89 -51.22 604.73 -55.43Q598.56 -59.64 584.85 -60.77L573.44 -61.75Q551.04 -63.7 537.74 -75.77Q524.43 -87.84 524.43 -107.77Q524.43 -122.31 531.27 -132.74Q538.1 -143.17 550.48 -148.79Q562.86 -154.42 579.61 -154.42Q597.38 -154.42 609.99 -148.36Q622.6 -142.29 629.36 -131.3Q636.11 -120.31 636.11 -105.62H603.34Q603.34 -111.11 600.64 -115.79Q597.95 -120.46 592.68 -123.26Q587.41 -126.06 579.61 -126.06Q572.21 -126.06 567.23 -123.62Q562.24 -121.18 559.73 -116.99Q557.21 -112.81 557.21 -107.77Q557.21 -101.4 561.73 -96.73Q566.25 -92.05 576.63 -91.18L588.03 -90.21Q604.52 -88.82 617.03 -83.12Q629.54 -77.41 636.6 -67.68Q643.66 -57.95 643.66 -43.97Q643.66 -29.59 636.19 -18.75Q628.72 -7.91 614.97 -1.95Q601.23 4.01 582.17 4.01Z"/></g><g fill="#3b7fe0" transform="translate(650.14,0)"><path d="M12.02 -46.95V-67.91H91.85V-46.95Z"/><path d="M124.52 0V-150H149.18V0Z"/><path d="M187.29 0V-110.65H206.4V-63.13H204.14Q204.14 -79.57 208.41 -90.87Q212.67 -102.17 221.15 -108.11Q229.62 -114.04 242.47 -114.04H243.49Q256.39 -114.04 264.91 -108.11Q273.44 -102.17 277.63 -90.87Q281.82 -79.57 281.82 -63.13H275.34Q275.34 -79.57 279.68 -90.87Q284.02 -102.17 292.58 -108.11Q301.13 -114.04 313.97 -114.04H315Q327.89 -114.04 336.55 -108.11Q345.21 -102.17 349.52 -90.87Q353.84 -79.57 353.84 -63.13V0H329.69V-66.63Q329.69 -78.6 323.71 -85.38Q317.72 -92.16 306.99 -92.16Q295.94 -92.16 289.29 -85.07Q282.64 -77.98 282.64 -65.6V0H258.49V-66.63Q258.49 -78.6 252.51 -85.38Q246.52 -92.16 235.79 -92.16Q224.74 -92.16 218.09 -85.07Q211.44 -77.98 211.44 -65.6V0Z"/><path d="M454.16 0V-32.98H450.15V-70.38Q450.15 -80.8 444.86 -86.07Q439.57 -91.34 429.04 -91.34Q423.29 -91.34 416.3 -91.13Q409.32 -90.92 402.59 -90.67Q395.86 -90.41 390.72 -90V-110.75Q395.34 -111.16 400.81 -111.5Q406.28 -111.83 412.11 -111.96Q417.95 -112.09 423.18 -112.09Q440.19 -112.09 451.26 -107.8Q462.33 -103.51 467.8 -94.16Q473.27 -84.81 473.27 -69.3V0ZM418.2 2.88Q405.98 2.88 396.96 -1.36Q387.95 -5.6 383.01 -13.64Q378.08 -21.68 378.08 -32.98Q378.08 -44.95 383.71 -52.78Q389.33 -60.62 399.86 -64.55Q410.39 -68.48 424.88 -68.48H452.72V-52.55H424.26Q413.42 -52.55 407.62 -47.29Q401.82 -42.02 401.82 -33.65Q401.82 -25.33 407.62 -20.21Q413.42 -15.1 424.26 -15.1Q430.74 -15.1 436.46 -17.47Q442.19 -19.83 445.97 -25.45Q449.74 -31.08 450.15 -40.99L456.32 -33.08Q455.29 -21.37 450.67 -13.41Q446.04 -5.45 437.93 -1.28Q429.81 2.88 418.2 2.88Z"/><path d="M549.09 43.41Q541.28 43.41 533.27 42.79Q525.26 42.17 518.22 41.15V20.86Q525.57 21.83 533.86 22.5Line truncated

After

Width:  |  Height:  |  Size: 9.6 KiB

+26
View File
@@ -0,0 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024"><defs><linearGradient id="mg" x1="0" y1="277" x2="0" y2="747" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#3b7fe0"/><stop offset="0.55" stop-color="#4aa5f2"/><stop offset="1" stop-color="#7fe6fb"/></linearGradient><linearGradient id="dg" x1="0" y1="277" x2="0" y2="747" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a9e3fc"/><stop offset="1" stop-color="#c8f6fd"/></linearGradient><clipPath id="lh"><rect x="0" y="0" width="581.06" height="1024"/></clipPath></defs><path d="M235.51,747 A5.64,5.64 0 0 1 230.53,738.71 L472.64,284.47 A14.1,14.1 0 0 1 485.08,277 L530.67,277 A35.25,35.25 0 0 1 565.92,312.25 L565.92,684.02 A28.2,28.2 0 0 1 537.72,712.22 L504.82,712.22 A28.2,28.2 0 0 1 476.62,684.02 L476.62,444.54 L322.04,734.55 A23.5,23.5 0 0 1 301.3,747 Z" fill="url(#mg)"/><rect x="698.98" y="279.87" width="46.48" height="46.48" rx="8.36" fill="#3b7fe0"/>
<rect x="751.2" y="279.87" width="46.48" height="46.48" rx="8.36" fill="#3b7fe0"/>
<rect x="646.76" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#ade5fc"/>
<rect x="698.98" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#3e88e4"/>
<rect x="751.2" y="332.09" width="46.48" height="46.48" rx="8.36" fill="#3e88e4"/>
<rect x="646.76" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#b1e8fc"/>
<rect x="698.98" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#4290e8"/>
<rect x="751.2" y="384.32" width="46.48" height="46.48" rx="8.36" fill="#4290e8"/>
<rect x="594.54" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#b5eafc"/>
<rect x="646.76" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#b5eafc"/>
<rect x="698.98" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#4599ec"/>
<rect x="751.2" y="436.54" width="46.48" height="46.48" rx="8.36" fill="#4599ec"/>
<rect x="594.54" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#b8ecfc"/>
<rect x="646.76" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#b8ecfc"/>
<rect x="698.98" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#49a2f0"/>
<rect x="751.2" y="488.76" width="46.48" height="46.48" rx="8.36" fill="#49a2f0"/>
<rect x="594.54" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#bceffd"/>
<rect x="698.98" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#53b0f4"/>
<rect x="751.2" y="540.98" width="46.48" height="46.48" rx="8.36" fill="#53b0f4"/>
<rect x="594.54" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#c0f1fd"/>
<rect x="698.98" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#62c2f6"/>
<rect x="751.2" y="593.21" width="46.48" height="46.48" rx="8.36" fill="#62c2f6"/>
<rect x="698.98" y="645.43" width="46.48" height="46.48" rx="8.36" fill="#70d4f8"/>
<rect x="751.2" y="645.43" width="46.48" height="46.48" rx="8.36" fill="#70d4f8"/>
<rect x="698.98" y="697.65" width="46.48" height="46.48" rx="8.36" fill="#7fe6fb"/>
<rect x="751.2" y="697.65" width="46.48" height="46.48" rx="8.36" fill="#7fe6fb"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

+10
View File
@@ -0,0 +1,10 @@
# Default prompts for Gradio. Save as UTF-8 and restart the UI after editing.
# Text below [prompt_prefix] is prefilled in the editable Prompt field.
# Text below [negative_prompt] is prefilled in the editable Negative Prompt field.
# Both sections support multiple lines. Leave a section empty to disable its default.
[prompt_prefix]
best quality, masterpiece
[negative_prompt]
nsfw, worst quality, bad anatomy, watermark, jpeg artifact
View File
Whitespace-only changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="4128" height="1328" viewBox="0 0 4128 1328"><defs><filter id="soften" x="-5%" y="-5%" width="110%" height="110%" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="5" /></filter><clipPath id="left-canvas"><rect width="1936" height="1088" /></clipPath></defs><rect width="4128" height="1328" fill="white" /><g transform="translate(48 48)"><rect width="4032" height="1184" fill="white" /><g clip-path="url(#left-canvas)"><image width="1936" height="1088" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB5AAAARACAIAAACnblhQAAEAAElEQVR4nOy9d6BcV3Xv/137zNymq94lV7nIBffeG6YTCJBACAkhAVJJXl5e8pL3S/JS4CWBEEKooTeDAZtijI3BYNy7JFvFKrZlWb3r9ntn5uz1+2OXs0+ZuXOrrqT1wVzNnDln17X3zPnuddamWlwjIgBgImKGgSAIgiAIgiAIgiAIgiAIgiAI4wcBnH4Lc4SAWCNSJfJHiZEI1eFVgiAIgiAIgiAIgiAIgiAIgjAO5H2lCQATiMC6BKLwHBGqBUEQBEEQBEEQBEEQBEEQhEmGoEBcIgIY7JyxAw9rr2JzkeqdUbb91Zxz6z7SOcqqM2pG1w6JU//E02QJQ2PO2zanyxyOAgQfZY7nU27MSBvk2DTCTE9lDuZ7Kn8O0ifkCS+pd3khmZPzvTNFJsO8tWcm+3zrNZ9UA7hO1kjnjob5Up1hWHha4bANC5C/atgCoE7LjKhb8+087OVjz/TwQkUWUvywV9GFo8iocBI4UpprosnMmY0nupHOWiMKH1dv/DbIt5nRjZwBNDnEmq/p6H7JNEh/FF8QzZShwXdik7+Ohp3bJ5PG04hh2BPqMY7f0fUSyf+GaXxjlaHBT5pR91GTX0AYrqmb+eKeOJr/Dm3yd07+xwaCC0eU9SjOnFDqTbCFT2Bnzqz3Vd7Mz78GpzWY7evl0vhHY+MBWJhdg0uaGR1hSZofyPkUGp8/Re4jJodjpJoh41vl/I+lUWdR7x6q8a+vxjSeNwo1llH8YvTn5Of/5mkm5WFTQJ3b7TCdwimucVMU3kFnbu2PlHFU2CwGZlcRAoE0gyjWMYEYoKDabM5wlwUJHVltIQiCIAiCIAiCIAiCIAiCIEwRipcWnBzNIFJkDrD5A6dn+8sYAIPYppWR9gnJcSFEGkQQBEEQhKmJ/EoRBEEQBEEQJh/5FTpGjrgGpNxbSh9MXnPwF0CJAUo+JU4+JQIziMAAG4frwDedKJtUmNOUcsHO+NVPcr55Cr3fm6GwCpyuYOMnagtLkn8GoV6O+WfEhn3mq3mm1IOok0mTFc88HNrM86cN7AG5fm/8wF3+8mao98gh6lSnSaOa+qbS5BNSk5bOMUXGkuuNl8bPumaerqKcxQ57fiZZNOzHcTfpxoMIdZqlmcGVH9HD5jWi9CeCwifvxliSxu2Qf/Qvc2Y9GjTpsN/1YQpNInMLRjXNDvtwa/6BzXEvgzBSGv/2LvyOaCbBo7vXmjf1/EcGmgIN1cxs3+Q5hrBSw87njXMp/LJoZqqvd1V44Xjd/07oF3czvzqazz3fFJ5Rf+/nHzSfyhT+Bs6c0IBhTa75BAtvLfNvG/9eKmQUJpFJv1DcaHCkQbIj+s3cjATU+BfgsIxuvj1chj05mTYYCFN8OA/LBJW/nlI0Fij3OpVg0ElJXv4ainUcXhbMLoflrjJdBHtwKvzcEQRBEARBEARBEARBEARBODaptzg66kVizn1MYIYiheyiknlHY1TRRwW5suQ1eBK1WhAEQRAEQRAEQRAEQRAE4XCQkW3zL4a9Nv8kLvlXHHhQq+AUSmflkzgc2rUgCIIgCIIgCIIgCIIgCIIwFckrxoUacgNhmf0/nD5T5U4K/xomwbW5GU08XzBBEARBEARBEARBEARBEARh4uBAmM0otJxTa7m+sJyPHc8okp5LuSP5LQUmIRB7867jEhhEEARBEARBEARBEARBEARhcmgQBqQwsHOTaXL4Jrww8bBOy+OT7GEtCIIgCIIgCIIgCIIgCIIgHCNQvW0LMx7WJOK0IAiCIAiCIAiCIAiCIAiCMOkQ0psuInCszocUEQRBEARBEARBEARBEARBEITxokB5VkUfUMO3giAIgiAIgiAIgiAIgiAIgjBGMsozIxfDWrRpQRAEQRAEQRAEQRAEQRAEYXLIKtLKHxWtWhAEQRAEQRAEQRAEQRAEQTiMqOFPEQRBEARBEARBEARBEARBEISJJyNYc+6FIAiCIAiCIAiCIAiCIAiCIEwEWSG6cNNFlgAhgiAIgiAIgiAIgiAIgiAIwiSTxLBOIx7WgiAIgiAIgiAIgiAIgiAIwqSSeFiLRC0IgiAIgiAIgiAIgiAIgiAMRxhZmnNHMi9GRmnUhRIEQRAEQRAEQRAEQRAEQRCOYRpElh5l0Gm36SJL1GpBEARBEARBEARBEARBEARhWMZfp/Y4wVrkakEQBEEQBEEQBEEQBEEQBGF4JjC8tPKvJIa1IAiCIAiCIAiCIAiCIAiCMBx592d/ZKQyczapJCTIcFkKgiAIgiAIgiAIgiAIgiAIQgNGKixnhWlVeJb4WwuCIAiCIAiCIAiCIAiCIAiTQiJH1xOsBUEQBEEQBEEQBEEQBEEQBCEP517kP2pwpBEiWAuCIAiCIAiCIAiCIAiCIAhjgYO/I70qRWnsZREEQRAEQRAEQRAEQRAEQRCODTLadANv69HgPawlaLUgCIIgCIIgCIIgCIIgCIJQj1BDpjqvx4qEBBEEQRAEQRAEQRAEQRAEQRBGBNd5PYrLU2QFa3G0FgRBEARBEARBEARBEARBEADkIn5MuH5cEMOax9eHWxCEYxSZSwRBEARBEARBEARBEI5cRu1DPSZRWzZdFARhghC1WhAEQRAEQRAEQRAE4chlLNoONSFbF58gMawFQRAEQRAEQRAEQRAEQRCEQkbhLk25FyMg72EtUawFQRAEQRAEQRAEQRAEQRCE0WnFnHsxAhp4WI8pXUEQBEEQBEEQBEEQBEEQBOFIxrhIT5Y+zIARrI8QQZobvhUEQRAEQRAEQRAEQRAEQRDGkfHSYLn5pOp6WE89PZhyb6deGQVBEARBEARBEARBEARBEI4Gxld9pSZDehyJmy76+oxln0pBEMbIlF0x4mDVjnPH8yc3SCSTWv6qKdsIQkhhN3H6P9Tpa0EQBOGIZty/suVrwpD/oYX0EflKFUYEN/wlVvjbXhAEQTjiMGp1U5sx1hWsp7AY7IsmX1fCWGjSfuTXdkjhT8lQ7EPRcdQ5YYLITBGFxSgUtQurRkUX+qum8EwpFCxXNLjbySyFyqg/lpm4EGRjEc7EJgWhefKjmMfv6czCr/7876LGRRoj9b7OJmGiyHyZUlHdOfiZVM+HYBT5ClOZYTuowQnNuIaQG3qNf3tPhE8J5wx7FOr5RPyWaPK0yZkWBEEQmmQEP10o1rE9J5j8KfUvTw1RJvxJFL7AlCnhkcKUaq6wQw97mJdxKUBYl7Cdp1Szj4jMoGuSBueHEnAoDmaOF+Z72I2kHmHBCstM9euVbxAERzLn1Dt4zDJp9iCtPY6Mej7kOmMH6fmk3vhC+pzw+IiY0O+skSbeWDurtwBTrxlHSmEh84XPfyc2TiFzVabvCrOod7BB4k0Wo17BmjxhWEtr5usS6UZA+njhaZzr/ca/mcdiD5P/C6feF+4kM44LnBNakfysMqIZ5rC08Kjzbfzbu/FPygYTS+HM3GB0Nx7Xox5uo26TBl8Khe2AOl+UhT9Hj1ym2m3FGMszxhlpHFtj7EkNO0yGHUT5L838b4lMdqP4ddfkEC78Bq/3tT5GRvGN3PiXWP7MBreuhSmP4ja2mcappyQ0PnksOR7LTNAtT4PECcxQRLGOCeCcYM0AjcACJpQGPwKmSAkPI4WNg6LZpDH1ft41M7ZHrTvUK8noFNKpQ73vvClrooWdWE/9QX3VNax1YToYv0aop5LU++hIZNj7oilrURNHoQQz0T3eQGsTGlAok2UmlsaXN/kVNiL1MCxSM4kfUxSqnJkTPGPRTUYnnB2hjF2AGMf2GendeKHkjZEUqd4XWTMUqo1T7Yv+qDdgYdKoZ+040tYMBGF8mUxTHOlXTONVLuRSa7Iu9YrR5M+wzK33iNbhxki97FA/lwbLioUn5M9sRm8pFMeGLW3jHyH1llLG+FMnLGGmSJN8Nzo5olw2fVfPQLAOD/uLgn8nWQ4O26WZ1jkiBMGxELbDZN7jjTr9o0BxnmgaC8HNrxaMnbzEnJd1Rt2JzXzXjo56X/xichnqDcYjYqoci0Qy0YiEPQVlI0EQjg7kq1wQBEEQhEKm1I+ExoWpJ/XUW0JoPsd6noLjy+S08zCCdd0Y1ofPCqg5eYLSf+no1Q7COqLo74jSaZBy/hxK51vvv3zxkFbKRlqwsZx2ZMFFLemZhCoXZjou+WaWu/LGZj4d9aII6jRa5pyjgBH1SN5+CofwEUG+tIe95KOefo8+6vVL4VdDodWNvQGlI6YOU2qcHmUc3e1ZWLupcyMqCIIgCGOn3v3XqL/ip+xtXePyjOVTz+H6kdDg3qfwtHq3QvV8bRuIcoUlmUL3QRz8HXeGDQkyyc7LY/eU9DLZlOi8+jRw/q9X8nqu1sJRAAVdPwrbaJLCFDIHJ8KuMhN0+LZxTcPzCwsmA2F0ZHp8ys6WU9ONt/nVuGOExLine truncated

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

+77
View File
@@ -0,0 +1,77 @@
# MOSS-Image for ComfyUI
English | [简体中文](README_ZH.md)
MOSS-Image supports loading directly from a local Hugging Face / Diffusers model
directory. Its standard ComfyUI nodes output MODEL, CLIP and VAE, using native
sampling, SLG and memory management.
## Installation
Copy `comfyui/moss-image/` to `ComfyUI/custom_nodes/moss-image/` and restart
ComfyUI. The native plugin uses ComfyUI's dependencies and can be installed
independently of this repository.
Alternatively, create links from the repository root:
```bash
python comfyui/install.py --comfy-root /path/to/ComfyUI
```
For a separate local ComfyUI installation, use the [local launch scripts](#local-launch) below.
Existing user workflows are not overwritten. Environments, weights, generated
images and user settings stay local and are excluded from version control.
## Workflow
1. Download [moss-image.json](moss-image/example_workflows/moss-image.json) and drag it into ComfyUI.
2. Download [MOSS-Image-Base](https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base). In **MOSS-Image HF Loader**, set `model_path` to the downloaded local directory containing `transformer/`, `text_encoder/`, `tokenizer/`, and `vae/`.
3. Edit the positive and negative prompts, then click **Run** to generate an image.
The workflow is ready to run with **50 steps, CFG 3, Shift 5, and negative-branch
skipping at layer 22**, using Euler / sgm_uniform at 1024×1024.
See the [user guide](../USERGUIDE.md) for prompt and sampling recommendations.
## Local launch
```bash
bash comfyui/local/setup.sh
bash comfyui/local/run.sh
```
The setup script clones ComfyUI into the Git-ignored `local/ComfyUI/` directory
if it is missing, creates a separate environment, and installs its dependencies.
It installs the nodes and the MOSS-Image workflow without
overwriting an existing file of the same name. Set `MOSS_PYTHON` to choose the
interpreter and `UV_INDEX_URL` to choose the package index.
`COMFYUI_ROOT` selects an existing ComfyUI checkout. `COMFY_HOST` and
`COMFY_PORT` set the listening address; `CUDA_VISIBLE_DEVICES` selects the GPU.
Launch defaults enable FP32 VAE and Latent2RGB previews and disable image
metadata. The runtime's `local/env.sh` can configure launch options.
## Advanced settings
The [API JSON](moss-image/example_workflows/moss-image-api.json) provides the same
workflow for programmatic submission.
The loader reads local single-file or sharded safetensors weights; it does not
download models from a Hub repository ID. `weight_dtype` controls DiT precision,
`text_device` selects the text encoder's device, and the VAE uses FP32.
Text encoding is capped at 4096 tokens.
Clear Simple SLG's `single_layers` to disable negative-branch skipping. To use
standard SLG instead, replace Simple SLG with `SkipLayerGuidanceDiT`, choose
`single_layers`, and set scale 3, start 0.01, end 1, and rescaling 0. Keep
`double_layers` empty. The user guide does not specify standard SLG layer indices.
Keep ModelSamplingSD3 before SLG so scheduling and SLG thresholds share the same
shift. ComfyUI SLG intervals use sigma-based percentages. Its native scheduler
does not use the standalone pipeline's training-grid snapping, so matching seeds
and parameters do not guarantee identical images.
Separate component loaders remain available for custom workflows. LoRAs with
matching model keys can use the built-in LoRA loader. For SLG or changing block
patches, use eager execution: TorchCompileModel filters
transformer-option guards.
+68
View File
@@ -0,0 +1,68 @@
# MOSS-Image for ComfyUI
[English](README.md) | 简体中文
moss-image 支持直接读取本地 Hugging Face / Diffusers 模型目录,提供标准
MODEL、CLIP、VAE 输出,配合 ComfyUI 原生采样、SLG 及显存管理使用。
## 安装
将 `comfyui/moss-image/` 复制到 `ComfyUI/custom_nodes/moss-image/`,重启 ComfyUI。
插件使用 ComfyUI 提供的依赖,可独立安装。
也可以在仓库根目录建立链接:
```bash
python comfyui/install.py --comfy-root /path/to/ComfyUI
```
也可以使用下方的[本地运行脚本](#本地运行)安装独立的 ComfyUI。
已有用户工作流不会被覆盖。环境、权重、生成图片和用户配置不纳入版本控制。
## 工作流
1. 下载 [moss-image.json](moss-image/example_workflows/moss-image.json),拖入 ComfyUI。
2. 下载 [MOSS-Image-Base](https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base),在 **MOSS-Image HF Loader** 的 `model_path` 中填写本地模型目录。目录应包含 `transformer/`、`text_encoder/`、`tokenizer/` 和 `vae/`。
3. 修改正向和负向提示词,点击 **Run** 生成图片。
工作流已配置好 **50 步、CFG 3、Shift 5、负向跳过第 22 层**,
使用 Euler / sgm_uniform 采样,分辨率为 1024×1024。
提示词和采样建议见[用户指南](../USERGUIDE_ZH.md)。
## 本地运行
```bash
bash comfyui/local/setup.sh
bash comfyui/local/run.sh
```
安装脚本在目录不存在时将 ComfyUI 克隆到 Git 忽略的 `local/ComfyUI/`,
创建独立环境并安装依赖,然后安装节点和 MOSS-Image 工作流,不覆盖已有同名文件。
`MOSS_PYTHON` 指定解释器,`UV_INDEX_URL` 指定依赖源。
`COMFYUI_ROOT` 指定已有 ComfyUI,`COMFY_HOST`、`COMFY_PORT` 控制监听地址,
`CUDA_VISIBLE_DEVICES` 选择设备。默认启用 FP32 VAE、Latent2RGB 预览并关闭图片元数据写入。
运行目录的 `local/env.sh` 可配置启动选项。
## 高级设置
[API JSON](moss-image/example_workflows/moss-image-api.json) 是同一工作流的接口格式,
供程序提交使用。
加载器读取本地单文件或分片 safetensors,不会通过 Hub 仓库 ID 自动下载模型。
`weight_dtype` 控制 DiT 精度,`text_device` 控制文本编码设备,VAE 使用 FP32。
文本编码最长为 4096 tokens。
清空 Simple SLG 的 `single_layers` 可关闭负向跳层。如需改用标准 SLG,
将 Simple SLG 替换为 `SkipLayerGuidanceDiT`,选择 `single_layers`,
并设置 scale 3、start 0.01、end 1、rescaling 0,`double_layers` 留空。
用户指南尚未指定标准 SLG 的层号。
ModelSamplingSD3 保持在 SLG 前,让采样和 SLG 阈值使用同一套 Shift。
ComfyUI 的 SLG 区间采用 sigma 百分比语义。其原生 scheduler 不包含独立 pipeline
的训练网格吸附;即使 seed 和参数相同,也不保证生成相同的图片。
单独的组件加载节点仍可用于自定义工作流。模型键匹配的 LoRA 可使用内置 LoRA
加载器。TorchCompileModel 会过滤 transformer options 的编译 guard,
配合 SLG 或动态 block 补丁时请使用未编译执行。
+61
View File
@@ -0,0 +1,61 @@
import argparse
import json
import shutil
from pathlib import Path
from safetensors.torch import load_file, save_file
def load_shards(directory, index_name):
index = json.loads((directory / index_name).read_text())
state = {}
for filename in sorted(set(index["weight_map"].values())):
path = (directory / filename).resolve()
if not path.is_relative_to(directory.resolve()):
raise ValueError("Shard path escapes the component directory")
state.update(load_file(path))
if state.keys() != index["weight_map"].keys():
raise ValueError("Shard keys do not match the index")
return state
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("source", type=Path, help="Exported MOSSImagePipeline directory, not a distributed training checkpoint")
parser.add_argument("models", type=Path, help="Destination ComfyUI models directory")
parser.add_argument("--name", default="moss-image", help="Output filename prefix for this checkpoint")
args = parser.parse_args()
if not args.name or Path(args.name).name != args.name or args.name in (".", ".."):
parser.error("--name must be a filename prefix, not a path")
config = json.loads((args.source / "transformer/config.json").read_text())
if config.get("_class_name") not in ("MOSImageTransformer", "MOSSImageTransformer"):
raise ValueError(f"Unsupported MOSSImage class: {config.get('_class_name')!r}")
for key, expected in {"text_dim": 4096, "freq_dim": 256,
"latent_channels": 128, "rope_base": 10000.0}.items():
if config.get(key) != expected:
raise ValueError(f"Unsupported MOSSImage configuration: {key}={config.get(key)!r}")
outputs = [args.models / f"diffusion_models/{args.name}-dit.safetensors",
args.models / f"text_encoders/{args.name}-qwen35.safetensors",
args.models / f"vae/{args.name}-vae.safetensors"]
for path in outputs:
if path.exists():
raise FileExistsError(path)
for path in outputs:
path.parent.mkdir(parents=True, exist_ok=True)
for component, index_name, target in [
("transformer", "diffusion_pytorch_model.safetensors.index.json", outputs[0]),
("text_encoder", "model.safetensors.index.json", outputs[1]),
]:
state = load_shards(args.source / component, index_name)
# Keep the exported values and dtype; this is packaging, not quantization.
temporary = target.with_suffix(".partial")
save_file(state, temporary, metadata={"format": "pt", "model": "moss-image"})
temporary.rename(target)
del state
temporary = outputs[2].with_suffix(".partial")
shutil.copyfile(args.source / "vae/diffusion_pytorch_model.safetensors", temporary)
temporary.rename(outputs[2])
if __name__ == "__main__":
main()
+43
View File
@@ -0,0 +1,43 @@
import argparse
import logging
import os
import shutil
from pathlib import Path
ROOT = Path(__file__).resolve().parent
def link(root, name):
source = ROOT / name
target = root / "custom_nodes" / name
target.parent.mkdir(parents=True, exist_ok=True)
if target.exists() or target.is_symlink():
if target.resolve() != source.resolve():
raise FileExistsError(f"Another node installation exists: {target}")
return
target.symlink_to(os.path.relpath(source, target.parent), target_is_directory=True)
def install(root):
if not (root / "main.py").is_file():
raise FileNotFoundError(f"Not a ComfyUI checkout: {root}")
link(root, "moss-image")
workflows = root / "user/default/workflows"
workflows.mkdir(parents=True, exist_ok=True)
source = ROOT / "moss-image/example_workflows/moss-image.json"
target = workflows / source.name
if not target.exists():
shutil.copy2(source, target)
logging.info("Installed MOSS-Image custom nodes into %s", root)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--comfy-root", type=Path, required=True)
args = parser.parse_args()
logging.basicConfig(level=logging.INFO, format="%(message)s")
install(args.comfy_root.resolve())
if __name__ == "__main__":
main()
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -euo pipefail
moss_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
export COMFYUI_ROOT="${COMFYUI_ROOT:-$moss_root/local/ComfyUI}"
cd "$COMFYUI_ROOT"
COMFY_ARGS=()
if [[ -f local/env.sh ]]; then
source local/env.sh
fi
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0}"
export OMP_NUM_THREADS="${OMP_NUM_THREADS:-8}"
export HF_HUB_OFFLINE=1
export HF_HUB_DISABLE_TELEMETRY=1
exec .venv/bin/python "${COMFY_ENTRYPOINT:-main.py}" \
--listen "${COMFY_HOST:-127.0.0.1}" --port "${COMFY_PORT:-8189}" \
--disable-auto-launch --disable-metadata --fp32-vae \
--preview-method latent2rgb --disable-api-nodes "${COMFY_ARGS[@]}" "$@"
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail
moss_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
export COMFYUI_ROOT="${COMFYUI_ROOT:-$moss_root/local/ComfyUI}"
COMFY_VENV_ARGS=()
if [[ $# -ne 0 ]]; then
printf "Usage: bash comfyui/local/setup.sh\n" >&2
exit 2
fi
if [[ ! -e "$COMFYUI_ROOT" ]]; then
mkdir -p "$(dirname -- "$COMFYUI_ROOT")"
git clone https://github.com/Comfy-Org/ComfyUI.git "$COMFYUI_ROOT"
fi
if [[ ! -f "$COMFYUI_ROOT/main.py" ]]; then
printf "Not a ComfyUI checkout: %s\n" "$COMFYUI_ROOT" >&2
exit 1
fi
cd "$COMFYUI_ROOT"
mkdir -p local
if [[ -f local/env.sh ]]; then
source local/env.sh
fi
moss_python="${MOSS_PYTHON:-python3.12}"
uv venv --python "$moss_python" --allow-existing "${COMFY_VENV_ARGS[@]}" .venv
if [[ -n "${COMFY_SETUP:-}" ]]; then
bash "$COMFY_SETUP"
fi
uv pip install --python .venv/bin/python \
--link-mode copy -r requirements.txt
.venv/bin/python "$moss_root/comfyui/install.py" --comfy-root "$COMFYUI_ROOT"
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+11
View File
@@ -0,0 +1,11 @@
# MOSS-Image for ComfyUI
Native MOSS-Image loaders that output standard MODEL, CLIP and VAE objects.
Use ComfyUI's sampling, guidance and memory management nodes.
See the [installation and usage guide](https://github.com/OpenMOSS/MOSS-Image/blob/main/comfyui/README.md).
The example workflow is in `example_workflows/moss-image.json`. Model weights
are downloaded separately from [MOSS-Image-Base](https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base).
Set the HF Loader's `model_path` to the local directory containing
`transformer/`, `text_encoder/`, `tokenizer/` and `vae/`.
+3
View File
@@ -0,0 +1,3 @@
from .nodes import comfy_entrypoint
__all__ = ["comfy_entrypoint"]
@@ -0,0 +1,138 @@
{
"1": {
"inputs": {
"model_path": "/path/to/MOSS-Image-Base",
"weight_dtype": "default",
"text_device": "default"
},
"class_type": "MOSSImageHFLoader",
"_meta": {
"title": "MOSS-Image HF Loader"
}
},
"4": {
"inputs": {
"text": "A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:\n\"记得买牛奶和鸡蛋!\n牛奶两盒,鸡蛋一打。\n顺便带一袋面包。\"",
"clip": [
"1",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "moss-image Positive"
}
},
"5": {
"inputs": {
"text": "",
"clip": [
"1",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "moss-image Negative"
}
},
"6": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptyFlux2LatentImage",
"_meta": {
"title": "Empty Flux 2 Latent"
}
},
"13": {
"inputs": {
"double_layers": "",
"single_layers": "22",
"start_percent": 0,
"end_percent": 1,
"model": [
"15",
0
]
},
"class_type": "SkipLayerGuidanceDiTSimple",
"_meta": {
"title": "Uncond skip (empty = off)"
}
},
"15": {
"inputs": {
"shift": 5,
"model": [
"1",
0
]
},
"class_type": "ModelSamplingSD3",
"_meta": {
"title": "Official Flow sigma shift"
}
},
"16": {
"inputs": {
"seed": 42,
"steps": 50,
"cfg": 3,
"sampler_name": "euler",
"scheduler": "sgm_uniform",
"denoise": 1,
"model": [
"13",
0
],
"positive": [
"4",
0
],
"negative": [
"5",
0
],
"latent_image": [
"6",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"17": {
"inputs": {
"samples": [
"16",
0
],
"vae": [
"1",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"18": {
"inputs": {
"filename_prefix": "moss-image",
"images": [
"17",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
}
}
@@ -0,0 +1,726 @@
{
"id": "602a9b4a-8b28-4c64-a19e-fb35024af9c8",
"revision": 2,
"last_node_id": 19,
"last_link_id": 26,
"nodes": [
{
"id": 1,
"type": "MOSSImageHFLoader",
"pos": [
196.06797287994917,
841.2778976539247
],
"size": [
460,
150
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"localized_name": "model_path",
"name": "model_path",
"type": "STRING",
"widget": {
"name": "model_path"
},
"link": null
},
{
"localized_name": "weight_dtype",
"name": "weight_dtype",
"type": "COMBO",
"widget": {
"name": "weight_dtype"
},
"link": null
},
{
"name": "text_device",
"type": "COMBO",
"widget": {
"name": "text_device"
},
"link": null
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
13
],
"slot_index": 0
},
{
"name": "CLIP",
"type": "CLIP",
"links": [
1,
2
],
"slot_index": 1
},
{
"name": "VAE",
"type": "VAE",
"links": [
23
],
"slot_index": 2
}
],
"properties": {
"Node name for S&R": "MOSSImageHFLoader"
},
"widgets_values": [
"/path/to/MOSS-Image-Base",
"default",
"default"
],
"widgets_values_named": {
"model_path": "/path/to/MOSS-Image-Base",
"weight_dtype": "default",
"text_device": "default"
},
"title": "MOSS-Image HF Loader"
},
{
"id": 4,
"type": "CLIPTextEncode",
"pos": [
590.980723946239,
282.97746942714315
],
"size": [
430,
240
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"localized_name": "clip",
"name": "clip",
"type": "CLIP",
"link": 1
},
{
"localized_name": "text",
"name": "text",
"type": "STRING",
"widget": {
"name": "text"
},
"link": null
}
],
"outputs": [
{
"localized_name": "CONDITIONING",
"name": "CONDITIONING",
"type": "CONDITIONING",
"slot_index": 0,
"links": [
18
]
}
],
"title": "moss-image Positive",
"properties": {
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
"A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:\n\"记得买牛奶和鸡蛋!\n牛奶两盒,鸡蛋一打。\n顺便带一袋面包。\""
],
"widgets_values_named": {
"text": "A wide view of a refrigerator beside a kitchen counter with a fruit bowl. A small sticky note on the refrigerator door is handwritten in Chinese:\n\"记得买牛奶和鸡蛋!\n牛奶两盒,鸡蛋一打。\n顺便带一袋面包。\""
}
},
{
"id": 5,
"type": "CLIPTextEncode",
"pos": [
580.0934329802259,
578.2532529363273
],
"size": [
430,
200
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"localized_name": "clip",
"name": "clip",
"type": "CLIP",
"link": 2
},
{
"localized_name": "text",
"name": "text",
"type": "STRING",
"widget": {
"name": "text"
},
"link": null
}
],
"outputs": [
{
"localized_name": "CONDITIONING",
"name": "CONDITIONING",
"type": "CONDITIONING",
"slot_index": 0,
"links": [
19
]
}
],
"title": "moss-image Negative",
"properties": {
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
""
],
"widgets_values_named": {
"text": ""
}
},
{
"id": 6,
"type": "EmptyFlux2LatentImage",
"pos": [
1076.8709415117667,
40.14629806728207
],
"size": [
300,
180
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"localized_name": "width",
"name": "width",
"type": "INT",
"widget": {
"name": "width"
},
"link": null
},
{
"localized_name": "height",
"name": "height",
"type": "INT",
"widget": {
"name": "height"
},
"link": null
},
{
"localized_name": "batch_size",
"name": "batch_size",
"type": "INT",
"widget": {
"name": "batch_size"
},
"link": null
}
],
"outputs": [
{
"localized_name": "LATENT",
"name": "LATENT",
"type": "LATENT",
"slot_index": 0,
"links": [
20
]
}
],
"properties": {
"Node name for S&R": "EmptyFlux2LatentImage"
},
"widgets_values": [
1024,
1024,
1
],
"widgets_values_named": {
"width": 1024,
"height": 1024,
"batch_size": 1
}
},
{
"id": 13,
"type": "SkipLayerGuidanceDiTSimple",
"pos": [
1073.946162642385,
755.9111121061204
],
"size": [
340,
260
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"localized_name": "model",
"name": "model",
"type": "MODEL",
"link": 16
},
{
"localized_name": "double_layers",
"name": "double_layers",
"type": "STRING",
"widget": {
"name": "double_layers"
},
"link": null
},
{
"localized_name": "single_layers",
"name": "single_layers",
"type": "STRING",
"widget": {
"name": "single_layers"
},
"link": null
},
{
"localized_name": "start_percent",
"name": "start_percent",
"type": "FLOAT",
"widget": {
"name": "start_percent"
},
"link": null
},
{
"localized_name": "end_percent",
"name": "end_percent",
"type": "FLOAT",
"widget": {
"name": "end_percent"
},
"link": null
}
],
"outputs": [
{
"localized_name": "MODEL",
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": [
17
]
}
],
"title": "Uncond skip (empty = off)",
"properties": {
"Node name for S&R": "SkipLayerGuidanceDiTSimple"
},
"widgets_values": [
"",
"22",
0,
1
],
"widgets_values_named": {
"double_layers": "",
"single_layers": "22",
"start_percent": 0,
"end_percent": 1
}
},
{
"id": 15,
"type": "ModelSamplingSD3",
"pos": [
635.5243515640974,
833.754663701251
],
"size": [
310,
90
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"localized_name": "model",
"name": "model",
"type": "MODEL",
"link": 13
},
{
"localized_name": "shift",
"name": "shift",
"type": "FLOAT",
"widget": {
"name": "shift"
},
"link": null
}
],
"outputs": [
{
"localized_name": "MODEL",
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": [
16
]
}
],
"title": "Official Flow sigma shift",
"properties": {
"Node name for S&R": "ModelSamplingSD3"
},
"widgets_values": [
5
],
"widgets_values_named": {
"shift": 5
}
},
{
"id": 16,
"type": "KSampler",
"pos": [
1462.4773114331942,
579.4775120615249
],
"size": [
270,
474
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"localized_name": "model",
"name": "model",
"type": "MODEL",
"link": 17
},
{
"localized_name": "positive",
"name": "positive",
"type": "CONDITIONING",
"link": 18
},
{
"localized_name": "negative",
"name": "negative",
"type": "CONDITIONING",
"link": 19
},
{
"localized_name": "latent_image",
"name": "latent_image",
"type": "LATENT",
"link": 20
},
{
"localized_name": "seed",
"name": "seed",
"type": "INT",
"widget": {
"name": "seed"
},
"link": null
},
{
"localized_name": "steps",
"name": "steps",
"type": "INT",
"widget": {
"name": "steps"
},
"link": null
},
{
"localized_name": "cfg",
"name": "cfg",
"type": "FLOAT",
"widget": {
"name": "cfg"
},
"link": null
},
{
"localized_name": "sampler_name",
"name": "sampler_name",
"type": "COMBO",
"widget": {
"name": "sampler_name"
},
"link": null
},
{
"localized_name": "scheduler",
"name": "scheduler",
"type": "COMBO",
"widget": {
"name": "scheduler"
},
"link": null
},
{
"localized_name": "denoise",
"name": "denoise",
"type": "FLOAT",
"widget": {
"name": "denoise"
},
"link": null
}
],
"outputs": [
{
"localized_name": "LATENT",
"name": "LATENT",
"type": "LATENT",
"links": [
22
]
}
],
"properties": {
"Node name for S&R": "KSampler"
},
"widgets_values": [
42,
"fixed",
50,
3,
"euler",
"sgm_uniform",
1
],
"widgets_values_named": {
"seed": 42,
"steps": 50,
"cfg": 3,
"sampler_name": "euler",
"scheduler": "sgm_uniform",
"denoise": 1,
"control_after_generate": "fixed"
}
},
{
"id": 17,
"type": "VAEDecode",
"pos": [
1866.0458086602723,
593.1343463769351
],
"size": [
300,
180
],
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"localized_name": "samples",
"name": "samples",
"type": "LATENT",
"link": 22
},
{
"localized_name": "vae",
"name": "vae",
"type": "VAE",
"link": 23
}
],
"outputs": [
{
"localized_name": "IMAGE",
"name": "IMAGE",
"type": "IMAGE",
"slot_index": 0,
"links": [
21
]
}
],
"properties": {
"Node name for S&R": "VAEDecode"
},
"widgets_values_named": {}
},
{
"id": 18,
"type": "SaveImage",
"pos": [
2267.030358480412,
597.7554837229761
],
"size": [
480,
600
],
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"localized_name": "images",
"name": "images",
"type": "IMAGE",
"link": 21
},
{
"localized_name": "filename_prefix",
"name": "filename_prefix",
"type": "STRING",
"widget": {
"name": "filename_prefix"
},
"link": null
}
],
"outputs": [
{
"localized_name": "images",
"name": "images",
"type": "IMAGE",
"links": []
}
],
"properties": {
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"moss-image"
],
"widgets_values_named": {
"filename_prefix": "moss-image"
}
}
],
"links": [
[
1,
1,
1,
4,
0,
"CLIP"
],
[
2,
1,
1,
5,
0,
"CLIP"
],
[
13,
1,
0,
15,
0,
"MODEL"
],
[
16,
15,
0,
13,
0,
"MODEL"
],
[
17,
13,
0,
16,
0,
"MODEL"
],
[
18,
4,
0,
16,
1,
"CONDITIONING"
],
[
19,
5,
0,
16,
2,
"CONDITIONING"
],
[
20,
6,
0,
16,
3,
"LATENT"
],
[
21,
17,
0,
18,
0,
"IMAGE"
],
[
22,
16,
0,
17,
0,
"LATENT"
],
[
23,
1,
2,
17,
1,
"VAE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.8052550000000049,
"offset": [
-131.05197466058883,
146.1616185214425
]
}
},
"version": 0.4
}
+84
View File
@@ -0,0 +1,84 @@
"""Local Hugging Face component loading with native ComfyUI outputs."""
import json
from pathlib import Path
import torch
from comfy import sd, utils
from transformers import AutoTokenizer
from .loaders import DTYPES, load_clip_state, load_model_state
from .text_encoder import MOSSImageTokenizer
def component(root, name):
path = Path(root).expanduser().resolve() / name
config = json.loads((path / "config.json").read_text())
return path, config
def read_weights(path, stem):
index = path / f"{stem}.safetensors.index.json"
if not index.exists():
return utils.load_torch_file(str(path / f"{stem}.safetensors"), safe_load=True)
mapping = json.loads(index.read_text())["weight_map"]
state = {}
for filename in sorted(set(mapping.values())):
shard = (path / filename).resolve()
if not shard.is_relative_to(path.resolve()):
raise ValueError("Shard path escapes the component directory")
values = utils.load_torch_file(str(shard), safe_load=True)
expected = {key for key, file in mapping.items() if file == filename}
if values.keys() != expected:
raise ValueError(f"Shard contents do not match index: {filename}")
state.update(values)
return state
class HFTokenizer(MOSSImageTokenizer):
def __init__(self, embedding_directory=None, tokenizer_data={}):
super().__init__(embedding_directory, tokenizer_data)
self.qwen35_9b.tokenizer = AutoTokenizer.from_pretrained(
tokenizer_data["hf_path"], local_files_only=True,
)
def load_hf_model(root, weight_dtype, disable_dynamic=False):
path, config = component(root, "transformer")
if config.get("_class_name") not in ("MOSImageTransformer", "MOSSImageTransformer"):
raise ValueError("Expected a MOSS-Image transformer")
for key, value in {"text_dim": 4096, "freq_dim": 256,
"latent_channels": 128, "rope_base": 10000.0}.items():
if config.get(key) != value:
raise ValueError(f"Unsupported MOSS-Image {key}: {config.get(key)}")
state = read_weights(path, "diffusion_pytorch_model")
patcher = load_model_state(
state, DTYPES[weight_dtype], disable_dynamic,
fp8_optimizations=weight_dtype == "fp8_e4m3fn_fast",
)
patcher.cached_patcher_init = (load_hf_model, (root, weight_dtype))
return patcher
def load_hf_clip(root, device, disable_dynamic=False):
path, config = component(root, "text_encoder")
if config.get("model_type") != "qwen3_5":
raise ValueError("Expected a Qwen3.5 text encoder")
tokenizer = Path(root).expanduser().resolve() / "tokenizer"
state = read_weights(path, "model")
clip = load_clip_state(state, device, disable_dynamic, HFTokenizer, {"hf_path": str(tokenizer)})
clip.patcher.cached_patcher_init = (load_hf_clip_patcher, (root, device))
return clip
def load_hf_clip_patcher(root, device, disable_dynamic=False):
return load_hf_clip(root, device, disable_dynamic).patcher
def load_hf_vae(root):
path, config = component(root, "vae")
if config.get("_class_name") != "AutoencoderKLFlux2":
raise ValueError("Expected an AutoencoderKLFlux2 VAE")
vae = sd.VAE(sd=read_weights(path, "diffusion_pytorch_model"), dtype=torch.float32)
vae.throw_exception_if_invalid()
return vae
+192
View File
@@ -0,0 +1,192 @@
import torch
from comfy import (
conds,
latent_formats,
model_base,
model_detection,
model_management,
model_patcher,
sd,
storage,
utils,
)
from comfy.supported_models_base import BASE, ClipTarget
from comfy.text_encoders import hunyuan_video
from .model import MOSSImageTransformer
from .text_encoder import MOSSImageTokenizer, te
DTYPES = {
"default": None,
"bf16": torch.bfloat16,
"fp32": torch.float32,
"fp8_e4m3fn": torch.float8_e4m3fn,
"fp8_e4m3fn_fast": torch.float8_e4m3fn,
"fp8_e5m2": torch.float8_e5m2,
}
class MOSSImage(model_base.BaseModel):
def __init__(self, config, device):
super().__init__(config, model_base.ModelType.FLOW, device=device, unet_model=MOSSImageTransformer)
def extra_conds(self, **kwargs):
out = super().extra_conds(**kwargs)
for source, target in (("cross_attn", "c_crossattn"), ("attention_mask", "attention_mask")):
value = kwargs.get(source)
if value is not None:
out[target] = conds.CONDRegular(value)
return out
class MOSSImageConfig(BASE):
unet_extra_config = {}
sampling_settings = {"shift": 1.0, "multiplier": 1000}
latent_format = latent_formats.Flux2
supported_inference_dtypes = [torch.bfloat16, torch.float32]
memory_usage_factor = 4.0
vae_key_prefix = ["vae."]
text_encoder_key_prefix = ["text_encoders."]
def get_model(self, state_dict, prefix="", device=None):
return MOSSImage(self, device)
def clip_target(self, state_dict):
detect = hunyuan_video.llama_detect(state_dict, "text_encoders.qwen35_9b.transformer.")
return ClipTarget(MOSSImageTokenizer, te(**detect))
def model_config(state):
keys = (
"video_embedder.bias",
"text_embedder.proj.weight",
"text_embedder.blocks.0.qkv.weight",
"shared_block_modulation.weight",
"layers.0.q_norm.weight",
"layers.0.proj.ffn_up_gate.weight",
"final_linear_video.weight",
"video_head_modulation.weight",
"time_embedding.0.bias",
)
missing = [key for key in keys if key not in state]
if missing:
raise ValueError(f"Not a complete moss-image diffusion model; missing: {missing}")
dim = state["video_embedder.bias"].shape[0]
head = state["layers.0.q_norm.weight"].shape[0]
return MOSSImageConfig(
{
"dim": dim,
"num_heads": dim // head,
"num_layers": model_detection.count_blocks(state, "layers.{}."),
"ffn_dim": state["layers.0.proj.ffn_up_gate.weight"].shape[0] // 2,
"latent_channels": state["final_linear_video.weight"].shape[0],
"text_dim": 4096,
"freq_dim": 256,
"rope_base": 10000.0,
}
)
def load_model_state(
state, dtype, disable_dynamic, metadata=None, fp8_optimizations=False, model_options=None
):
options = {} if model_options is None else model_options
operations = options.get("custom_operations")
if operations is None:
state, metadata = utils.convert_old_quants(state, "", metadata=metadata)
prefix = model_detection.unet_prefix_from_state_dict(state)
stripped = utils.state_dict_prefix_replace(state, {prefix: ""}, filter_keys=True)
if stripped:
state = stripped
if operations is None:
state, metadata = utils.convert_old_quants(state, "", metadata=metadata)
config = model_config(state)
config.quant_config = utils.detect_layer_quantization(state, "")
if operations is not None:
config.custom_operations = operations
if fp8_optimizations or options.get("fp8_optimizations", False):
config.optimizations = {**config.optimizations, "fp8": True}
device = options.get("load_device", model_management.get_torch_device())
dtype = options.get("dtype", dtype)
weight_dtype = None if config.quant_config else utils.weight_dtype(state)
if dtype is None:
dtype = model_management.unet_dtype(
model_params=utils.calculate_parameters(state),
supported_dtypes=config.supported_inference_dtypes,
weight_dtype=weight_dtype,
)
cast = model_management.unet_manual_cast(
None if config.quant_config else dtype, device, config.supported_inference_dtypes
)
config.set_inference_dtype(dtype, cast, device=device)
model = config.get_model(state)
patcher_type = model_patcher.ModelPatcher if disable_dynamic else model_patcher.CoreModelPatcher
offload = options.get("offload_device", model_management.unet_offload_device())
patcher = patcher_type(
model, load_device=device, offload_device=offload, fast_disk=storage.state_dict_fast_disk(state)
)
if not model_management.is_device_cpu(offload):
model.to(offload)
model.load_model_weights(state, "", assign=patcher.is_dynamic())
return patcher
def load_model(path, weight_dtype, disable_dynamic=False):
state, metadata = utils.load_torch_file(path, return_metadata=True)
patcher = load_model_state(
state,
DTYPES[weight_dtype],
disable_dynamic,
metadata=metadata,
fp8_optimizations=weight_dtype == "fp8_e4m3fn_fast",
)
patcher.cached_patcher_init = (load_model, (path, weight_dtype))
return patcher
def clip_state(state):
state = utils.state_dict_prefix_replace(
state,
{
"language_model.": "model.language_model.",
"visual.": "model.visual.",
},
)
if sd.detect_te_model(state) != sd.TEModel.QWEN35_9B:
raise ValueError("moss-image requires a Qwen3.5-9B text encoder")
return utils.state_dict_prefix_replace(
state,
{
"model.language_model.": "model.",
"model.visual.": "visual.",
},
)
def load_clip(path, device, disable_dynamic=False):
state, metadata = utils.load_torch_file(path, safe_load=True, return_metadata=True)
state, metadata = utils.convert_old_quants(state, model_prefix="", metadata=metadata)
clip = load_clip_state(state, device, disable_dynamic, MOSSImageTokenizer, {})
clip.patcher.cached_patcher_init = (load_clip_patcher, (path, device))
return clip
def load_clip_state(state, device, disable_dynamic, tokenizer, tokenizer_data):
state = clip_state(state)
target = ClipTarget(tokenizer, te(**sd.llama_detect([state])))
options = {}
if device == "cpu":
options = {"load_device": torch.device("cpu"), "offload_device": torch.device("cpu")}
clip = sd.CLIP(
target,
tokenizer_data=tokenizer_data,
parameters=utils.calculate_parameters(state),
state_dict=[state],
model_options=options,
disable_dynamic=disable_dynamic,
)
return clip
def load_clip_patcher(path, device, disable_dynamic=False):
return load_clip(path, device, disable_dynamic).patcher
+247
View File
@@ -0,0 +1,247 @@
"""MOSSImage dense text-to-image transformer, with native ComfyUI operations."""
import torch
from comfy.ldm.modules.attention import optimized_attention
from torch import nn
def _situ(hidden, gate):
return (4.0 * torch.tanh(gate / 4.0) * torch.sigmoid(gate)) * (25.0 * torch.tanh(hidden / 25.0))
def _rotate(x, rope):
sin, cos = rope.chunk(2, -1)
sin = torch.cat((sin, sin), -1).unsqueeze(-2)
cos = torch.cat((cos, cos), -1).unsqueeze(-2)
a, b = x.chunk(2, -1)
return x * cos + torch.cat((-b, a), -1) * sin
def _attention(q, k, v, rope, heads):
shape = (*q.shape[:2], heads, q.shape[-1] // heads)
q = _rotate(q.reshape(shape), rope).transpose(1, 2)
k = _rotate(k.reshape(shape), rope).transpose(1, 2)
v = v.reshape(shape).transpose(1, 2)
return optimized_attention(q, k, v, heads, skip_reshape=True)
class _TextBlock(nn.Module):
def __init__(self, dim, ffn_dim, heads, device, dtype, operations):
super().__init__()
self.heads = heads
self.norm1, self.norm2 = (
operations.RMSNorm(dim, eps=1e-6, device=device, dtype=dtype),
operations.RMSNorm(dim, eps=1e-6, device=device, dtype=dtype),
)
self.q_norm, self.k_norm = (
operations.RMSNorm(dim // heads, eps=1e-6, device=device, dtype=dtype),
operations.RMSNorm(dim // heads, eps=1e-6, device=device, dtype=dtype),
)
self.qkv = operations.Linear(dim, 3 * dim, device=device, dtype=dtype)
self.proj = operations.Linear(dim, dim, device=device, dtype=dtype)
self.ffn_gate, self.ffn_up = (
operations.Linear(dim, ffn_dim, device=device, dtype=dtype),
operations.Linear(dim, ffn_dim, device=device, dtype=dtype),
)
self.ffn_down = operations.Linear(ffn_dim, dim, device=device, dtype=dtype)
def forward(self, x, rope):
q, k, v = self.qkv(self.norm1(x)).chunk(3, -1)
q = self.q_norm(q.unflatten(-1, (self.heads, -1))).flatten(2)
k = self.k_norm(k.unflatten(-1, (self.heads, -1))).flatten(2)
x = x + self.proj(_attention(q, k, v, rope, self.heads))
y = self.norm2(x)
return x + self.ffn_down(_situ(self.ffn_up(y), self.ffn_gate(y)))
class _TextProjection(nn.Module):
def __init__(self, text_dim, dim, ffn_dim, heads, device, dtype, operations):
super().__init__()
self.proj = operations.Linear(text_dim, dim, device=device, dtype=dtype)
self.blocks = nn.ModuleList(
[_TextBlock(dim, ffn_dim, heads, device, dtype, operations) for _ in range(2)]
)
def forward(self, x, rope):
x = self.proj(x.to(self.proj.weight.dtype))
for block in self.blocks:
x = block(x, rope)
return x
class _Block(nn.Module):
def __init__(self, dim, ffn_dim, heads, device, dtype, operations):
super().__init__()
self.heads = heads
self.norm1, self.norm2 = (
operations.RMSNorm(dim, eps=1e-6, device=device, dtype=dtype),
operations.RMSNorm(dim, eps=1e-6, device=device, dtype=dtype),
)
self.q_norm, self.k_norm = (
operations.RMSNorm(dim // heads, eps=1e-6, device=device, dtype=dtype),
operations.RMSNorm(dim // heads, eps=1e-6, device=device, dtype=dtype),
)
self.proj = nn.ModuleDict(
{
name: operations.Linear(dim, dim, bias=False, device=device, dtype=dtype)
for name in ("q", "k", "v", "o")
}
)
self.proj["ffn_up_gate"] = operations.Linear(dim, 2 * ffn_dim, bias=False, device=device, dtype=dtype)
self.proj["ffn_down"] = operations.Linear(ffn_dim, dim, bias=False, device=device, dtype=dtype)
def forward(self, x, rope, modulation):
shift_a, scale_a, gate_a, shift_f, scale_f, gate_f = modulation.unbind(1)
y = self.norm1(x) * (1 + scale_a[:, None]) + shift_a[:, None]
dtype = self.proj["q"].weight.dtype
y = y.to(dtype)
q = self.q_norm(self.proj["q"](y).unflatten(-1, (self.heads, -1))).flatten(2)
k = self.k_norm(self.proj["k"](y).unflatten(-1, (self.heads, -1))).flatten(2)
x = x + self.proj["o"](_attention(q, k, self.proj["v"](y), rope, self.heads)) * gate_a[:, None]
y = self.norm2(x) * (1 + scale_f[:, None]) + shift_f[:, None]
hidden, gate = self.proj["ffn_up_gate"](y.to(dtype)).chunk(2, -1)
return x + self.proj["ffn_down"](_situ(hidden, gate)) * gate_f[:, None]
class _RoPE(nn.Module):
def __init__(self, head_dim, base):
super().__init__()
self.num_bands = head_dim // 8
self.base = base
self.register_buffer("bands", torch.empty(self.num_bands))
def _default_bands(self, device):
# Match training's CPU fp32 construction, including under meta init.
exponent = torch.arange(self.num_bands, device="cpu", dtype=torch.float32) / self.num_bands
return (1 / (self.base**exponent)).to(device)
def forward(self, height, width, text_length, device):
bands = self._default_bands(device)
# Coordinates: (r, f, h, w); sequence order is image followed by text.
h, w = torch.meshgrid(
torch.arange(height, device=device), torch.arange(width, device=device), indexing="ij"
)
image = (
torch.stack((torch.zeros_like(h), torch.full_like(h, text_length), h, w), -1)
.flatten(0, 1)
.float()
)
image[:, 2] -= (height - 1) / 2
image[:, 3] -= (width - 1) / 2
text = torch.zeros(text_length, 4, device=device, dtype=torch.float32)
text[:, 1] = torch.arange(text_length, device=device)
phase = torch.cat((image, text), 0).unsqueeze(-1) * bands
return torch.cat((phase.sin(), phase.cos()), -2).flatten(-2).unsqueeze(0)
class MOSSImageTransformer(nn.Module):
"""MOSSImage DiT with training-compatible keys and ComfyUI attention.
Each sample is evaluated at its true text length, including text refinement;
padded tokens cannot influence either text or joint attention.
"""
def __init__(
self,
dim=3072,
ffn_dim=8192,
num_heads=24,
num_layers=42,
text_dim=4096,
freq_dim=256,
latent_channels=128,
rope_base=10000.0,
device=None,
dtype=None,
operations=None,
**kwargs,
):
super().__init__()
if dim % num_heads or (dim // num_heads) % 8 or freq_dim % 2:
raise ValueError("Require dim divisible by heads, head_dim divisible by 8, and even freq_dim.")
self.dtype = dtype
self.latent_channels = latent_channels
self.freq_dim = freq_dim
self.video_embedder = operations.Linear(latent_channels, dim, device=device, dtype=dtype)
self.text_embedder = _TextProjection(text_dim, dim, ffn_dim, num_heads, device, dtype, operations)
self.rope = _RoPE(dim // num_heads, rope_base)
self.time_embedding = nn.Sequential(
operations.Linear(freq_dim, dim, device=device, dtype=dtype),
nn.SiLU(),
operations.Linear(dim, dim, device=device, dtype=dtype),
)
self.shared_block_modulation = operations.Linear(dim, 6 * dim, device=device, dtype=dtype)
self.layers = nn.ModuleList(
[_Block(dim, ffn_dim, num_heads, device, dtype, operations) for _ in range(num_layers)]
)
self.final_norm_video = operations.RMSNorm(dim, eps=1e-6, device=device, dtype=dtype)
self.final_linear_video = operations.Linear(
dim, latent_channels, bias=False, device=device, dtype=dtype
)
self.video_head_modulation = operations.Linear(dim, 2 * dim, device=device, dtype=dtype)
def forward(self, x, timestep, context, attention_mask=None, transformer_options={}, **kwargs):
transformer_options = transformer_options.copy()
blocks_replace = transformer_options.get("patches_replace", {}).get("dit", {})
hidden_states, encoder_hidden_states = x, context
encoder_attention_mask = attention_mask
if hidden_states.ndim != 4 or hidden_states.shape[1] != self.latent_channels:
raise ValueError("hidden_states must be [B, latent_channels, H, W].")
batch, _, height, width = hidden_states.shape
if encoder_hidden_states.ndim != 3 or encoder_hidden_states.shape[0] != batch:
raise ValueError("encoder_hidden_states must be [B, S, text_dim].")
mask = encoder_attention_mask
if mask is None:
mask = torch.ones(encoder_hidden_states.shape[:2], dtype=torch.bool, device=hidden_states.device)
if mask.shape != encoder_hidden_states.shape[:2] or not torch.all((mask == 0) | (mask == 1)):
raise ValueError("encoder_attention_mask must be a binary [B, S] mask.")
times = torch.as_tensor(timestep, device=hidden_states.device, dtype=torch.float32).reshape(-1)
times = times.expand(batch)
# Training computes the sinusoid in float64 and feeds float32 into its MLP.
half = self.freq_dim // 2
freq = 10000 ** (-torch.arange(half, device=times.device, dtype=torch.float64) / half)
phase = times.double()[:, None] * freq
embedding = torch.cat((phase.cos(), phase.sin()), -1).float()
time = self.time_embedding(embedding.to(self.time_embedding[0].weight.dtype)).float()
mod = self.shared_block_modulation(time.to(self.shared_block_modulation.weight.dtype)).view(
batch, 6, -1
)
head = self.video_head_modulation(time.to(self.video_head_modulation.weight.dtype)).view(batch, 2, -1)
outputs = []
for index in range(batch):
context = encoder_hidden_states[index : index + 1, mask[index].bool()]
if context.shape[1] == 0:
raise ValueError("Each sample needs at least one valid text token.")
video = hidden_states[index : index + 1].flatten(2).transpose(1, 2)
video = self.video_embedder(video.to(self.video_embedder.weight.dtype).contiguous())
# Match the reference activation dtype under fp32 weights + autocast.
rope = self.rope(height, width, context.shape[1], hidden_states.device).to(video.dtype)
text = self.text_embedder(context, rope[:, height * width :])
x = torch.cat((video, text), 1)
transformer_options["total_blocks"] = len(self.layers)
transformer_options["block_type"] = "single"
for layer_index, layer in enumerate(self.layers):
transformer_options["block_index"] = layer_index
if ("single_block", layer_index) in blocks_replace:
def block_wrap(args):
return {"img": layer(args["img"], args["pe"], args["vec"])}
out = blocks_replace[("single_block", layer_index)](
{
"img": x,
"pe": rope,
"vec": mod[index : index + 1],
"transformer_options": transformer_options,
},
{"original_block": block_wrap},
)
x = out["img"]
else:
x = layer(x, rope, mod[index : index + 1])
x = self.final_norm_video(x[:, : height * width].to(self.final_norm_video.weight.dtype))
x = x * (1 + head[index : index + 1, 1, None]) + head[index : index + 1, 0, None]
x = self.final_linear_video(x.to(self.final_linear_video.weight.dtype))
outputs.append(x.transpose(1, 2).reshape(1, -1, height, width))
sample = torch.cat(outputs)
return sample
+130
View File
@@ -0,0 +1,130 @@
import folder_paths
from comfy_api.latest import ComfyExtension, io
from .hf import load_hf_clip, load_hf_model, load_hf_vae
from .loaders import DTYPES, load_clip, load_model
class MOSSImageUNETLoader(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MOSSImageUNETLoader",
display_name="MOSS-Image Load Diffusion Model",
category="MOSS-Image",
inputs=[
io.Combo.Input("unet_name", options=folder_paths.get_filename_list("diffusion_models")),
io.Combo.Input("weight_dtype", options=list(DTYPES), default="default"),
],
outputs=[io.Model.Output()],
)
@classmethod
def execute(cls, unet_name, weight_dtype):
path = folder_paths.get_full_path_or_raise("diffusion_models", unet_name)
return io.NodeOutput(load_model(path, weight_dtype))
class MOSSImageCLIPLoader(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MOSSImageCLIPLoader",
display_name="MOSS-Image Load Qwen3.5",
category="MOSS-Image",
inputs=[
io.Combo.Input("clip_name", options=folder_paths.get_filename_list("text_encoders")),
io.Combo.Input("device", options=["default", "cpu"], default="default", advanced=True),
],
outputs=[io.Clip.Output()],
)
@classmethod
def execute(cls, clip_name, device):
path = folder_paths.get_full_path_or_raise("text_encoders", clip_name)
return io.NodeOutput(load_clip(path, device))
class MOSSImageHFDiTLoader(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MOSSImageHFDiTLoader", display_name="MOSS-Image HF DiT",
category="MOSS-Image/HF",
inputs=[io.String.Input("model_path"),
io.Combo.Input("weight_dtype", options=list(DTYPES), default="default")],
outputs=[io.Model.Output()],
)
@classmethod
def execute(cls, model_path, weight_dtype):
return io.NodeOutput(load_hf_model(model_path, weight_dtype))
class MOSSImageHFTextEncoderLoader(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MOSSImageHFTextEncoderLoader", display_name="MOSS-Image HF Text Encoder",
category="MOSS-Image/HF",
inputs=[io.String.Input("model_path"),
io.Combo.Input("device", options=["default", "cpu"], default="default")],
outputs=[io.Clip.Output()],
)
@classmethod
def execute(cls, model_path, device):
return io.NodeOutput(load_hf_clip(model_path, device))
class MOSSImageHFVAELoader(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MOSSImageHFVAELoader", display_name="MOSS-Image HF VAE",
category="MOSS-Image/HF",
inputs=[io.String.Input("model_path")],
outputs=[io.Vae.Output()],
)
@classmethod
def execute(cls, model_path):
return io.NodeOutput(load_hf_vae(model_path))
class MOSSImageHFLoader(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MOSSImageHFLoader", display_name="MOSS-Image HF Loader",
category="MOSS-Image/HF",
inputs=[
io.String.Input("model_path"),
io.Combo.Input("weight_dtype", options=list(DTYPES), default="default"),
io.Combo.Input("text_device", options=["default", "cpu"], default="default", advanced=True),
],
outputs=[io.Model.Output(), io.Clip.Output(), io.Vae.Output()],
)
@classmethod
def execute(cls, model_path, weight_dtype, text_device):
model = load_hf_model(model_path, weight_dtype)
clip = load_hf_clip(model_path, text_device)
vae = load_hf_vae(model_path)
return io.NodeOutput(model, clip, vae)
class MOSSImageExtension(ComfyExtension):
async def get_node_list(self):
return [
MOSSImageUNETLoader,
MOSSImageCLIPLoader,
MOSSImageHFLoader,
MOSSImageHFDiTLoader,
MOSSImageHFTextEncoderLoader,
MOSSImageHFVAELoader,
]
async def comfy_entrypoint():
return MOSSImageExtension()
+15
View File
@@ -0,0 +1,15 @@
[project]
name = "moss-image"
version = "0.1.0"
description = "Native MOSS-Image model loaders for ComfyUI"
license = { file = "LICENSE" }
requires-python = ">=3.10"
dependencies = []
[project.urls]
Repository = "https://github.com/OpenMOSS/MOSS-Image"
Documentation = "https://github.com/OpenMOSS/MOSS-Image/blob/main/comfyui/README.md"
[tool.comfy]
PublisherId = "mosi"
DisplayName = "MOSS-Image"
+65
View File
@@ -0,0 +1,65 @@
from comfy import sd1_clip
from comfy.text_encoders import qwen35
class MOSSImageTokenizer(sd1_clip.SD1Tokenizer):
def __init__(self, embedding_directory=None, tokenizer_data={}):
def tokenizer(*args, **kwargs):
return qwen35.Qwen35Tokenizer(*args, **kwargs, embedding_size=4096, embedding_key="qwen35_9b")
super().__init__(
embedding_directory=embedding_directory,
tokenizer_data=tokenizer_data,
name="qwen35_9b",
tokenizer=tokenizer,
)
def tokenize_with_weights(self, text, return_word_ids=False, **kwargs):
text = f"<|im_start|>user\n{text}<|im_end|>\n<|im_start|>assistant\n<think>\n"
tokens = super().tokenize_with_weights(
text, return_word_ids=return_word_ids, disable_weights=True, **kwargs
)
tokens["qwen35_9b"] = [tokens["qwen35_9b"][0][:4096]]
return tokens
class Qwen35MOSSImage(qwen35.Qwen35):
model_type = "qwen35_9b"
class MOSSImageClipModel(sd1_clip.SDClipModel):
def __init__(self, device="cpu", dtype=None, model_options={}):
super().__init__(
device=device,
dtype=dtype,
layer="last",
textmodel_json_config={"lm_head": False},
model_class=Qwen35MOSSImage,
special_tokens={"pad": 248044},
enable_attention_masks=True,
return_attention_masks=True,
model_options=model_options,
)
class MOSSImageTEModel(sd1_clip.SD1ClipModel):
def __init__(self, device="cpu", dtype=None, model_options={}):
super().__init__(
device=device,
dtype=dtype,
name="qwen35_9b",
clip_model=MOSSImageClipModel,
model_options=model_options,
)
def te(dtype_llama=None, llama_quantization_metadata=None):
class MOSSImageTEModel_(MOSSImageTEModel):
def __init__(self, device="cpu", dtype=None, model_options={}):
if dtype_llama is not None:
dtype = dtype_llama
if llama_quantization_metadata is not None:
model_options = {**model_options, "quantization_metadata": llama_quantization_metadata}
super().__init__(device=device, dtype=dtype, model_options=model_options)
return MOSSImageTEModel_
+866
View File
@@ -0,0 +1,866 @@
"""MOSS-Image Gradio interface."""
import argparse
import gc
import hashlib
import html
import importlib.metadata
import inspect
import json
import logging
import math
import secrets
import threading
import time
from dataclasses import asdict, dataclass, replace
from functools import partial
from importlib.resources import files
from pathlib import Path
from secrets import randbits
from uuid import uuid4
import torch
from gradio_presets import (
PIXELS,
fit_size,
pixel_label,
ratio_value,
size_selection,
)
from inference_runtime import (
DEFAULT_MODEL,
configure_pipeline,
cuda_budget_gib,
generate_with_progress,
model_source,
set_scheduler,
)
from inference_runtime import (
load_pipeline as load_hf_pipeline,
)
logger = logging.getLogger(__name__)
COMPONENTS = ("transformer", "text_encoder", "tokenizer", "vae", "scheduler")
PROFILES = ("auto", "16gb", "24gb", "48gb")
def is_model_bundle(path):
try:
if not (path / "pipeline_moss_image.py").is_file():
return False
index = json.loads((path / "model_index.json").read_text())
if not all(name in index and (path / name).is_dir() for name in COMPONENTS):
return False
for name in ("transformer", "text_encoder", "vae"):
component = path / name
if not (component / "config.json").is_file():
return False
indices = list(component.glob("*.safetensors.index.json"))
if indices:
for file in indices:
shards = json.loads(file.read_text())["weight_map"].values()
if not shards or not all((component / shard).is_file() for shard in shards):
return False
elif not any(component.glob("*.safetensors")):
return False
tokenizer = path / "tokenizer"
return (
(path / "scheduler" / "scheduler_config.json").is_file()
and (tokenizer / "tokenizer_config.json").is_file()
and (
(tokenizer / "tokenizer.json").is_file()
or ((tokenizer / "vocab.json").is_file() and (tokenizer / "merges.txt").is_file())
)
)
except (OSError, ValueError, KeyError, TypeError, AttributeError):
return False
def discover_models(root):
root = Path(root).expanduser().resolve()
if not root.is_dir():
return []
candidates = [root] if is_model_bundle(root) else sorted(p for p in root.iterdir() if p.is_dir())
return sorted({str(p.resolve()) for p in candidates if is_model_bundle(p)})
def profile_defaults(profile, vram_gb=None):
if profile == "auto":
if vram_gb is None:
vram_gb = cuda_budget_gib() if torch.cuda.is_available() else 24
profile = "16gb" if vram_gb < 20 else "24gb" if vram_gb < 40 else "48gb"
return {"16gb": ("model", 1024, 1024), "24gb": ("model", 1024, 1024), "48gb": ("none", 1024, 1024)}[
profile
]
@dataclass(frozen=True)
class GenerationConfig:
prompt: str = ""
negative_prompt: str = ""
height: int = 1024
width: int = 1024
steps: int = 50
cfg: float = 3.0
shift: float = 5.0
seed: int = 42
num_images: int = 1
max_sequence_length: int = 4096
uncond_skip_layers: str = "22"
slg_layers: str = ""
slg_scale: float = 0.0
slg_start: float = 0.0
slg_stop: float = 1.0
offload: str = "model"
compile_transformer: bool = False
def layers(self, name):
value = getattr(self, name)
if not value.strip():
return ()
try:
layers = tuple(int(item.strip()) for item in value.split(","))
except ValueError as exc:
raise ValueError("SLG layers must be comma-separated integer indices, e.g. 22.") from exc
if any(layer < 0 for layer in layers) or len(set(layers)) != len(layers):
raise ValueError("SLG indices must be nonnegative and unique.")
return layers
def validate(self):
if not isinstance(self.prompt, str) or not self.prompt.strip():
raise ValueError("Enter a prompt.")
for name in ("height", "width", "steps", "seed", "num_images", "max_sequence_length"):
value = getattr(self, name)
if not isinstance(value, int) or isinstance(value, bool):
raise ValueError(f"{name} must be an integer.")
if self.height <= 0 or self.width <= 0 or self.height % 16 or self.width % 16:
raise ValueError("Height and width must be positive multiples of 16.")
if self.steps < 1 or self.num_images < 1:
raise ValueError("Steps and image count must be positive.")
if not math.isfinite(self.cfg) or self.cfg < 0 or not math.isfinite(self.shift) or self.shift <= 0:
raise ValueError("CFG must be finite and nonnegative; shift must be finite and positive.")
if not -1 <= self.seed < 2**53:
raise ValueError("Seed must be -1 (random) or an integer from 0 to 2⁵³−1 (browser-safe range).")
if not 1 <= self.max_sequence_length <= 4096:
raise ValueError("Maximum text length must be between 1 and 4096.")
if self.offload not in ("none", "model", "sequential"):
raise ValueError("Unknown offload mode.")
if not isinstance(self.compile_transformer, bool):
raise ValueError("Compile transformer must be true or false.")
if self.offload == "sequential" and self.compile_transformer:
raise ValueError("Compile transformer is incompatible with sequential offload.")
if not math.isfinite(self.slg_scale) or self.slg_scale < 0:
raise ValueError("SLG scale must be finite and nonnegative.")
if not 0 <= self.slg_start <= self.slg_stop <= 1:
raise ValueError("Require 0 <= SLG start <= SLG stop <= 1.")
self.layers("uncond_skip_layers")
self.layers("slg_layers")
def pipeline_kwargs(self):
return dict(
prompt=self.prompt,
negative_prompt=self.negative_prompt,
height=self.height,
width=self.width,
num_inference_steps=self.steps,
guidance_scale=self.cfg,
num_images_per_prompt=self.num_images,
max_sequence_length=self.max_sequence_length,
uncond_skip_layers=self.layers("uncond_skip_layers"),
slg_layers=self.layers("slg_layers"),
slg_scale=self.slg_scale,
slg_start=self.slg_start,
slg_stop=self.slg_stop,
)
def read_prompt_defaults(path):
headers = {"[prompt_prefix]": "prompt_prefix", "[negative_prompt]": "negative_prompt"}
sections = {}
current = None
for line in Path(path).read_text(encoding="utf-8").splitlines():
header = line.strip()
if header in headers:
current = headers[header]
if current in sections:
raise ValueError(f"Duplicate section {header} in {path}.")
sections[current] = []
continue
if current is None:
if header and not header.startswith("#"):
raise ValueError(f"Expected [prompt_prefix] or [negative_prompt] in {path}.")
continue
sections[current].append(line)
if sections.keys() != set(headers.values()):
raise ValueError(f"Both [prompt_prefix] and [negative_prompt] are required in {path}.")
return {name: "\n".join(lines).strip() for name, lines in sections.items()}
def parse_parameters(parameters, version):
if version not in (1, 2):
raise ValueError("Unsupported generation metadata version.")
parameters = dict(parameters)
if version == 1:
# Version 1 called negative-branch skipping "slg_layers".
layers = parameters.pop("slg_layers", "")
parameters["uncond_skip_layers"] = layers if parameters.pop("slg", True) else ""
if parameters.get("seed") is None:
parameters["seed"] = -1
parameters.setdefault("compile_transformer", False)
if parameters.get("offload") == "staged":
parameters["offload"] = "model"
config = GenerationConfig(**parameters)
config.validate()
return config
def load_pipeline(model, offload, compile_transformer=False, local_files_only=False):
if not torch.cuda.is_available():
raise ValueError("A CUDA GPU is required for generation. The interface can be previewed without one.")
pipe = load_hf_pipeline(model, local_files_only=local_files_only)
return configure_pipeline(pipe, offload=offload, compile_transformer=compile_transformer)
class ModelRunner:
def __init__(self, output_dir, local_files_only):
self.output_dir = Path(output_dir).expanduser().resolve()
self.local_files_only = local_files_only
self.pipe = None
self.key = None
self.lock = threading.RLock()
def unload(self):
with self.lock:
if self.pipe is not None:
self.pipe.remove_all_hooks()
self.pipe = None
self.key = None
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
return "Model released. It will load again on the next generation."
def generate(self, model, config, progress=None):
config.validate()
model = model_source(model)
if Path(model).is_dir() and not is_model_bundle(Path(model)):
raise ValueError("Choose a complete local model bundle with all five components.")
with self.lock:
config = replace(config, seed=secrets.randbelow(2**32)) if config.seed == -1 else config
start = time.monotonic()
total_steps = config.steps
def report(value, **kwargs):
if progress is not None:
progress(value, **kwargs)
def report_stage(stage):
nonlocal total_steps
if stage == "denoise":
timesteps = getattr(getattr(self.pipe, "scheduler", None), "timesteps", None)
if timesteps is not None and len(timesteps):
total_steps = len(timesteps)
descriptions = {
"encode": "Encoding prompt",
"denoise": f"Sampling · step 0/{total_steps}",
"decode": "Decoding image",
}
report((0, total_steps) if stage == "denoise" else 0, desc=descriptions[stage], unit="steps")
def report_step(pipe, step_index, timestep, callback_kwargs):
completed = step_index + 1
report(
(completed, total_steps), desc=f"Sampling · step {completed}/{total_steps}", unit="steps"
)
return callback_kwargs
try:
key = (str(model), config.offload, config.compile_transformer)
if key != self.key:
report(0, desc="Loading model")
self.unload()
self.pipe = load_pipeline(
model, config.offload, config.compile_transformer, self.local_files_only
)
self.key = key
depth = self.pipe.transformer.config.num_layers
layers = config.layers("uncond_skip_layers") + config.layers("slg_layers")
if any(layer >= depth for layer in layers):
raise ValueError(f"SLG layer index must be below {depth}.")
set_scheduler(self.pipe, config.shift)
images = generate_with_progress(
self.pipe, report_stage, report_step,
**config.pipeline_kwargs(),
generator=torch.Generator("cpu").manual_seed(config.seed),
).images
except torch.cuda.OutOfMemoryError as exc:
self.unload()
raise ValueError(
"GPU memory exhausted. Try fewer/smaller images or a lower-memory offload mode."
) from exc
report(0, desc="Saving images and parameters")
folder = self.output_dir / uuid4().hex
folder.mkdir(parents=True, exist_ok=True)
paths = []
for i, image in enumerate(images):
path = folder / f"{i + 1:02d}.png"
image.save(path)
paths.append(str(path))
root = Path(model)
configs = []
if root.is_dir():
configs = (
[root / "model_index.json", root / "scheduler" / "scheduler_config.json"]
+ [root / c / "config.json" for c in ("transformer", "text_encoder", "vae")]
+ sorted(
p for p in (root / "tokenizer").iterdir() if p.suffix in (".json", ".jinja", ".txt")
)
)
record = {
"schema_version": 2,
"model": root.name if root.is_dir() else model,
"pipeline_class": type(self.pipe).__name__,
"pipeline_module": type(self.pipe).__module__,
"parameters": asdict(config),
"sampler": "Euler",
"weight_dtype": "bfloat16",
"vae_dtype": "float32",
"pipeline_sha256": hashlib.sha256(
Path(inspect.getfile(type(self.pipe))).read_bytes()
).hexdigest(),
"model_config_sha256": {
str(p.relative_to(root)): hashlib.sha256(p.read_bytes()).hexdigest()
for p in configs
if p.is_file()
},
"versions": {
name: importlib.metadata.version(name)
for name in ("torch", "diffusers", "transformers", "accelerate")
},
"gpu": torch.cuda.get_device_name(0) if torch.cuda.is_available() else None,
"elapsed_seconds": round(time.monotonic() - start, 3),
"images": [Path(p).name for p in paths],
}
metadata = folder / "parameters.json"
metadata.write_text(json.dumps(record, indent=2, ensure_ascii=False) + "\n")
report(1, desc="Complete")
return (
paths,
str(metadata),
f"Saved {len(images)} image(s) · seed {config.seed} · {record['elapsed_seconds']:.1f}s",
)
UI_ASSETS = Path(str(files("assets")))
EXAMPLES = UI_ASSETS / "images"
RATIO_PRESETS = ("9:16", "2:3", "3:4", "1:1", "4:3", "3:2", "16:9")
def build_app(
model_root,
profile="auto",
model=None,
output_dir="outputs/gradio",
prompt_defaults=UI_ASSETS / "prompt_defaults.txt",
local_files_only=False,
):
import gradio as gr
runner = ModelRunner(output_dir, local_files_only)
choices = [DEFAULT_MODEL, *discover_models(model_root)]
if model:
model = model_source(model)
if model not in choices:
choices.append(model)
initial = model or (choices[0] if choices else None)
offload_default, height_default, width_default = profile_defaults(profile)
pixels_default, ratio_default = size_selection(width_default, height_default)
min_budget, max_budget = PIXELS[0] / 1048576, PIXELS[-1] / 1048576
defaults = GenerationConfig()
texts = read_prompt_defaults(prompt_defaults)
def asset_snapshot():
paths = sorted(EXAMPLES.glob("*/parameters.json"))
images = []
stamps = []
for path in paths:
record = json.loads(path.read_text())
image = (path.parent / record.get("image", "image.webp")).resolve()
if not image.is_relative_to(EXAMPLES.resolve()):
raise ValueError("Example images must be inside the assets directory.")
images.append(str(image))
stamps.append([str(path), path.stat().st_mtime_ns, image.stat().st_mtime_ns])
return {"paths": [str(p) for p in paths], "images": images, "stamps": stamps,
"defaults": Path(prompt_defaults).stat().st_mtime_ns, "selected": None}
initial_assets = asset_snapshot()
with gr.Blocks(title="MOSS-Image", analytics_enabled=False) as app:
logo = app.serve_static_file(UI_ASSETS / "logo.svg")
gr.HTML(
'<header style="text-align:center;padding:20px 0 24px">'
'<div style="display:flex;align-items:center;justify-content:center;gap:20px">'
f'<img src="{html.escape(logo["url"].lstrip("/"), quote=True)}" alt="MOSS-Image" '
'width="56" height="56" style="display:block;object-fit:contain">'
'<span aria-hidden="true" style="font-size:32px;font-weight:300;opacity:.3">|</span>'
'<h1 style="margin:0;font-size:clamp(24px,3vw,34px);font-weight:650;'
'letter-spacing:.04em;line-height:1.2">MOSS-Image</h1></div>'
'<nav aria-label="Project links" style="display:flex;justify-content:center;'
'align-items:center;flex-wrap:wrap;gap:8px 24px;margin-top:14px;'
'font-size:14px;line-height:1.8;font-weight:500">'
'<a style="color:var(--body-text-color-subdued);text-decoration:none" '
'href="https://github.com/OpenMOSS/MOSS-Image">GitHub</a>'
'<a style="color:var(--body-text-color-subdued);text-decoration:none" '
'href="https://huggingface.co/OpenMOSS-Team/MOSS-Image-Base">Base weights</a>'
'<a style="color:var(--body-text-color-subdued);text-decoration:none" '
'href="https://github.com/OpenMOSS/MOSS-Image/blob/main/README_ZH.md">文档</a>'
'<a style="color:var(--body-text-color-subdued);text-decoration:none" '
'href="https://x.com/Open_MOSS">OpenMOSS</a></nav></header>'
)
with gr.Row(equal_height=True):
with gr.Column(scale=3, min_width=640):
with gr.Row(equal_height=False, scale=0, elem_id="model-toolbar"):
checkpoint = gr.Dropdown(
choices=[(Path(p).name, p) for p in choices],
value=initial,
allow_custom_value=True,
label="Hugging Face model ID or local directory",
scale=3,
min_width=200,
)
with gr.Group():
prompt = gr.Textbox(
value=texts["prompt_prefix"],
label="Prompt",
lines=4,
max_lines=8,
placeholder="Describe your image — subject, light, composition, style…",
)
negative = gr.Textbox(
value=texts["negative_prompt"],
label="Negative Prompt",
lines=1,
max_lines=3,
placeholder="What would you like to leave out?",
)
with gr.Column():
resolution = gr.State(pixels_default)
ratio = gr.State(ratio_default)
with gr.Row():
resolution_slider = gr.Slider(
minimum=min_budget,
maximum=max_budget,
step=1 / 16,
value=pixels_default / 1048576,
label="Resolution (M pixels)",
scale=3,
min_width=170,
)
aspect_slider = gr.Slider(
minimum=0.125,
maximum=8,
step=0.001,
value=width_default / height_default,
label="Aspect ratio (W/H)",
scale=3,
min_width=170,
)
width = gr.Number(
value=width_default,
precision=0,
label="Width",
minimum=16,
step=16,
scale=1,
min_width=80,
)
height = gr.Number(
value=height_default,
precision=0,
label="Height",
minimum=16,
step=16,
scale=1,
min_width=80,
)
with gr.Row():
resolution_choices = gr.Radio(
choices=[(pixel_label(n), n) for n in PIXELS],
value=pixels_default,
label="Resolution presets",
scale=5,
min_width=240,
)
aspect_choices = gr.Radio(
choices=list(RATIO_PRESETS),
value=ratio_default if ratio_default in RATIO_PRESETS else None,
label="Aspect ratio presets",
scale=7,
min_width=320,
)
with gr.Row(equal_height=True):
with gr.Column(scale=1, min_width=100):
count = gr.Number(value=1, precision=0, label="Images", minimum=1)
with gr.Column(scale=1, min_width=100):
random_seed = gr.Button("Random", size="sm", render=False)
seed = gr.Number(
value=42,
precision=0,
label="Seed",
minimum=-1,
maximum=2**53 - 1,
buttons=[random_seed],
)
with gr.Column(scale=1, min_width=100):
steps = gr.Number(value=defaults.steps, precision=0, minimum=1, label="Steps")
with gr.Accordion("Advanced settings", open=False):
with gr.Row():
cfg = gr.Number(value=defaults.cfg, label="CFG", minimum=0)
shift = gr.Number(value=defaults.shift, label="Shift", minimum=0.01)
with gr.Row():
offload = gr.Dropdown(
choices=[
("GPU resident", "none"),
("Component", "model"),
("Sequential · fallback", "sequential"),
],
value=offload_default,
label="Memory mode",
scale=2,
min_width=140,
)
compile_transformer = gr.Checkbox(
value=False,
interactive=offload_default != "sequential",
label="Compile DiT",
scale=0,
min_width=0,
)
skip_mode = gr.Radio(
choices=[("Off", "off"), ("Negative-branch skipping", "negative"),
("Standard SLG", "standard")],
value="negative",
label="Skip layer mode",
)
layers = gr.Textbox(
value=defaults.uncond_skip_layers,
label="Skip layers",
info="Zero-based layer indices, separated by commas. Empty disables skipping.",
)
with gr.Row(visible=False) as standard_settings:
slg_layers = gr.Textbox(
value=defaults.slg_layers, label="SLG layers",
info="Zero-based layer indices, separated by commas.",
)
slg_scale = gr.Number(value=defaults.slg_scale, minimum=0, label="SLG scale")
with gr.Row() as skip_interval:
slg_start = gr.Number(value=defaults.slg_start, minimum=0, maximum=1, label="Skip start")
slg_stop = gr.Number(value=defaults.slg_stop, minimum=0, maximum=1, label="Skip stop")
with gr.Column(scale=2):
gallery = gr.Gallery(label="生成结果", columns=2, scale=1, object_fit="contain")
status = gr.Textbox(label="Status", interactive=False, scale=0)
with gr.Row():
with gr.Column(scale=3, min_width=640):
generate = gr.Button("Generate", variant="primary")
gr.Column(scale=2)
gr.Markdown("## Examples")
with gr.Row(equal_height=False):
with gr.Column(scale=3, min_width=360):
examples = gr.Gallery(
value=initial_assets["images"],
label="Examples",
columns=4,
object_fit="contain",
interactive=False,
)
with gr.Column(scale=2, min_width=300):
example_prompt = gr.Textbox(
label="Original Prompt",
lines=5,
max_lines=8,
interactive=False,
placeholder="Click an image to view its original prompt.",
)
example_negative = gr.Textbox(
label="Negative Prompt",
lines=1,
max_lines=3,
interactive=False,
)
example_settings = gr.Textbox(
label="Original settings",
lines=2,
max_lines=3,
interactive=False,
)
fields = [
prompt,
negative,
height,
width,
steps,
cfg,
shift,
seed,
count,
layers,
slg_layers,
slg_scale,
slg_start,
slg_stop,
offload,
compile_transformer,
]
field_names = (
"prompt",
"negative_prompt",
"height",
"width",
"steps",
"cfg",
"shift",
"seed",
"num_images",
"uncond_skip_layers",
"slg_layers",
"slg_scale",
"slg_start",
"slg_stop",
"offload",
"compile_transformer",
)
def run(selected, progress=gr.Progress(), *values):
try:
parameters = dict(zip(field_names, values))
if parameters.get("negative_prompt") is None:
parameters["negative_prompt"] = ""
config = GenerationConfig(**parameters)
images, _, message = runner.generate(selected or "", config, progress=progress)
return images, message
except (ValueError, OSError) as exc:
logger.exception("Generation failed")
raise gr.Error(str(exc)) from exc
def load_example(path):
path = Path(path)
record = json.loads(path.read_text())
# Examples supply image settings; keep the user's runtime configuration.
parameters = {
key: value
for key, value in record["parameters"].items()
if key not in ("offload", "compile_transformer")
}
config = parse_parameters(parameters, record.get("schema_version", 1))
# Runtime options stay as the user set them; seed belongs to the example.
return (
config.prompt,
config.negative_prompt,
config.height,
config.width,
config.steps,
config.cfg,
config.shift,
config.num_images,
config.seed,
gr.update(value=config.uncond_skip_layers, visible=bool(config.uncond_skip_layers)),
config.slg_layers,
config.slg_scale,
config.slg_start,
config.slg_stop,
"standard" if config.slg_layers and config.slg_scale > 0 else
"negative" if config.uncond_skip_layers else "off",
gr.update(visible=bool(config.slg_layers and config.slg_scale > 0)),
gr.update(visible=bool(config.uncond_skip_layers or config.slg_layers and config.slg_scale > 0)),
config.prompt,
config.negative_prompt,
(
f"{config.width} × {config.height} · {config.steps} steps · CFG {config.cfg:g}\n"
f"Euler · Seed {parameters.get('seed') if parameters.get('seed') is not None else 'unknown (random on generation)'}\n"
f"Shift {config.shift:g} · "
f"Uncond skip {config.uncond_skip_layers or 'off'} · "
f"Standard SLG {config.slg_layers or 'off'} (scale {config.slg_scale:g}) · "
f"Interval [{config.slg_start:g}, {config.slg_stop:g})"
),
)
assets = gr.State(initial_assets)
def choose_example(state, evt: gr.SelectData):
if evt.index < 0 or evt.index >= len(state["paths"]):
raise gr.Error("Choose an example image.")
path = state["paths"][evt.index]
return (*load_example(path), {**state, "selected": path})
def refresh_assets(state):
fresh = asset_snapshot()
changed = fresh["paths"] != state["paths"] or fresh["stamps"] != state["stamps"]
selected = state["selected"]
fresh["selected"] = selected if selected in fresh["paths"] else None
values = [gr.skip() for _ in example_fields]
if fresh["selected"]:
before = state["stamps"][state["paths"].index(selected)]
after = fresh["stamps"][fresh["paths"].index(selected)]
if before != after:
values = list(load_example(selected))
if selected and not fresh["selected"]:
values[-3:] = ["", "", "Example removed from assets."]
if fresh["defaults"] != state["defaults"]:
defaults = read_prompt_defaults(prompt_defaults)
values[0] = defaults["prompt_prefix"]
values[1] = defaults["negative_prompt"]
selection = fresh["paths"].index(selected) if fresh["selected"] else None
gallery = gr.update(value=fresh["images"], selected_index=selection) if changed else gr.skip()
return (gallery, fresh, *values)
def update_skip(mode):
negative = mode == "negative"
standard = mode == "standard"
return (
gr.update(value="22" if negative else "", visible=negative),
"", 3.0 if standard else 0.0, 0.01 if standard else 0.0, 1.0,
gr.update(visible=standard), gr.update(visible=mode != "off"),
)
def update_compile(mode):
if mode == "sequential":
return gr.update(value=False, interactive=False)
return gr.update(interactive=True)
def apply_ratio(selected, pixels, w, h):
if selected == "custom" or (not pixels and (not w or not h)):
return gr.skip(), gr.skip()
return fit_size(pixels or w * h, selected)
def apply_resolution(pixels, selected, w, h):
if not pixels or (selected == "custom" and (not w or not h)):
return gr.skip(), gr.skip()
return fit_size(pixels, f"{w}:{h}" if selected == "custom" else selected)
def apply_budget(value, selected, w, h):
return apply_resolution(value * 1048576, selected, w, h)
def apply_aspect(value, pixels, w, h):
return apply_ratio(f"{value}:1", pixels, w, h)
def sync_size(w, h):
pixels, selected = size_selection(w, h)
choices = [pixels, selected, pixels or None, selected if selected in RATIO_PRESETS else None]
if not w or not h or w <= 0 or h <= 0:
return choices + [gr.skip(), gr.skip()]
budget = (pixels or w * h) / 1048576
aspect = ratio_value(selected) if selected != "custom" else w / h
return choices + [min(max_budget, max(min_budget, budget)), min(8, max(0.125, aspect))]
resolution_slider.release(
apply_budget, [resolution_slider, ratio, width, height], [width, height], queue=False
)
aspect_slider.release(
apply_aspect, [aspect_slider, resolution, width, height], [width, height], queue=False
)
resolution_choices.input(
apply_resolution,
[resolution_choices, ratio, width, height],
[width, height],
queue=False,
)
aspect_choices.input(
apply_ratio,
[aspect_choices, resolution, width, height],
[width, height],
queue=False,
)
for field in (width, height):
field.change(
sync_size,
[width, height],
[
resolution,
ratio,
resolution_choices,
aspect_choices,
resolution_slider,
aspect_slider,
],
queue=False,
api_name=False,
)
random_seed.click(partial(randbits, 32), outputs=seed, queue=False, api_name=False)
example_fields = [
prompt, negative, height, width, steps, cfg, shift, count, seed, layers,
slg_layers, slg_scale, slg_start, slg_stop,
skip_mode, standard_settings, skip_interval,
example_prompt, example_negative, example_settings,
]
examples.select(
choose_example, inputs=assets, outputs=[*example_fields, assets],
queue=False, api_name=False,
)
gr.Timer(2).tick(
refresh_assets, inputs=assets, outputs=[examples, assets, *example_fields],
queue=False, api_name=False,
)
skip_mode.input(
update_skip, inputs=skip_mode,
outputs=[layers, slg_layers, slg_scale, slg_start, slg_stop, standard_settings, skip_interval],
queue=False, api_name=False,
)
offload.change(
update_compile,
offload,
compile_transformer,
queue=False,
api_name=False,
)
generate.click(
run,
[checkpoint] + fields,
[gallery, status],
concurrency_limit=1,
concurrency_id="model",
api_name="generate",
)
return app.queue(default_concurrency_limit=1, max_size=8)
def main(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--profile", choices=PROFILES, default="auto")
parser.add_argument(
"--model-root",
type=Path,
default=Path(".."),
help="Directory containing complete local model bundles",
)
parser.add_argument("--model", help="Hugging Face model ID or local directory")
parser.add_argument("--local-files-only", action="store_true", help="Use only local files or cached HF files")
parser.add_argument("--output-dir", type=Path, default=Path("outputs/gradio"))
parser.add_argument(
"--prompt-defaults",
type=Path,
default=UI_ASSETS / "prompt_defaults.txt",
help="UTF-8 text file containing [prompt_prefix] and [negative_prompt] sections",
)
parser.add_argument("--host", default="127.0.0.1")
parser.add_argument("--port", type=int, default=7860)
args = parser.parse_args(argv)
logging.basicConfig(level=logging.INFO, format="%(message)s")
app = build_app(
args.model_root, args.profile, args.model, args.output_dir, args.prompt_defaults, args.local_files_only
)
app.launch(
server_name=args.host,
server_port=args.port,
share=False,
allowed_paths=[
str(args.output_dir.expanduser().resolve()),
str(EXAMPLES.resolve()),
str(UI_ASSETS.resolve()),
],
)
if __name__ == "__main__":
main()
+33
View File
@@ -0,0 +1,33 @@
import math
RATIOS = ("1:8", "1:4", "1:3", "1:2", "9:16", "2:3", "3:4", "1:1", "4:3", "3:2", "16:9", "2:1", "3:1", "4:1", "8:1")
PIXELS = (262144, 1048576, 1572864, 2097152, 4194304)
def pixel_label(pixels):
return f"{math.isqrt(pixels)}²" if pixels < 1048576 else f"{pixels / 1048576:g}M"
def ratio_value(text):
w, h = map(float, text.split(":"))
return w / h
def fit_size(pixels, ratio):
ratio = ratio_value(ratio)
width, height = math.sqrt(pixels * ratio), math.sqrt(pixels / ratio)
return tuple(max(16, math.floor(edge / 16 + 0.5) * 16) for edge in (width, height))
def size_selection(width, height):
if not width or not height or width <= 0 or height <= 0:
return 0, "custom"
for pixels in PIXELS:
for ratio in RATIOS:
if fit_size(pixels, ratio) == (width, height):
return pixels, ratio
ratio = next(
(r for r in RATIOS if abs(ratio_value(r) - width / height) < 1e-5),
"custom",
)
return 0, ratio
+84
View File
@@ -0,0 +1,84 @@
"""Application device placement, optional compilation, and progress reporting."""
from __future__ import annotations
from pathlib import Path
import diffusers
import torch
from huggingface_hub.utils import validate_repo_id
DEFAULT_MODEL = "OpenMOSS-Team/MOSS-Image-Base"
def model_source(model):
"""Resolve local bundles without turning Hub IDs into filesystem paths."""
model = str(model).strip()
path = Path(model).expanduser()
if path.is_dir():
if not (path / "pipeline_moss_image.py").is_file():
raise ValueError("The local bundle must include pipeline_moss_image.py from the HF repository.")
return str(path.resolve())
if model.startswith(("/", ".", "~")):
raise FileNotFoundError(f"Model directory does not exist: {model}")
validate_repo_id(model)
return model
def load_pipeline(model, local_files_only=False):
return diffusers.DiffusionPipeline.from_pretrained(
model_source(model),
custom_pipeline="pipeline_moss_image",
trust_remote_code=True,
local_files_only=local_files_only,
torch_dtype={"default": torch.bfloat16, "vae": torch.float32},
)
def set_scheduler(pipe, shift):
pipe.scheduler = type(pipe.scheduler).from_config(pipe.scheduler.config, shift=shift)
def cuda_budget_gib():
if not torch.cuda.is_available():
return 0.0
total = torch.cuda.get_device_properties(0).total_memory
return total * torch.cuda.get_per_process_memory_fraction(0) / 1024**3
def configure_pipeline(pipe, offload="auto", compile_transformer=False):
device = "cuda" if torch.cuda.is_available() else "cpu"
if offload == "auto":
offload = "none" if device == "cpu" or cuda_budget_gib() >= 40 else "model"
if compile_transformer and offload == "sequential":
raise ValueError("Compilation is incompatible with sequential offload.")
if offload == "model":
pipe.enable_model_cpu_offload(device=device)
elif offload == "sequential":
pipe.enable_sequential_cpu_offload(device=device)
elif offload == "none":
pipe.to(device)
else:
raise ValueError(f"Unknown offload mode: {offload}")
if compile_transformer:
for block in (*pipe.transformer.layers, *pipe.transformer.text_embedder.blocks):
block.compile(backend="inductor", fullgraph=True, dynamic=True, mode="default")
return pipe
def generate_with_progress(pipe, report_stage, report_step, **kwargs):
progress_bar = pipe.progress_bar
def progress(items):
report_stage("denoise")
for index, timestep in enumerate(progress_bar(items)):
yield timestep
report_step(pipe, index, timestep, {})
if kwargs.get("output_type", "pil") != "latent":
report_stage("decode")
pipe.progress_bar = progress
try:
report_stage("encode")
return pipe(**kwargs)
finally:
pipe.progress_bar = progress_bar
Binary file not shown.
+39
View File
@@ -0,0 +1,39 @@
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "moss-image"
version = "0.1.0"
description = "Standalone MOSS-Image text-to-image inference with Diffusers"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.10"
dependencies = [
"torch>=2.9", "diffusers>=0.38", "transformers>=5.3",
"accelerate>=1.10", "safetensors>=0.6", "Pillow>=10",
]
[project.optional-dependencies]
dev = ["pytest>=8", "ruff>=0.11"]
ui = ["gradio>=6.30"]
[tool.setuptools]
license-files = ["LICENSE", "LICENSES/*.txt"]
py-modules = ["inference_runtime", "gradio_app", "gradio_presets"]
packages = ["assets"]
include-package-data = false
[tool.setuptools.package-data]
assets = ["logo.svg", "prompt_defaults.txt", "images/*/*.webp", "images/*/*.png", "images/*/*.json"]
[tool.ruff]
line-length = 110
target-version = "py310"
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "I"]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["."]
+1
View File
@@ -0,0 +1 @@
-e .
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
repo_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
exec python "${repo_dir}/gradio_app.py" "$@"
+107
View File
@@ -0,0 +1,107 @@
---
name: moss-image-prompt-enhancer
description: Expand an image-generation request into a detailed MOSS-Image caption or spatial layout, and compile a local JSON draft into a ready-to-paste prompt. Use for prompt enhancement, image composition and text placement; this skill does not generate images.
---
# MOSS-Image Prompt Enhancer
Turn the user's idea into a concrete image description. Target GPT-6-family
agents with filesystem and shell tools. The agent makes creative decisions;
the bundled Python tool handles coordinate arithmetic and serialization.
No Echidna service, model API or third-party Python dependency is needed.
## Choose the deliverable
Honor an explicit request for a caption or Layout. Otherwise use a caption for
ordinary scenes, photographs and illustrations. Use Layout when specific text
placement, a poster, several panels, or controlled object relationships would
benefit from bounding boxes. A detailed image does not automatically need Layout.
Preserve the user's subjects, counts, relationships, medium, style, exclusions
and intended visible wording. Resolve ordinary creative gaps yourself; ask only
when a missing decision would materially change the requested image. Do not
invent factual event logistics or specifications as if the user supplied them.
Default to English for descriptive prose, following a requested output language
when given. Preserve visible text verbatim in its original language, including
punctuation, capitalization and requested line breaks. A quoted sentence in an
instruction is not necessarily text to render: distinguish visible wording from
reference material and constraints.
## Develop the image
Describe visible choices: subject and action, relevant appearance, setting,
camera/framing, medium, lighting, materials, palette and mood. Add detail where
it makes the requested image more specific. Avoid redundant quality tags,
unrequested style changes, arbitrary word budgets and invisible process notes.
Keep an explicit minimalist brief minimalist; develop a rich brief without
turning it into a generic title/hero/footer template.
Keep explanations of JSON, bounding-box annotations and conversion steps out of
image-description fields; those are tool instructions, not depicted content.
For designed images, compose the information and imagery together. Establish
reading order, relative prominence, coherent groups and readable text at the
chosen pixels. Write the intended copy rather than placeholders such as
"headline here" or "some explanatory text". Do not import unrelated names,
watermarks or copy from a reference. Use supplied references when useful; outside
research is optional unless needed for factual accuracy or requested by the user.
## Caption
Write a UTF-8 JSON file containing exactly `{"caption":"..."}`. The caption is
cohesive prose, with spatial relations in words and any visible wording quoted
exactly. It may contain paragraphs; do not add coordinates or JSON-layout fields
to a caption just to make it look structured.
## Layout
Read [references/layout.md](references/layout.md) before writing a Layout draft.
Write readable JSON with `summary`, a flat `items` array, concrete `width` and
`height`, `bbox_coord_space="abs"` and `bbox_format="xyxy"`.
**Draft boxes use `[x_min,y_min,x_max,y_max]` in actual pixels, from the canvas
top-left.** Keep x in `0..width` and y in `0..height`. Do not use normalized
coordinates or manually center, reorder or quantize the boxes.
Honor supplied dimensions. With only an aspect ratio, choose compatible pixel
dimensions; without either, use 1024×1024 unless the requested medium suggests
another shape. MOSS-Image dimensions must be positive multiples of 16. Do not
silently change explicit dimensions that are incompatible; surface the conflict.
Use the same width and height in the image-generation workflow.
Use boxes for coherent visible units, splitting only when independent placement
matters. Grouping should preserve content and relationships, not erase them.
Natural occlusion and overlap are allowed. A box is a placement annotation,
not an instruction to draw a border, panel or sticker. Describe appearance in
captions and global treatment in `summary.caption`; let boxes agree with any
spatial descriptions. Keep exact visible strings in text items' `text` fields.
## Compile and deliver
Save the draft to a user-appropriate working directory, then run the tool bundled
beside this SKILL.md. Resolve the script path from the skill location, not the
user's working directory:
```bash
python3 /path/to/moss-image-prompt-enhancer/scripts/compile_prompt.py \
draft.json --output prompt.txt
```
Use an actual path in the invocation. Keep the editable JSON draft and compiled
output separate. Read the result and check the subject, exact text, intended
geometry and chosen canvas before delivering. Fix validation errors in the draft
and rerun; do not bypass a failed conversion by hand-writing centered JSON.
For captions, the output is plain text. For Layout, it is one physical line of
JSON with flat `items`, integer `abs_centralized` / `yxyx` boxes and no canvas
metadata. The tool encloses fractional pixel edges before subtracting the center,
matching Echidna's generation conversion. It rejects invalid or out-of-bounds
boxes instead of silently clipping them. String newlines are escaped in the JSON
while remaining actual newlines in the decoded text.
Return the ready-to-paste prompt or a link to its file, and retain a link to the
draft when useful for editing. For Layout also state the required width×height
outside the prompt; the model prompt itself does not contain these dimensions.
If showing Layout JSON inline, use the compiled output without reformatting it.
Only the caption or compiled Layout belongs in MOSS-Image's positive prompt.
Creating these files does not submit image generation or publish anything.
@@ -0,0 +1,4 @@
interface:
display_name: "MOSS-Image Prompt Enhancer"
short_description: "Expand image ideas into captions or pixel layouts"
default_prompt: "Use $moss-image-prompt-enhancer to turn my image idea into a detailed caption or a generation-ready layout."
Loaded 100 of 119 files, more files were not shown because too many files have changed in this diff. Show more