-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Xingchao Liu
committed
Nov 13, 2024
1 parent
7a388c4
commit b010135
Showing
10 changed files
with
2,982 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,12 @@ | |
<img src="images/logo.svg" width="60%" alt="DeepSeek LLM" /> | ||
</div> | ||
<hr> | ||
|
||
<div align="center"> | ||
<h1>🚀 Janus-Series: Unified Multimodal Understanding and Generation Models</h1> | ||
|
||
</div> | ||
|
||
<div align="center"> | ||
|
||
<a href="https://www.deepseek.com/" target="_blank"> | ||
|
@@ -45,30 +51,44 @@ | |
|
||
|
||
<p align="center"> | ||
<a href="#3-model-download"><b>📥 Model Download</b></a> | | ||
<a href="#4-quick-start"><b>⚡ Quick Start</b></a> | | ||
<a href="#5-license"><b>📜 License</b></a> | | ||
<a href="#6-citation"><b>📖 Citation</b></a> <br> | ||
<a href="https://arxiv.org/abs/2410.13848"><b>📄 Paper Link</b></a> | | ||
<a href="https://huggingface.co/spaces/deepseek-ai/Janus-1.3B"><b>🤗 Online Demo</b></a> | ||
<a href="#2-model-download"><b>📥 Model Download</b></a> | | ||
<a href="#3-quick-start"><b>⚡ Quick Start</b></a> | | ||
<a href="#4-license"><b>📜 License</b></a> | | ||
<a href="#5-citation"><b>📖 Citation</b></a> <br> | ||
<!-- 📄 Paper Link (<a href="https://arxiv.org/abs/2410.13848"><b>Janus</b></a>, <a href="https://arxiv.org/abs/2410.13848"><b>JanusFlow</b></a>) | --> | ||
🤗 Online Demo (<a href="https://huggingface.co/spaces/deepseek-ai/Janus-1.3B"><b>Janus</b></a>, <a href="https://huggingface.co/spaces/deepseek-ai/JanusFlow-1.3B"><b>JanusFlow</b></a>) | ||
</p> | ||
|
||
|
||
## News | ||
|
||
**2024.11.13**: JanusFlow is released, a new unified model with rectified flow for image generation. See [paper](https://arxiv.org/abs/2411.07975), [demo](https://huggingface.co/spaces/deepseek-ai/JanusFlow-1.3B) and [usage](https://github.com/deepseek-ai/Janus?tab=readme-ov-file#janusflow). | ||
|
||
**2024.10.23**: Evaluation code for reproducing the multimodal understanding results from the paper has been added to VLMEvalKit. Please refer to [this link]( https://github.com/open-compass/VLMEvalKit/pull/541). | ||
|
||
**2024.10.20**: (1) Fix a bug in [tokenizer_config.json](https://huggingface.co/deepseek-ai/Janus-1.3B/blob/main/tokenizer_config.json). The previous version caused classifier-free guidance to not function properly, resulting in relatively poor visual generation quality. (2) Release Gradio demo ([online demo](https://huggingface.co/spaces/deepseek-ai/Janus-1.3B) and [local](#gradio-demo)). | ||
|
||
|
||
## 1. Introduction | ||
|
||
Janus is a novel autoregressive framework that unifies multimodal understanding and generation. It addresses the limitations of previous approaches by decoupling visual encoding into separate pathways, while still utilizing a single, unified transformer architecture for processing. The decoupling not only alleviates the conflict between the visual encoder’s roles in understanding and generation, but also enhances the framework’s flexibility. Janus surpasses previous unified model and matches or exceeds the performance of task-specific models. The simplicity, high flexibility, and effectiveness of Janus make it a strong candidate for next-generation unified multimodal models. | ||
<a href="https://arxiv.org/abs/2410.13848"><b>Janus: Decoupling Visual Encoding for Unified Multimodal Understanding and Generation</b></a> | ||
|
||
**Janus** is a novel autoregressive framework that unifies multimodal understanding and generation. It addresses the limitations of previous approaches by decoupling visual encoding into separate pathways, while still utilizing a single, unified transformer architecture for processing. The decoupling not only alleviates the conflict between the visual encoder’s roles in understanding and generation, but also enhances the framework’s flexibility. Janus surpasses previous unified model and matches or exceeds the performance of task-specific models. The simplicity, high flexibility, and effectiveness of Janus make it a strong candidate for next-generation unified multimodal models. | ||
|
||
<div align="center"> | ||
<img alt="image" src="images/teaser.png" style="width:90%;"> | ||
</div> | ||
|
||
## 2. News | ||
<a href="https://arxiv.org/abs/2411.07975"><b>JanusFlow: Harmonizing Autoregression and Rectified Flow for Unified Multimodal Understanding and Generation</b></a> | ||
|
||
**2024.10.23**: Evaluation code for reproducing the multimodal understanding results from the paper has been added to VLMEvalKit. Please refer to [this link]( https://github.com/open-compass/VLMEvalKit/pull/541). | ||
**JanusFlow** introduces a minimalist architecture that integrates autoregressive language models with rectified flow, a state-of-the-art method in generative modeling. Our key finding demonstrates that rectified flow can be straightforwardly trained within the large language model framework, eliminating the need for complex architectural modifications. Extensive experiments show that JanusFlow achieves comparable or superior performance to specialized models in their respective domains, while significantly outperforming existing unified approaches across standard benchmarks. This work represents a step toward more efficient and versatile vision-language models. | ||
|
||
**2024.10.20**: (1) Fix a bug in [tokenizer_config.json](https://huggingface.co/deepseek-ai/Janus-1.3B/blob/main/tokenizer_config.json). The previous version caused classifier-free guidance to not function properly, resulting in relatively poor visual generation quality. (2) Release Gradio demo ([online demo](https://huggingface.co/spaces/deepseek-ai/Janus-1.3B) and [local](#gradio-demo)). | ||
<div align="center"> | ||
<img alt="image" src="images/teaser_janusflow.png" style="width:90%;"> | ||
</div> | ||
|
||
|
||
## 3. Model Download | ||
## 2. Model Download | ||
|
||
We release Janus to the public to support a broader and more diverse range of research within both academic and commercial communities. | ||
Please note that the use of this model is subject to the terms outlined in [License section](#5-license). Commercial usage is | ||
|
@@ -79,11 +99,15 @@ permitted under these terms. | |
| Model | Sequence Length | Download | | ||
|-----------------------|-----------------|-----------------------------------------------------------------------------| | ||
| Janus-1.3B | 4096 | [🤗 Hugging Face](https://huggingface.co/deepseek-ai/Janus-1.3B) | | ||
| JanusFlow-1.3B | 4096 | [🤗 Hugging Face](https://huggingface.co/deepseek-ai/JanusFlow-1.3B) | | ||
|
||
|
||
|
||
|
||
## 3. Quick Start | ||
|
||
## 4. Quick Start | ||
<details> | ||
<summary><h3>Janus</h3></summary> | ||
|
||
### Installation | ||
|
||
|
@@ -278,26 +302,237 @@ To test the server, you can open another terminal and run: | |
``` | ||
python demo/fastapi_client.py | ||
``` | ||
</details> | ||
|
||
<details> | ||
<summary><h3>JanusFlow</h3></summary> | ||
### Installation | ||
|
||
## 5. License | ||
On the basis of `Python >= 3.8` environment, install the necessary dependencies by running the following command: | ||
|
||
This code repository is licensed under [the MIT License](https://github.com/deepseek-ai/DeepSeek-LLM/blob/HEAD/LICENSE-CODE). The use of Janus models is subject to [DeepSeek Model License](https://github.com/deepseek-ai/DeepSeek-LLM/blob/HEAD/LICENSE-MODEL). | ||
```shell | ||
pip install -e . | ||
pip install diffusers[torch] | ||
``` | ||
|
||
### 🤗 Huggingface Online Demo | ||
Check out the demo in [this link](https://huggingface.co/spaces/deepseek-ai/JanusFlow-1.3B). | ||
|
||
### Simple Inference Example | ||
|
||
#### Multimodal Understanding | ||
```python | ||
|
||
import torch | ||
from janus.janusflow.models import MultiModalityCausalLM, VLChatProcessor | ||
from janus.utils.io import load_pil_images | ||
|
||
# specify the path to the model | ||
model_path = "deepseek-ai/JanusFlow-1.3B" | ||
vl_chat_processor: VLChatProcessor = VLChatProcessor.from_pretrained(model_path) | ||
tokenizer = vl_chat_processor.tokenizer | ||
|
||
vl_gpt = MultiModalityCausalLM.from_pretrained( | ||
model_path, trust_remote_code=True | ||
) | ||
vl_gpt = vl_gpt.to(torch.bfloat16).cuda().eval() | ||
|
||
conversation = [ | ||
{ | ||
"role": "User", | ||
"content": "<image_placeholder>\nConvert the formula into latex code.", | ||
"images": ["images/equation.png"], | ||
}, | ||
{"role": "Assistant", "content": ""}, | ||
] | ||
|
||
# load images and prepare for inputs | ||
pil_images = load_pil_images(conversation) | ||
prepare_inputs = vl_chat_processor( | ||
conversations=conversation, images=pil_images, force_batchify=True | ||
).to(vl_gpt.device) | ||
|
||
# # run image encoder to get the image embeddings | ||
inputs_embeds = vl_gpt.prepare_inputs_embeds(**prepare_inputs) | ||
|
||
# # run the model to get the response | ||
outputs = vl_gpt.language_model.generate( | ||
inputs_embeds=inputs_embeds, | ||
attention_mask=prepare_inputs.attention_mask, | ||
pad_token_id=tokenizer.eos_token_id, | ||
bos_token_id=tokenizer.bos_token_id, | ||
eos_token_id=tokenizer.eos_token_id, | ||
max_new_tokens=512, | ||
do_sample=False, | ||
use_cache=True, | ||
) | ||
|
||
answer = tokenizer.decode(outputs[0].cpu().tolist(), skip_special_tokens=True) | ||
print(f"{prepare_inputs['sft_format'][0]}", answer) | ||
|
||
``` | ||
|
||
#### Text-to-Image Generation | ||
```python | ||
import os | ||
import PIL.Image | ||
import torch | ||
import numpy as np | ||
from janus.janusflow.models import MultiModalityCausalLM, VLChatProcessor | ||
import torchvision | ||
|
||
|
||
# specify the path to the model | ||
model_path = "deepseek-ai/JanusFlow-1.3B" | ||
vl_chat_processor: VLChatProcessor = VLChatProcessor.from_pretrained(model_path) | ||
tokenizer = vl_chat_processor.tokenizer | ||
|
||
vl_gpt = MultiModalityCausalLM.from_pretrained( | ||
model_path, trust_remote_code=True | ||
) | ||
vl_gpt = vl_gpt.to(torch.bfloat16).cuda().eval() | ||
|
||
from diffusers.models import AutoencoderKL | ||
# remember to use bfloat16 dtype, this vae doesn't work with fp16 | ||
vae = AutoencoderKL.from_pretrained("stabilityai/sdxl-vae") | ||
vae = vae.to(torch.bfloat16).cuda().eval() | ||
|
||
conversation = [ | ||
{ | ||
"role": "User", | ||
"content": "A stunning princess from kabul in red, white traditional clothing, blue eyes, brown hair", | ||
}, | ||
{"role": "Assistant", "content": ""}, | ||
] | ||
|
||
sft_format = vl_chat_processor.apply_sft_template_for_multi_turn_prompts( | ||
conversations=conversation, | ||
sft_format=vl_chat_processor.sft_format, | ||
system_prompt="", | ||
) | ||
prompt = sft_format + vl_chat_processor.image_gen_tag | ||
|
||
## 6. Citation | ||
|
||
@torch.inference_mode() | ||
def generate( | ||
mmgpt: MultiModalityCausalLM, | ||
vl_chat_processor: VLChatProcessor, | ||
prompt: str, | ||
cfg_weight: float = 5.0, | ||
num_inference_steps: int = 30, | ||
batchsize: int = 5 | ||
): | ||
input_ids = vl_chat_processor.tokenizer.encode(prompt) | ||
input_ids = torch.LongTensor(input_ids) | ||
|
||
tokens = torch.stack([input_ids] * 2 * batchsize).cuda() | ||
tokens[batchsize:, 1:] = vl_chat_processor.pad_id | ||
inputs_embeds = vl_gpt.language_model.get_input_embeddings()(tokens) | ||
|
||
# we remove the last <bog> token and replace it with t_emb later | ||
inputs_embeds = inputs_embeds[:, :-1, :] | ||
|
||
# generate with rectified flow ode | ||
# step 1: encode with vision_gen_enc | ||
z = torch.randn((batchsize, 4, 48, 48), dtype=torch.bfloat16).cuda() | ||
|
||
dt = 1.0 / num_inference_steps | ||
dt = torch.zeros_like(z).cuda().to(torch.bfloat16) + dt | ||
|
||
# step 2: run ode | ||
attention_mask = torch.ones((2*batchsize, inputs_embeds.shape[1]+577)).to(vl_gpt.device) | ||
attention_mask[batchsize:, 1:inputs_embeds.shape[1]] = 0 | ||
attention_mask = attention_mask.int() | ||
for step in range(num_inference_steps): | ||
# prepare inputs for the llm | ||
z_input = torch.cat([z, z], dim=0) # for cfg | ||
t = step / num_inference_steps * 1000. | ||
t = torch.tensor([t] * z_input.shape[0]).to(dt) | ||
z_enc = vl_gpt.vision_gen_enc_model(z_input, t) | ||
z_emb, t_emb, hs = z_enc[0], z_enc[1], z_enc[2] | ||
z_emb = z_emb.view(z_emb.shape[0], z_emb.shape[1], -1).permute(0, 2, 1) | ||
z_emb = vl_gpt.vision_gen_enc_aligner(z_emb) | ||
llm_emb = torch.cat([inputs_embeds, t_emb.unsqueeze(1), z_emb], dim=1) | ||
|
||
# input to the llm | ||
# we apply attention mask for CFG: 1 for tokens that are not masked, 0 for tokens that are masked. | ||
if step == 0: | ||
outputs = vl_gpt.language_model.model(inputs_embeds=llm_emb, | ||
use_cache=True, | ||
attention_mask=attention_mask, | ||
past_key_values=None) | ||
past_key_values = [] | ||
for kv_cache in past_key_values: | ||
k, v = kv_cache[0], kv_cache[1] | ||
past_key_values.append((k[:, :, :inputs_embeds.shape[1], :], v[:, :, :inputs_embeds.shape[1], :])) | ||
past_key_values = tuple(past_key_values) | ||
else: | ||
outputs = vl_gpt.language_model.model(inputs_embeds=llm_emb, | ||
use_cache=True, | ||
attention_mask=attention_mask, | ||
past_key_values=past_key_values) | ||
hidden_states = outputs.last_hidden_state | ||
|
||
# transform hidden_states back to v | ||
hidden_states = vl_gpt.vision_gen_dec_aligner(vl_gpt.vision_gen_dec_aligner_norm(hidden_states[:, -576:, :])) | ||
hidden_states = hidden_states.reshape(z_emb.shape[0], 24, 24, 768).permute(0, 3, 1, 2) | ||
v = vl_gpt.vision_gen_dec_model(hidden_states, hs, t_emb) | ||
v_cond, v_uncond = torch.chunk(v, 2) | ||
v = cfg_weight * v_cond - (cfg_weight-1.) * v_uncond | ||
z = z + dt * v | ||
|
||
# step 3: decode with vision_gen_dec and sdxl vae | ||
decoded_image = vae.decode(z / vae.config.scaling_factor).sample | ||
|
||
os.makedirs('generated_samples', exist_ok=True) | ||
save_path = os.path.join('generated_samples', "img.jpg") | ||
torchvision.utils.save_image(decoded_image.clip_(-1.0, 1.0)*0.5+0.5, save_path) | ||
|
||
generate( | ||
vl_gpt, | ||
vl_chat_processor, | ||
prompt, | ||
cfg_weight=2.0, | ||
num_inference_steps=30, | ||
batchsize=5 | ||
) | ||
``` | ||
@misc{wu2024janus, | ||
title={Janus: Decoupling Visual Encoding for Unified Multimodal Understanding and Generation}, | ||
author={Chengyue Wu and Xiaokang Chen and Zhiyu Wu and Yiyang Ma and Xingchao Liu and Zizheng Pan and Wen Liu and Zhenda Xie and Xingkai Yu and Chong Ruan and Ping Luo}, | ||
year={2024}, | ||
eprint={2410.13848}, | ||
archivePrefix={arXiv}, | ||
primaryClass={cs.CV}, | ||
url={https://arxiv.org/abs/2410.13848}, | ||
|
||
### Gradio Demo | ||
For the local gradio demo, you can run with the following command: | ||
|
||
``` | ||
pip install -e .[gradio] | ||
python demo/app_janusflow.py | ||
``` | ||
|
||
Have Fun! | ||
|
||
</details> | ||
|
||
## 4. License | ||
|
||
This code repository is licensed under [the MIT License](https://github.com/deepseek-ai/DeepSeek-LLM/blob/HEAD/LICENSE-CODE). The use of Janus models is subject to [DeepSeek Model License](https://github.com/deepseek-ai/DeepSeek-LLM/blob/HEAD/LICENSE-MODEL). | ||
|
||
## 5. Citation | ||
|
||
```bibtex | ||
@article{wu2024janus, | ||
title={Janus: Decoupling visual encoding for unified multimodal understanding and generation}, | ||
author={Wu, Chengyue and Chen, Xiaokang and Wu, Zhiyu and Ma, Yiyang and Liu, Xingchao and Pan, Zizheng and Liu, Wen and Xie, Zhenda and Yu, Xingkai and Ruan, Chong and others}, | ||
journal={arXiv preprint arXiv:2410.13848}, | ||
year={2024} | ||
} | ||
@misc{ma2024janusflow, | ||
title={JanusFlow: Harmonizing Autoregression and Rectified Flow for Unified Multimodal Understanding and Generation}, | ||
author={Yiyang Ma and Xingchao Liu and Xiaokang Chen and Wen Liu and Chengyue Wu and Zhiyu Wu and Zizheng Pan and Zhenda Xie and Haowei Zhang and Xingkai yu and Liang Zhao and Yisong Wang and Jiaying Liu and Chong Ruan}, | ||
journal={arXiv preprint arXiv:2411.07975}, | ||
year={2024} | ||
} | ||
``` | ||
|
||
## 7. Contact | ||
## 6. Contact | ||
|
||
If you have any questions, please raise an issue or contact us at [[email protected]](mailto:[email protected]). |
Oops, something went wrong.