Full Code of modelscope/facechain for AI

main 7bc7119c54de cached
249 files
5.2 MB
1.4M tokens
1328 symbols
1 requests
Download .txt
Showing preview only (5,464K chars total). Download the full file or copy to clipboard to get everything.
Repository: modelscope/facechain
Branch: main
Commit: 7bc7119c54de
Files: 249
Total size: 5.2 MB

Directory structure:
gitextract_95kbsdu1/

├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── README_ZH.md
├── app.py
├── face_adapter/
│   ├── __init__.py
│   ├── face_adapter_v1.py
│   ├── face_attention_processor_v1.py
│   ├── face_preprocess.py
│   ├── utils.py
│   └── vit.py
├── face_module/
│   ├── DamoFD/
│   │   └── README.md
│   ├── TopoFR/
│   │   ├── GUM.py
│   │   ├── README.md
│   │   ├── backbones/
│   │   │   ├── __init__.py
│   │   │   ├── iresnet.py
│   │   │   ├── iresnet2060.py
│   │   │   └── mobilefacenet.py
│   │   ├── configs/
│   │   │   ├── __init__.py
│   │   │   ├── base.py
│   │   │   ├── glint360k_r100.py
│   │   │   ├── glint360k_r200.py
│   │   │   ├── glint360k_r50.py
│   │   │   ├── ms1mv2_r100.py
│   │   │   ├── ms1mv2_r200.py
│   │   │   └── ms1mv2_r50.py
│   │   ├── dataset.py
│   │   ├── docs/
│   │   │   ├── eval.md
│   │   │   ├── install.md
│   │   │   ├── install_dali.md
│   │   │   ├── modelzoo.md
│   │   │   ├── prepare_webface42m.md
│   │   │   └── speed_benchmark.md
│   │   ├── eval/
│   │   │   ├── __init__.py
│   │   │   └── verification.py
│   │   ├── eval_ijbc_glint360k.py
│   │   ├── eval_ijbc_ms1mv2.py
│   │   ├── flops.py
│   │   ├── inference.py
│   │   ├── losses.py
│   │   ├── lr_scheduler.py
│   │   ├── onnx_helper.py
│   │   ├── onnx_ijbc.py
│   │   ├── partial_fc.py
│   │   ├── persistent_homology.py
│   │   ├── requirement.txt
│   │   ├── topology.py
│   │   ├── torch2onnx.py
│   │   ├── train.py
│   │   └── utils/
│   │       ├── __init__.py
│   │       ├── plot.py
│   │       ├── utils_callbacks.py
│   │       ├── utils_config.py
│   │       ├── utils_distributed_sampler.py
│   │       └── utils_logging.py
│   └── TransFace/
│       ├── FFT.py
│       ├── README.md
│       ├── backbones/
│       │   ├── __init__.py
│       │   ├── iresnet.py
│       │   ├── iresnet2060.py
│       │   ├── mobilefacenet.py
│       │   └── vit.py
│       ├── configs/
│       │   ├── __init__.py
│       │   ├── base.py
│       │   ├── glint360k_vit_s.py
│       │   └── ms1mv2_vit_s.py
│       ├── dataset.py
│       ├── dist.sh
│       ├── docs/
│       │   ├── eval.md
│       │   ├── install.md
│       │   ├── install_dali.md
│       │   ├── modelzoo.md
│       │   ├── prepare_webface42m.md
│       │   └── speed_benchmark.md
│       ├── eval/
│       │   ├── __init__.py
│       │   └── verification.py
│       ├── eval_ijbc.py
│       ├── flops.py
│       ├── inference.py
│       ├── losses.py
│       ├── lr_scheduler.py
│       ├── onnx_helper.py
│       ├── onnx_ijbc.py
│       ├── partial_fc_exp.py
│       ├── requirement.txt
│       ├── run.sh
│       ├── torch2onnx.py
│       ├── train.py
│       └── utils/
│           ├── __init__.py
│           ├── plot.py
│           ├── utils_callbacks.py
│           ├── utils_config.py
│           ├── utils_distributed_sampler.py
│           └── utils_logging.py
├── facechain/
│   ├── constants.py
│   ├── inference_fact.py
│   ├── inference_inpaint_fact.py
│   ├── merge_lora.py
│   └── utils.py
├── install.py
├── main.css
├── more_apps/
│   └── Facechain-SuDe/
│       ├── README.md
│       ├── configs/
│       │   ├── autoencoder/
│       │   │   ├── autoencoder_kl_16x16x16.yaml
│       │   │   ├── autoencoder_kl_32x32x4.yaml
│       │   │   ├── autoencoder_kl_64x64x3.yaml
│       │   │   └── autoencoder_kl_8x8x64.yaml
│       │   ├── latent-diffusion/
│       │   │   ├── celebahq-ldm-vq-4.yaml
│       │   │   ├── cin-ldm-vq-f8.yaml
│       │   │   ├── cin256-v2.yaml
│       │   │   ├── ffhq-ldm-vq-4.yaml
│       │   │   ├── lsun_bedrooms-ldm-vq-4.yaml
│       │   │   ├── lsun_churches-ldm-kl-8.yaml
│       │   │   ├── txt2img-1p4B-eval.yaml
│       │   │   ├── txt2img-1p4B-eval_with_tokens.yaml
│       │   │   ├── txt2img-1p4B-finetune.yaml
│       │   │   └── txt2img-1p4B-finetune_style.yaml
│       │   └── stable-diffusion/
│       │       ├── v1-finetune_unfrozen.yaml
│       │       └── v1-inference.yaml
│       ├── environment.yaml
│       ├── ldm/
│       │   ├── data/
│       │   │   ├── __init__.py
│       │   │   ├── base.py
│       │   │   ├── imagenet.py
│       │   │   ├── lsun.py
│       │   │   ├── personalized.py
│       │   │   └── personalized_style.py
│       │   ├── lr_scheduler.py
│       │   ├── models/
│       │   │   ├── autoencoder.py
│       │   │   └── diffusion/
│       │   │       ├── __init__.py
│       │   │       ├── classifier.py
│       │   │       ├── ddim.py
│       │   │       ├── ddpm.py
│       │   │       └── plms.py
│       │   ├── modules/
│       │   │   ├── attention.py
│       │   │   ├── diffusionmodules/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── model.py
│       │   │   │   ├── openaimodel.py
│       │   │   │   └── util.py
│       │   │   ├── distributions/
│       │   │   │   ├── __init__.py
│       │   │   │   └── distributions.py
│       │   │   ├── ema.py
│       │   │   ├── embedding_manager.py
│       │   │   ├── encoders/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── modules.py
│       │   │   │   └── modules_bak.py
│       │   │   ├── image_degradation/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── bsrgan.py
│       │   │   │   ├── bsrgan_light.py
│       │   │   │   └── utils_image.py
│       │   │   ├── losses/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── contperceptual.py
│       │   │   │   └── vqperceptual.py
│       │   │   └── x_transformer.py
│       │   └── util.py
│       ├── main.py
│       ├── main.sh
│       ├── merge_embeddings.py
│       ├── scripts/
│       │   ├── download_first_stages.sh
│       │   ├── download_models.sh
│       │   ├── evaluate_model.py
│       │   ├── inpaint.py
│       │   ├── latent_imagenet_diffusion.ipynb
│       │   ├── sample_diffusion.py
│       │   ├── stable_txt2img.py
│       │   └── txt2img.py
│       └── setup.py
├── run_inference.py
├── run_inference_inpaint.py
├── scripts/
│   └── facechain_sdwebui.py
├── styles/
│   ├── MajicmixRealistic_v6/
│   │   ├── Autumn_populus.json
│   │   ├── Bleak_autumn.json
│   │   ├── Cartoon.json
│   │   ├── Cheongsam.json
│   │   ├── Chinese_New_Year.json
│   │   ├── Chinese_winter_hanfu.json
│   │   ├── Christmas.json
│   │   ├── Colorful_rainbow.json
│   │   ├── Cool_tones.json
│   │   ├── Cowboy.json
│   │   ├── Deer_girl.json
│   │   ├── Disneyland.json
│   │   ├── DreamyOcean.json
│   │   ├── Dunhuang.json
│   │   ├── Duobaan.json
│   │   ├── Embroidery.json
│   │   ├── European_fields.json
│   │   ├── Fairy_style.json
│   │   ├── Fashion_glasses.json
│   │   ├── Flame_red_style.json
│   │   ├── Flowers.json
│   │   ├── Gentleman.json
│   │   ├── GuoFeng.json
│   │   ├── Hiphop.json
│   │   ├── Hong_Kong_night_style.json
│   │   ├── India.json
│   │   ├── Jacket_in_Snow_Mountain.json
│   │   ├── Kimono.json
│   │   ├── Li.json
│   │   ├── Lolita.json
│   │   ├── Luolita.json
│   │   ├── Maid.json
│   │   ├── Mechnical.json
│   │   ├── Men_suit.json
│   │   ├── Miaozu.json
│   │   ├── Model_style.json
│   │   ├── Mongolian.json
│   │   ├── Motorcycle_race_style.json
│   │   ├── Ocean_Summer_vibe.json
│   │   ├── PekingOpera_female_role.json
│   │   ├── Polaroid_style.json
│   │   ├── Princess_style.json
│   │   ├── Rainy_night.json
│   │   ├── Redstyle.json
│   │   ├── Retro_style.json
│   │   ├── Roaming_Astronaut.json
│   │   ├── School_uniform.json
│   │   ├── Science_fiction.json
│   │   ├── Soccer.json
│   │   ├── Street_style.json
│   │   ├── Tibetan_clothing.json
│   │   ├── Traditional_chinese_style.json
│   │   ├── Tyndall.json
│   │   ├── Underwater.json
│   │   ├── Wedding_dress.json
│   │   ├── Wedding_dress_2.json
│   │   ├── West_cowboy.json
│   │   ├── Wild_west.json
│   │   ├── Witch.json
│   │   ├── Wizard_of_Oz.json
│   │   ├── ZangZu.json
│   │   └── Zhuang_style.json
│   └── leosamsMoonfilm_filmGrain20/
│       ├── Armor.json
│       ├── Barbie_Doll.json
│       ├── Casual_Lifestyle.json
│       ├── Chinese_traditional_gorgeous_suit.json
│       ├── Cybernetics_punk.json
│       ├── Elegant_Princess.json
│       ├── Gown.json
│       ├── Hanfu.json
│       ├── Innocent_Girl_in_White_Dress.json
│       ├── Pixy_Girl.json
│       ├── Snow_white.json
│       ├── T-shirt.json
│       └── Working_suit.json
└── train_style/
    ├── __init__.py
    ├── convert_lora.py
    ├── deepbooru.py
    ├── demo.py
    └── train_text_to_image_lora.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
*.safetensors filter=lfs diff=lfs merge=lfs -text


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
test.py
# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
/package
/temp
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/

.vscode
.idea

# custom
*.pkl
*.pkl.json
*.log.json
*.whl
*.tar.gz
*.swp
*.log
*.tar.gz
source.sh
tensorboard.sh
.DS_Store
replace.sh
result.png
lora_result.png
result.jpg
result.mp4

# Pytorch
*.pth
*.pt

# ast template
ast_index_file.py


================================================
FILE: LICENSE
================================================
                                 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.


================================================
FILE: README.md
================================================
<p align="center">
    <br>
    <img src="https://modelscope.oss-cn-beijing.aliyuncs.com/modelscope.gif" width="400"/>
    <br>
    <h1>FaceChain</h1>
<p>

<p align="center">
<a href="https://trendshift.io/repositories/1185" target="_blank"><img src="https://trendshift.io/api/badge/repositories/1185" alt="modelscope%2Ffacechain | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>

# News
- Our work [FaceChain-MMID](https://www.sciencedirect.com/science/article/abs/pii/S0031320325005187) got accepted to Pattern Recognition ! (May 30th, 2025 UTC)
- More Technology Details of FaceChain-FACT train-free portrait generation can be seen in [Paper](https://arxiv.org/abs/2410.12312). (October 17th, 2024 UTC)
- Our work [TopoFR](https://arxiv.org/abs/2410.10587) got accepted to NeurIPS 2024 ! (September 26th, 2024 UTC)
- We provide training scripts for new styles, offering an automatic training for new style LoRas as well as the corresponding style prompts, along with the one click call in Infinite Style Portrait generation tab! (July 3rd, 2024 UTC)
- 🚀🚀🚀 We are launching [FACT] into the main branch, offering a 10-second impressive speed and seamless integration with standard ready-to-use LoRas and ControlNets, along with improved instruction-following capabilities ! The original train-based FaceChain is moved to (https://github.com/modelscope/facechain/tree/v3.0.0 ). (May 28th, 2024 UTC)
- Our work [FaceChain-ImagineID](https://arxiv.org/abs/2403.01901) and [FaceChain-SuDe](https://arxiv.org/abs/2403.06775) got accepted to CVPR 2024 ! (February 27th, 2024 UTC)

# Introduction

如果您熟悉中文,可以阅读[中文版本的README](./README_ZH.md)。

FaceChain is a novel framework for generating identity-preserved human portraits. In the newest FaceChain FACT (Face Adapter with deCoupled Training) version, with only 1 photo and 10 seconds, you can generate personal portraits in different settings (multiple styles now supported!). FaceChain has both high controllability and authenticity in portrait generation, including text-to-image and inpainting based pipelines, and is seamlessly compatible with ControlNet and LoRAs. You may generate portraits via FaceChain's Python scripts, or via the familiar Gradio interface, or via sd webui. 
FaceChain is powered by [ModelScope](https://github.com/modelscope/modelscope).


<p align="center">
        ModelScope Studio <a href="https://modelscope.cn/studios/CVstudio/FaceChain-FACT">🤖<a></a>&nbsp |API <a href="https://help.aliyun.com/zh/dashscope/developer-reference/facechain-quick-start">🔥<a></a>&nbsp | SD WebUI | HuggingFace Space <a href="https://huggingface.co/spaces/modelscope/FaceChain-FACT">🤗</a>&nbsp 
</p>
<br>

<a href='https://facechain-fact.github.io/'><img src='https://img.shields.io/badge/Project-Page-Green'></a>  [![YouTube](https://badges.aleen42.com/src/youtube.svg)](https://youtu.be/DHqEl0qwi-M?si=y6VpInXdhIX0HpbI)


![image](resources/git_cover.png)


# News
- Our work [FaceChain-MMID](https://www.sciencedirect.com/science/article/abs/pii/S0031320325005187) got accepted to Pattern Recognition ! (May 30th, 2025 UTC)
- More Technology Details of FaceChain-FACT train-free portrait generation can be seen in [Paper](https://arxiv.org/abs/2410.12312). (October 17th, 2024 UTC)
- Our work [TopoFR](https://arxiv.org/abs/2410.10587) got accepted to NeurIPS 2024 ! (September 26th, 2024 UTC)
- We provide training scripts for new styles, offering an automatic training for new style LoRas as well as the corresponding style prompts, along with the one click call in Infinite Style Portrait generation tab! (July 3rd, 2024 UTC)
- 🚀🚀🚀 We are launching [FACT], offering a 10-second impressive speed and seamless integration with standard ready-to-use LoRas and ControlNets, along with improved instruction-following capabilities ! (May 28th, 2024 UTC)
- Our work [FaceChain-ImagineID](https://arxiv.org/abs/2403.01901) and [FaceChain-SuDe](https://arxiv.org/abs/2403.06775) got accepted to CVPR 2024 ! (February 27th, 2024 UTC)
- 🏆🏆🏆Alibaba Annual Outstanding Open Source Project, Alibaba Annual Open Source Pioneer (Yang Liu, Baigui Sun). (January 20th, 2024 UTC)
- Our work [InfoBatch](https://github.com/henryqin1997/InfoBatch) co-authored with NUS team got accepted to ICLR 2024(Oral)! (January 16th, 2024 UTC)
- 🏆OpenAtom's 2023 Rapidly Growing Open Source Projects Award. (December 20th, 2023 UTC)
- Add SDXL pipeline🔥🔥🔥, image detail is improved obviously. (November 22th, 2023 UTC)
- Support super resolution🔥🔥🔥, provide multiple resolution choice (512*512, 768*768, 1024*1024, 2048*2048). (November 13th, 2023 UTC)
- 🏆FaceChain has been selected in the [BenchCouncil Open100 (2022-2023)](https://www.benchcouncil.org/evaluation/opencs/annual.html#Institutions) annual ranking. (November 8th, 2023 UTC)
- Add virtual try-on module. (October 27th, 2023 UTC)
- Add wanx version [online free app](https://tongyi.aliyun.com/wanxiang/app/portrait-gallery). (October 26th, 2023 UTC)
- 🏆1024 Programmer's Day AIGC Application Tool Most Valuable Business Award. (2023-10-24, 2023 UTC)
- Support FaceChain in stable-diffusion-webui🔥🔥🔥. (October 13th, 2023 UTC)
- High performance inpainting for single & double person, Simplify User Interface. (September 09th, 2023 UTC)
- More Technology Details can be seen in [Paper](https://arxiv.org/abs/2308.14256). (August 30th, 2023 UTC)
- Add validate & ensemble for Lora training, and InpaintTab(hide in gradio for now).  (August 28th, 2023 UTC)
- Add pose control module.   (August 27th, 2023 UTC)
- Add robust face lora training module, enhance the performance of one pic training & style-lora blending.   (August 27th, 2023 UTC)
- HuggingFace Space is available now! You can experience FaceChain directly with <a href="https://huggingface.co/spaces/modelscope/FaceChain">🤗</a>      (August 25th, 2023 UTC)
- Add awesome prompts! Refer to: [awesome-prompts-facechain](resources/awesome-prompts-facechain.txt)   (August 18th, 2023 UTC)
- Support a series of new style models in a plug-and-play fashion.  (August 16th, 2023 UTC)
- Support customizable prompts. (August 16th, 2023 UTC)
- Colab notebook is available now! You can experience FaceChain directly with  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/modelscope/facechain/blob/main/facechain_demo.ipynb).   (August 15th, 2023 UTC)


# To-Do List
- full-body digital humans


# Citation

Please cite FaceChain and FaceChain-FACT in your publications if it helps your research
```
@article{liu2023facechain,
  title={FaceChain: A Playground for Identity-Preserving Portrait Generation},
  author={Liu, Yang and Yu, Cheng and Shang, Lei and Wu, Ziheng and 
          Wang, Xingjun and Zhao, Yuze and Zhu, Lin and Cheng, Chen and 
          Chen, Weitao and Xu, Chao and Xie, Haoyu and Yao, Yuan and 
          Zhou,  Wenmeng and Chen Yingda and Xie, Xuansong and Sun, Baigui},
  journal={arXiv preprint arXiv:2308.14256},
  year={2023}
}
```
```
@article{yu2024facechain,
  title={FaceChain-FACT: Face Adapter with Decoupled Training for Identity-preserved Personalization},
  author={Yu, Cheng and Xie, Haoyu and Shang, Lei and Liu, Yang and Dan, Jun and Sun, Baigui and Bo, Liefeng},
  journal={arXiv preprint arXiv:2410.12312},
  year={2024}
}
```


# Installation

## Compatibility Verification
We have verified e2e execution on the following environment:
- python: py3.8, py3.10
- pytorch: torch2.0.0, torch2.0.1
- CUDA: 11.7
- CUDNN: 8+
- OS: Ubuntu 20.04, CentOS 7.9
- GPU: Nvidia-A10 24G

## Memory Optimization
Jemalloc are recommanded to install for optimizing the memory from above 30G to below 20G. Here is an example for installing Jemalloc in Modelscope notebook.

```shell
apt-get install -y libjemalloc-dev
export LD_PRELOAD=/lib/x86_64-linux-gnu/libjemalloc.so
```

## Installation Guide
The following installation methods are supported:


### 1. ModelScope notebook【recommended】

   The ModelScope Notebook offers a free-tier that allows ModelScope user to run the FaceChain application with minimum setup, refer to [ModelScope Notebook](https://modelscope.cn/my/mynotebook/preset)

```shell
# Step1: 我的notebook -> PAI-DSW -> GPU环境
# Note: Please use: ubuntu20.04-py38-torch2.0.1-tf1.15.5-modelscope1.8.1

# Step2: Entry the Notebook cell,clone FaceChain from github:
!GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/modelscope/facechain.git --depth 1

# Step3: Change the working directory to facechain, and install the dependencies:
import os
os.chdir('/mnt/workspace/facechain')    # You may change to your own path
print(os.getcwd())

!pip3 install gradio==3.47.1
!pip3 install controlnet_aux==0.0.6
!pip3 install python-slugify
!pip3 install diffusers==0.29.0
!pip3 install peft==0.11.1
!pip3 install modelscope -U
!pip3 install datasets==2.16

# Step4: Start the app service, click "public URL" or "local URL", upload your images to 
# train your own model and then generate your digital twin.
!python3 app.py

```
   Alternatively, you may also purchase a [PAI-DSW](https://www.aliyun.com/activity/bigdata/pai/dsw) instance (using A10 resource), with the option of ModelScope image to run FaceChain following similar steps.


### 2. Docker

If you are familiar with using docker, we recommend to use this way:

```shell
# Step1: Prepare the environment with GPU on local or cloud, we recommend to use Alibaba Cloud ECS, refer to: https://www.aliyun.com/product/ecs

# Step2: Download the docker image (for installing docker engine, refer to https://docs.docker.com/engine/install/)
# For China Mainland users:
docker pull registry.cn-hangzhou.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1
# For users outside China Mainland:
docker pull registry.us-west-1.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1

# Step3: run the docker container
docker run -it --name facechain -p 7860:7860 --gpus all registry.cn-hangzhou.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1 /bin/bash
# Note: you may need to install the nvidia-container-runtime, follow the instructions:
# 1. Install nvidia-container-runtime:https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
# 2. sudo systemctl restart docker

# Step4: Install the gradio in the docker container:
pip3 install gradio==3.47.1
pip3 install controlnet_aux==0.0.6
pip3 install python-slugify
pip3 install diffusers==0.29.0
pip3 install peft==0.11.1
pip3 install modelscope -U
pip3 install datasets==2.16

# Step5 clone facechain from github
GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/modelscope/facechain.git --depth 1
cd facechain
python3 app.py
# Note: FaceChain currently assume single-GPU, if your environment has multiple GPU, please use the following instead:
# CUDA_VISIBLE_DEVICES=0 python3 app.py

# Step6
Run the app server: click "public URL" --> in the form of: https://xxx.gradio.live
```

### 3. stable-diffusion-webui

1. Select the `Extensions Tab`, then choose `Install From URL` (official plugin integration is integrated, please install from URL currently).
   ![image](resources/sdwebui_install.png)

2. Switch to `Installed`, check the FaceChain plugin, then click `Apply and restart UI`. It may take a while for installing the dependencies and downloading the models. Make sure that the "CUDA Toolkit" is installed correctly, otherwise the "mmcv" package cannot be successfully installed.
   ![image](resources/sdwebui_restart.png)

3. After the page refreshes, the appearance of the `FaceChain` Tab indicates a successful installation.
   ![image](resources/sdwebui_success.jpg)

# Script Execution

FaceChain supports direct inference in the python environment. When inferring for Infinite Style Portrait generation, please edit the code in run_inference.py:

```python
# Use pose control, default False
use_pose_model = False
# The path of the input image containing ID information for portrait generation
input_img_path = 'poses/man/pose2.png'
# The path of the image for pose control, only effective when using pose control
pose_image = 'poses/man/pose1.png'
# The number of images to generate in inference
num_generate = 5
# The weight for the style model, see styles for detail
multiplier_style = 0.25
# Specify a folder to save the generated images, this parameter can be modified as needed
output_dir = './generated'
# The index of the chosen base model, see facechain/constants.py for detail
base_model_idx = 0
# The index of the style model, see styles for detail
style_idx = 0
```

Then execute:

```shell
python run_inference.py
```

You can find the generated personal digital image photos in the `output_dir`.

When inferring for Fixed Templates Portrait generation, please edit the code in run_inference_inpaint.py.

```python
# Number of faces for the template image
num_faces = 1
# Index of face for inpainting, counting from left to right
selected_face = 1
# The strength for inpainting, you do not need to change the parameter
strength = 0.6
# The path of the template image
inpaint_img = 'poses/man/pose1.png'
# The path of the input image containing ID information for portrait generation
input_img_path = 'poses/man/pose2.png'
# The number of images to generate in inference
num_generate = 1
# Specify a folder to save the generated images, this parameter can be modified as needed
output_dir = './generated_inpaint'
```

Then execute:

```shell
python run_inference_inpaint.py
```

You can find the generated personal digital image photos in the `output_dir`.


# Algorithm Introduction

The capability of AI portraits generation comes from the large generative models like Stable Diffusion and its fine-tuning techniques. Due to the strong generalization capability of large models, it is possible to perform downstream tasks by fine-tuning on specific types of data and tasks, while preserving the model's overall ability of text following and image generation. The technical foundation of train-based and train-free AI portraits generation comes from applying different fine-tuning tasks to generative models. Currently, most existing AI portraits tools adopt a two-stage “train then generate” pipeline, where the fine-tuning task is “to generate portrait photos of a fixed character ID”, and the corresponding training data are multiple images of the fixed character ID. The effectiveness of such train-based pipeline depends on the scale of the training data, thus requiring certain image data support and training time, which also increases the cost for users.

Different from train-based pipeline, train-free pipeline adjusts the fine-tuning task to “generate portrait photos of a specified character ID”, meaning that the character ID image (face photo) is used as an additional input, and the output is a portrait photo preserving the input ID. Such a pipeline completely separates offline training from online inference, allowing users to generate portraits directly based on the fine-tuned model with only one photo in just 10 seconds, avoiding the cost for extensive data and training time. The fine-tuning task of train-free AI portraits generation is based on the adapter module. Face photos are processed through an image encoder with fixed weights and a parameter-efficient feature projection layer to obtain aligned features, and are then fed into the U-Net model of Stable Diffusion through attention mechanism similar as text conditions. At this point, face information as an independent branch condition is fed into the model alongside text information for inference, thereby enabling the generated images to maintain ID fidelity.

The basic algorithm based on face adapter is capable of achieving train-free AI portraits, but still requires certain adjustments to further improve its effectiveness. Existing train-free portrait tools generally suffer from the following issues: poor image quality of portraits, inadequate text following and style retention abilities in portraits, poor controllability and richness of portrait faces, and poor compatibility with extensions like ControlNet and style Lora. To address these issues, FaceChain attribute them to the fact that the fine-tuning tasks for existing train-free AI portrait tools have coupled with too much information beyond character IDs, and propose FaceChain Face Adapter with Decoupled Training (FaceChain FACT) to solve these problems. By fine-tuning the Stable Diffusion model on millions of portrait data, FaceChain FACT can achieve high-quality portrait image generation for specified character IDs. The entire framework of FaceChain FACT is shown in the figure below.

![image](resources/framework.png)

The decoupled training of FaceChain FACT consists of two parts: decoupling face from image, and decoupling ID from face. Existing methods often treat denoising portrait images as the fine-tuning task, which makes the model hard to accurately focus on the face area, thereby affecting the text-to-image ability of the base Stable Diffusion model. FaceChain FACT draws on the sequential processing and regional control advantages of face-swapping algorithms and implements the fine-tuning method for decoupling faces from images from both structural and training strategy aspects. Structurally, unlike existing methods that use a parallel cross-attention mechanism to process face and text information, FaceChain FACT adopts a sequential processing approach as an independent adapter layer inserted into the original Stable Diffusion's blocks. This way, face adaptation acts as an independent step similar to face-swapping during the denoising process, avoiding interference between face and text conditions. In terms of training strategy, besides the original MSE loss function, FaceChain FACT introduces the Face Adapting Incremental Regularization (FAIR) loss function, which controls the feature increment of the face adaptation step in the adapter layer to focus on the face region. During inference, users can flexibly adjust the generated effects by modifying the weight of the face adapter, balancing fidelity and generalization of the face while maintaining the text-to-image ability of Stable Diffusion. The FAIR loss function is formulated as follows:

![image](resources/FAIR.png)

Furthermore, addressing the issue of poor controllability and richness of generated faces, FaceChain FACT proposes a training method for decoupling ID from face, so that the portrait process only preserves the character ID rather than the entire face. Firstly, to better extract the ID information from the face while maintaining certain key facial details, and to better adapt to the structure of Stable Diffusion, FaceChain FACT employs a face feature extractor named [TransFace](https://github.com/DanJun6737/TransFace) based on the Transformer architecture, which is pre-trained on a large-scale face dataset. All tokens from the penultimate layer are subsequently fed into a simple attention query model for feature projection, thereby ensuring that the extracted ID features meet the aforementioned requirements. Additionally, during the training process, FaceChain FACT uses the Classifier Free Guidance (CFG) method to perform random shuffle and drop for different portrait images of the same ID, thus ensuring that the input face images and the target images used for denoising may have different faces with the same ID, thus further preventing the model from overfitting to non-ID information of the face. As such, FaceChain FACT possesses high compatibility with the massive exquisite styles of FaceChain, which is shown as follows.

![image](resources/generated_examples.png)


## Model List

The models used in FaceChain:

[1]  Face recognition model TransFace:https://www.modelscope.cn/models/iic/cv_vit_face-recognition

[2]  Face detection model DamoFD:https://modelscope.cn/models/damo/cv_ddsar_face-detection_iclr23-damofd

[3]  Human parsing model M2FP:https://modelscope.cn/models/damo/cv_resnet101_image-multiple-human-parsing

[4]  Skin retouching model ABPN:https://www.modelscope.cn/models/damo/cv_unet_skin_retouching_torch

[5]  Face fusion model:https://www.modelscope.cn/models/damo/cv_unet_face_fusion_torch

[6]  FaceChain FACT model: https://www.modelscope.cn/models/yucheng1996/FaceChain-FACT

[7]  Face attribute recognition model FairFace: https://modelscope.cn/models/damo/cv_resnet34_face-attribute-recognition_fairface


# More Information

- [ModelScope library](https://github.com/modelscope/modelscope/)


​        ModelScope Library provides the foundation for building the model-ecosystem of ModelScope, including the interface and implementation to integrate various models into ModelScope. 

- [Contribute models to ModelScope](https://modelscope.cn/docs/ModelScope%E6%A8%A1%E5%9E%8B%E6%8E%A5%E5%85%A5%E6%B5%81%E7%A8%8B%E6%A6%82%E8%A7%88)

# License

This project is licensed under the [Apache License (Version 2.0)](https://github.com/modelscope/modelscope/blob/master/LICENSE).


================================================
FILE: README_ZH.md
================================================
<p align="center">
    <br>
    <img src="https://modelscope.oss-cn-beijing.aliyuncs.com/modelscope.gif" width="400"/>
    <br>
    <h1>FaceChain</h1>
<p>

# 最新消息
- Facechain算法创新工作[FaceChain-MMID](https://www.sciencedirect.com/science/article/abs/pii/S0031320325005187) 在期刊Pattern Recognition上发表! (2025-05-30)
- 更多关于FaceChain-FACT免训练工作的技术细节可以在 [论文](https://arxiv.org/abs/2410.12312) 里查看. (2024-10-17)
- Facechain算法创新工作[TopoFR](https://arxiv.org/abs/2410.10587) 被NeurIPS 2024接收录用! (2024-09-26)
- 添加自定义风格模型训练,可全自动训练生成自定义风格LoRa模型以及对应的风格提示词,并在无限风格写真页面支持对训练的自定义风格模型的一键式调用!(2024-07-03)
- 🚀🚀🚀 正在推出[FACT]到主目录,10秒写真出图,兼容现成的LoRa与ControlNet,并且具备更强的指令跟随能力!原始版本已移至(https://github.com/modelscope/facechain/tree/v3.0.0 )。(2024-05-28)
- FaceChain两项算法创新工作[FaceChain-ImagineID](https://arxiv.org/abs/2403.01901)与[FaceChain-SuDe](https://arxiv.org/abs/2403.06775)被CVPR 2024接收录用! (2024-02-27)

# 介绍

FaceChain是一个可以用来生成个人写真的深度学习模型工具。在最新的FaceChain FACT版本中,用户仅需要提供一张照片即可10秒钟获得独属于自己的个人写真(支持多种风格)。FaceChain可实现兼具可控性与ID保持能力的无限风格写真与固定模板写真功能,同时对ControlNet和LoRA具有优秀的兼容能力。FaceChain支持在gradio的界面中使用模型训练和推理能力、支持资深开发者使用python脚本进行训练推理,也支持在sd webui中安装插件使用。同时,我们也欢迎开发者对本Repo进行继续开发和贡献。
FaceChain的模型由[ModelScope](https://github.com/modelscope/modelscope)开源模型社区提供支持。

<p align="center">
        ModelScope Studio <a href="https://modelscope.cn/studios/CVstudio/FaceChain-FACT">🤖<a></a>&nbsp |API <a href="https://help.aliyun.com/zh/dashscope/developer-reference/facechain-quick-start">🔥<a></a>&nbsp | SD WebUI | HuggingFace Space <a href="https://huggingface.co/spaces/modelscope/FaceChain-FACT">🤗</a>&nbsp 
</p>
<br>

<a href='https://facechain-fact.github.io/'><img src='https://img.shields.io/badge/Project-Page-Green'></a>  [![YouTube](https://badges.aleen42.com/src/youtube.svg)](https://youtu.be/DHqEl0qwi-M?si=y6VpInXdhIX0HpbI)


![image](resources/git_cover_ZH.png)



# News
- Facechain算法创新工作[FaceChain-MMID](https://www.sciencedirect.com/science/article/abs/pii/S0031320325005187) 在期刊Pattern Recognition上发表! (2025-05-30)
- 更多关于FaceChain-FACT免训练工作的技术细节可以在 [论文](https://arxiv.org/abs/2410.12312) 里查看. (2024-10-17)
- Facechain算法创新工作[TopoFR](https://arxiv.org/abs/2410.10587) 被NeurIPS 2024接收录用! (2024-09-26)
- 添加自定义风格模型训练,可全自动训练生成自定义风格LoRa模型以及对应的风格提示词,并在无限风格写真页面支持对训练的自定义风格模型的一键式调用!(2024-07-03)
- 🚀🚀🚀 正在推出[FACT],10秒写真出图,兼容现成的LoRa与ControlNet,并且具备更强的指令跟随能力!(2024-05-28)
- FaceChain两项算法创新工作[FaceChain-ImagineID](https://arxiv.org/abs/2403.01901)与[FaceChain-SuDe](https://arxiv.org/abs/2403.06775)被CVPR 2024接收录用! (2024-02-27)
- 🏆🏆🏆阿里巴巴年度开源新锐项目、阿里巴巴年度开源先锋人物-技术贡献(刘洋)、阿里巴巴年度开源先锋人物-生态贡献(孙佰贵). (2024-01-20)
- 与NUS团队合作的[InfoBatch](https://github.com/henryqin1997/InfoBatch) 被ICLR 2024(Oral)录用! pytorch中只用3行代码的版本PR中. (2024-01-16)
- 🏆开放原子2023快速成长开源项目奖项. (2023-12-20)
- 支持SDXL模块🔥🔥🔥,出图细腻度大幅提升. (November 22th, 2023 UTC)
- 支持超分模块🔥🔥🔥,目前多种分辨率可选 (512*512, 768*768, 1024*1024, 2048*2048). (November 13th, 2023 UTC)
- 🏆FaceChain入选[BenchCouncil Open100 (2022-2023)](https://www.benchcouncil.org/evaluation/opencs/annual.html#Institutions) 开源榜单. (2023-11-08)
- 增加虚拟试衣模块,可基于包含给定服饰的模特图或人台图进行重绘. (2023-10-27)
- 增加万相版本[在线免费应用](https://tongyi.aliyun.com/wanxiang/app/portrait-gallery). (2023-10-26)
- 🏆1024程序员节AIGC应用工具最具商业价值奖. (2023-10-24)
- stable-diffusion-webui支持🔥🔥🔥. (2023-10-13)
- 高性能的(单人&双人)模版重绘功能,简化用户界面. (2023-09-09)
- 更多技术细节可以在 [论文](https://arxiv.org/abs/2308.14256) 里查看. (2023-08-30)
- 为Lora训练添加验证和根据face_id的融合,并添加InpaintTab(目前在Gradio界面上暂时默认隐藏). (2023-08-28)
- 增加姿势控制模块,可一键体验模版pose复刻. (2023-08-27)
- 增加鲁棒性人脸lora训练,提升单图训练&风格lora融合的效果. (2023-08-27)
- 支持在HuggingFace Space中体验FaceChain ! <a href="https://huggingface.co/spaces/modelscope/FaceChain">🤗</a>      (2023-08-25)
- 新增高质量提示词模板,欢迎大家一起贡献! 参考 [awesome-prompts-facechain](resources/awesome-prompts-facechain.txt)    (2023-08-18)
- 支持即插即用的风格LoRA模型! (2023-08-16)
- 新增个性化prompt模块! (2023-08-16)
- Colab notebook安装已支持,您可以直接打开链接体验FaceChain: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/modelscope/facechain/blob/main/facechain_demo.ipynb)   (2023-08-15)


# 待办事项
- 全身数字人


# 引用

如果FaceChain对您的研究有所帮助,请在您的出版物中引用FaceChain及FaceChain-FACT
```
@article{liu2023facechain,
  title={FaceChain: A Playground for Identity-Preserving Portrait Generation},
  author={Liu, Yang and Yu, Cheng and Shang, Lei and Wu, Ziheng and 
          Wang, Xingjun and Zhao, Yuze and Zhu, Lin and Cheng, Chen and 
          Chen, Weitao and Xu, Chao and Xie, Haoyu and Yao, Yuan and 
          Zhou,  Wenmeng and Chen Yingda and Xie, Xuansong and Sun, Baigui},
  journal={arXiv preprint arXiv:2308.14256},
  year={2023}
```
```
@article{yu2024facechain,
  title={FaceChain-FACT: Face Adapter with Decoupled Training for Identity-preserved Personalization},
  author={Yu, Cheng and Xie, Haoyu and Shang, Lei and Liu, Yang and Dan, Jun and Sun, Baigui and Bo, Liefeng},
  journal={arXiv preprint arXiv:2410.12312},
  year={2024}
}
```

# 环境准备

## 兼容性验证
FaceChain是一个组合模型,基于PyTorch机器学习框架,以下是已经验证过的主要环境依赖:
- python环境: py3.8, py3.10
- pytorch版本: torch2.0.0, torch2.0.1
- CUDA版本: 11.7
- CUDNN版本: 8+
- 操作系统版本: Ubuntu 20.04, CentOS 7.9
- GPU型号: Nvidia-A10 24G

## 内存优化
推荐安装Jemalloc以节省内存占用,可将内存由约30G降至20G以下。以Modelscope notebook为例,Jemalloc的安装指令如下:

```shell
apt-get install -y libjemalloc-dev
export LD_PRELOAD=/lib/x86_64-linux-gnu/libjemalloc.so
```

## 资源要求
- GPU: 显存占用约19G
- 磁盘: 推荐预留50GB以上的存储空间


## 安装指南
支持以下几种安装方式,任选其一:

### 1. 使用ModelScope提供的notebook环境【推荐】
ModelScope(魔搭社区)提供给新用户初始的免费计算资源,参考[ModelScope Notebook](https://modelscope.cn/my/mynotebook/preset)
    
如果初始免费计算资源无法满足要求,您还可以从上述页面开通付费流程,以便创建一个准备就绪的ModelScope(GPU) DSW镜像实例。
    
Notebook环境使用简单,您只需要按以下步骤操作(注意:目前暂不提供永久存储,实例重启后数据会丢失):


```shell
# Step1: 我的notebook -> PAI-DSW -> GPU环境
# 注意: 请选择以下镜像: ubuntu20.04-py38-torch2.0.1-tf1.15.5-modelscope1.8.1

# Step2: 进入Notebook cell,执行下述命令从github clone代码:
!GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/modelscope/facechain.git --depth 1

# Step3: 切换当前工作路径,安装依赖
import os
os.chdir('/mnt/workspace/facechain')    # 注意替换成上述clone后的代码文件夹主路径
print(os.getcwd())

!pip3 install gradio==3.47.1
!pip3 install controlnet_aux==0.0.6
!pip3 install python-slugify
!pip3 install diffusers==0.29.0
!pip3 install peft==0.11.1
!pip3 install modelscope -U
!pip3 install datasets==2.16

# Step4: 启动服务,点击生成的URL即可访问web页面,上传照片开始训练和预测
!python3 app.py

```

除了ModelScope入口以外,您也可以前往[PAI-DSW](https://www.aliyun.com/activity/bigdata/pai/dsw) 直接购买带有ModelScope镜像的计算实例(推荐使用A10资源),这样同样可以使用如上的最简步骤运行起来。



### 2. docker镜像

如果您熟悉docker,可以使用我们提供的docker镜像,其包含了模型依赖的所有组件,无需复杂的环境安装:
```shell
# Step1: 机器资源
您可以使用本地或云端带有GPU资源的运行环境。
如需使用阿里云ECS,可访问: https://www.aliyun.com/product/ecs,推荐使用”镜像市场“中的CentOS 7.9 64位(预装NVIDIA GPU驱动)

# Step2: 将镜像下载到本地 (前提是已经安装了docker engine并启动服务,具体可参考: https://docs.docker.com/engine/install/)
# For China Mainland users:
docker pull registry.cn-hangzhou.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1
# For users outside China Mainland:
docker pull registry.us-west-1.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1

# Step3: 拉起镜像运行
docker run -it --name facechain -p 7860:7860 --gpus all registry.cn-hangzhou.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1 /bin/bash
# 注意: 如果提示无法使用宿主机GPU的错误,可能需要安装nvidia-container-runtime
# 1. 安装nvidia-container-runtime:https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
# 2. 重启docker服务:sudo systemctl restart docker

# Step4: 在容器中安装gradio
pip3 install gradio==3.47.1
pip3 install controlnet_aux==0.0.6
pip3 install python-slugify
pip3 install diffusers==0.29.0
pip3 install peft==0.11.1
pip3 install modelscope -U
pip3 install datasets==2.16

# Step5: 获取facechain源代码
GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/modelscope/facechain.git --depth 1
cd facechain
python3 app.py
# Note: FaceChain目前支持单卡GPU,如果您的环境有多卡,请使用如下命令
# CUDA_VISIBLE_DEVICES=0 python3 app.py

# Step6: 点击 "public URL", 形式为 https://xxx.gradio.live
```

### 3. stable-diffusion-webui中运行

1. 选择`Extensions Tab`,选择`Install From URL`(官方插件集成中,先从URL安装)。
   ![image](resources/sdwebui_install.png)

2. 切换到`Installed`,勾选FaceChain插件,点击`Apply and restart UI`。安装环境依赖和下载模型可能需要花费较长时间。请确认CUDA Toolkit已安装,否则mmcv的安装将会报错。
   ![image](resources/sdwebui_restart.png)

3. 页面刷新后,出现`FaceChain`选项说明安装成功。
   ![image](resources/sdwebui_success.jpg)

# 脚本运行

如果不想启动服务,而是直接在命令行进行开发调试等工作,FaceChain也支持在python环境中直接运行脚本进行训练和推理。进行无限风格写真生成时,请编辑run_inference.py中的代码:

```python
# 使用深度控制,默认False,仅在使用姿态控制时生效
use_pose_model = False
# 输入用户图像
input_img_path = 'poses/man/pose2.png'
# 姿态控制图片路径,仅在使用姿态控制时生效
pose_image = 'poses/man/pose1.png'
# 推理生成的图片数量
num_generate = 5
# 风格模型权重,详情可参考styles文件夹
multiplier_style = 0.25
# 指定一个保存生成的图片的文件夹,本参数可以根据需要修改
output_dir = './generated'
# 基模型的索引编号,详情可参考facechain/constants.py
base_model_idx = 0
# 风格模型的索引编号,详情可参考styles文件夹
style_idx = 0
```

之后执行:

```python
python run_inference.py
```

即可在`output_dir`中找到生成的个人写真照片。

进行固定模板写真生成时,请编辑run_inference_inpaint.py中的代码:

```python
# 模板图像的人脸数量
num_faces = 1
# 用于重绘的人脸编号,按从左至右的顺序
selected_face = 1
# 模板重回强度参数,该参数建议谨慎调整
strength = 0.6
# 输入模板图像
inpaint_img = 'poses/man/pose1.png'
# 输入用户图像
input_img_path = 'poses/man/pose2.png'
# 推理生成的图片数量
num_generate = 1
# 指定一个保存生成的图片的文件夹,本参数可以根据需要修改
output_dir = './generated_inpaint'
```

之后执行:

```shell
python run_inference_inpaint.py
```

即可在`output_dir`中找到生成的个人写真照片。
                                             
# 算法介绍

AI写真的能力来源于以Stable Diffusion为代表的文生图大模型及其微调技术。由于大模型具有强大的泛化能力,因此可以通过在单一类型的数据和任务中进行微调的方式,在保持模型整体的文本跟随和图像生成能力的基础上,实现下游任务。基于训练和免训练的AI写真的技术基础就来自于对文生图模型进行不同的微调任务。目前市面上的AI写真大多采用“训练+生成”的两阶段模式,此时的微调任务为“生成固定人物ID的写真图片”,对应的训练数据为多张该人物ID的形象图片。该模式的效果与训练数据的规模成正相关,因此往往需要庞大的形象数据支撑以及一定的训练时间,这也增加了用户的使用成本。

不同于上述模式,免训练的AI写真将微调任务调整为“生成指定人物ID的写真图片”,即将人物ID形象图片(人脸图片)作为额外的输入,输出具有与输入形象具有相同ID特征的写真图片。该模式可以将线下训练与线上推理彻底分离,用户使用时直接基于微调后的模型进行写真生成,仅需一张图片,无需大量数据和训练等待时间,10秒钟即可生成专属AI写真。免训练AI写真的微调任务的基础算法是基于适配器(adapter)模块实现的,人脸图片经过固定权重的图像编码器(image encoder)以及低参数量的特征投影层得到对齐后的特征,而后通过对固定权重的Stable Diffusion中的U-Net模块添加与文本条件类似的注意力机制模块实现对模型的微调。此时人脸信息作为独立分支的条件平行于文本信息一起送入模型中进行推理,故而可以使生成图片具有ID保持能力。

基于face adapter的基础算法尽管可以实现免训练AI写真,但仍需进行一定的调整以进一步优化其效果。市面上的免训练写真工具往往存在以下几点问题:写真图像质量差、写真文本跟随能力和风格保持能力不佳、写真人脸可控性和丰富度差、算法对ControlNet和风格Lora的兼容性不好等。针对上述问题,FaceChain将其归结于已有的用于免训练AI写真的微调任务耦合了过多人物ID以外的信息,并提出了解耦训练的人脸适配器算法(FaceChain Face Adapter with deCoupled Training,FaceChain FACT)以解决上述问题。通过在百万级别的写真数据上对Stable Diffusion模型进行微调,FaceChain FACT可以实现高质量的指定人物ID的写真图片生成。FaceChain FACT的整个框架如下图所示。

![image](resources/framework.png)

FaceChain FACT的解耦训练分为两个部分:从图像解耦人脸,以及从人脸解耦ID。已有方法往往将写真图像去噪作为微调任务,从而导致模型无法将注意力准确定位到人脸区域,从而导致Stable Diffusion的原有文生图功能受到影响。FaceChain FACT借鉴换脸算法的串行处理以及区域控制的优势,从结构和训练策略两方面实现从图像中解耦人脸的微调方法。在结构上,不同于已有方法使用并行的交叉注意力机制处理人脸和文本信息,FaceChain FACT采用串行处理的方法作为独立的adapter层插入原始Stable Diffusion的block中,从而将人脸适配作为类似换脸处理的独立步骤作用于去噪过程中,避免了彼此之间的干扰。在训练策略上,FaceChain FACT在原始的MSE损失函数的基础上引入人脸适配增量正则(Face Adapting Incremental Regularization,FAIR)损失函数,控制adapter层人脸适配步骤的特征增量集中于人脸区域。在推理过程中,用户可以通过调整face adapter的权重灵活调节生成效果,在保持Stable Diffusion原有文生图功能的同时,平衡人脸的保真度与泛化性。FAIR损失函数的具体形式如下所示:

![image](resources/FAIR.png)

此外,针对写真人脸可控性和丰富度差的问题,FaceChain FACT提出从人脸解耦ID的训练方法,使得写真过程仅控制人物ID而非整个人脸。首先,为了更针对性提取人脸的ID信息并保持部分关键人脸细节,并且更好适应Stable Diffusion的结构,FaceChain FACT采用在大量人脸数据上预训练的基于Transformer架构的人脸特征提取器[TransFace](https://github.com/DanJun6737/TransFace),抽取其倒数第二层的全部token,后续连接简单的注意力查询模型进行特征投影,从而使得提取的ID特征兼顾上述三点要求。另外,在训练过程中,FaceChain FACT使用Classifier Free Guidance(CFG)的方法,对相同ID对不同人脸写真图片进行随机打乱和舍弃,从而使得模型的输入人脸图片和用于去噪的目标图片可能具有同ID的不同人脸,以进一步避免模型过拟合于人脸的非ID信息。FaceChain FACT对FaceChain海量的精美风格以及姿态控制等功能具有丝滑的兼容能力,生成写真图像如下所示。

![image](resources/generated_examples.png)   

## 模型列表

FaceChain使用的模型链接:

[1]  人脸识别模型TransFace:https://www.modelscope.cn/models/iic/cv_vit_face-recognition

[2]  人脸检测+关键点模型DamoFD:https://modelscope.cn/models/damo/cv_ddsar_face-detection_iclr23-damofd

[3]  人体解析模型M2FP:https://modelscope.cn/models/damo/cv_resnet101_image-multiple-human-parsing

[4]  人像美肤模型ABPN:https://www.modelscope.cn/models/damo/cv_unet_skin_retouching_torch

[5]  人脸融合模型:https://www.modelscope.cn/models/damo/cv_unet_face_fusion_torch

[6]  FaceChain FACT使用模型:https://www.modelscope.cn/models/yucheng1996/FaceChain-FACT

[7]  人脸属性识别模型FairFace:https://modelscope.cn/models/damo/cv_resnet34_face-attribute-recognition_fairface

# 更多信息

- [ModelScope library](https://github.com/modelscope/modelscope/)

  ModelScope Library是一个托管于github上的模型生态仓库,隶属于达摩院魔搭项目。

- [贡献模型到ModelScope](https://modelscope.cn/docs/ModelScope%E6%A8%A1%E5%9E%8B%E6%8E%A5%E5%85%A5%E6%B5%81%E7%A8%8B%E6%A6%82%E8%A7%88)

# License

This project is licensed under the [Apache License (Version 2.0)](https://github.com/modelscope/modelscope/blob/master/LICENSE).



================================================
FILE: app.py
================================================
# Copyright (c) Alibaba, Inc. and its affiliates.
import enum
import os
import json
import shutil
import slugify
import time
import cv2
import gradio as gr
import numpy as np
import torch
from glob import glob
import platform
from PIL import Image
from importlib.util import find_spec
from facechain.inference_fact import GenPortrait
from facechain.inference_inpaint_fact import GenPortrait_inpaint
from facechain.utils import snapshot_download, check_ffmpeg, project_dir, join_worker_data_dir
from train_style.demo import set_img, init_tag, cut_img, train_lora, set_prompt
from facechain.constants import neg_prompt as neg, pos_prompt_with_cloth, pos_prompt_with_style, \
    pose_examples, base_models, tts_speakers_map


inference_done_count = 0
character_model = 'ly261666/cv_portrait_model'
BASE_MODEL_MAP = {
    "leosamsMoonfilm_filmGrain20": "写实模型(Realistic sd_1.5 model)",
    "MajicmixRealistic_v6": "\N{fire}写真模型(Photorealistic sd_1.5 model)",
}


class UploadTarget(enum.Enum):
    PERSONAL_PROFILE = 'Personal Profile'
    LORA_LIaBRARY = 'LoRA Library'


# utils
def concatenate_images(images):
    heights = [img.shape[0] for img in images]
    max_width = sum([img.shape[1] for img in images])

    concatenated_image = np.zeros((max(heights), max_width, 3), dtype=np.uint8)
    x_offset = 0
    for img in images:
        concatenated_image[0:img.shape[0], x_offset:x_offset + img.shape[1], :] = img
        x_offset += img.shape[1]
    return concatenated_image


def select_function(evt: gr.SelectData):
    name = evt.value[1] if isinstance(evt.value, (tuple, list)) else evt.value
    matched = list(filter(lambda item: name == item['name'], styles))
    style = matched[0]
    return gr.Text.update(value=style['name'], visible=True)

def select_function_multi(evt: gr.SelectData):
    tag = evt.value[1]
    impath = evt.value[0]
    return gr.Text.update(value=impath), gr.Text.update(value=tag)

def get_selected_image(state_image_list, evt: gr.SelectData):
    return state_image_list[evt.index]

def upload_file(files, current_files):
    file_paths = [file_d['name'] for file_d in current_files] + [file.name for file in files]
    return file_paths


def update_prompt(style_model, style_choice, uuid):
    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    if style_choice == 0:
        matched = list(filter(lambda item: style_model == item['name'], styles))
        style = matched[0]
        pos_prompt = generate_pos_prompt(style['name'], style['add_prompt_style'])
        multiplier_style = style['multiplier_style']
        multiplier_human = style['multiplier_human']
    else:
        f = open(f'{project_dir}/workspace/{uuid}/style_lora/{style_model}/add_prompt_style.txt', 'r')
        add_prompt_style = f.read()
        f.close()
        pos_prompt = pos_prompt_with_style.format(add_prompt_style)
        multiplier_style = 0.8
        
    return gr.Textbox.update(value=pos_prompt), \
           gr.Slider.update(value=multiplier_style)


def update_pose_model(pose_image, pose_model):
    if pose_image is None:
        return gr.Radio.update(value=pose_models[0]['name']), gr.Image.update(visible=False)
    else:
        if pose_model == 0:
            pose_model = 1
        pose_res_img = preprocess_pose(pose_image)
        return gr.Radio.update(value=pose_models[pose_model]['name']), gr.Image.update(value=pose_res_img, visible=True)



def generate_pos_prompt(style_model, prompt_cloth):
    if style_model is not None:
        matched = list(filter(lambda style: style_model == style['name'], styles))
        if len(matched) == 0:
            raise ValueError(f'styles not found: {style_model}')
        matched = matched[0]
        if matched['model_id'] is None:
            pos_prompt = pos_prompt_with_cloth.format(prompt_cloth)
        else:
            pos_prompt = pos_prompt_with_style.format(matched['add_prompt_style'])
    else:
        pos_prompt = pos_prompt_with_cloth.format(prompt_cloth)
    return pos_prompt


def launch_pipeline(uuid,
                    style_choice,
                    pos_prompt,
                    neg_prompt=None,
                    user_images=None,
                    num_images=1,
                    style_model=None,
                    lora_choice=None,
                    multiplier_style=0.35,
                    pose_image=None,
                    use_face_swap=0
                    ):
    
    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    
    # Check style model
    if style_choice == None:
        raise gr.Error('请选择风格模型(Please select the style model)!')
    
    if style_model == None and lora_choice == 'preset':
        raise gr.Error('请选择风格模型(Please select the style model)!')
    
    before_queue_size = 0
    before_done_count = inference_done_count
    
    if style_choice == 0:
        matched = list(filter(lambda item: style_model == item['name'], styles))
        if len(matched) == 0:
            raise ValueError(f'styles not found: {style_model}')
        matched = matched[0]
        style_model = matched['name']

    if lora_choice == 'preset':
        if style_choice == 1:
            style_model_path = os.path.join(f'{project_dir}/workspace/{uuid}/style_lora', style_model, 'lora_weights.safetensors')
            base_model_index = 0
        elif matched['model_id'] is None:
            style_model_path = None
            base_model_index = 0
        else:
            model_dir = snapshot_download(matched['model_id'], revision=matched['revision'])
            style_model_path = os.path.join(model_dir, matched['bin_file'])
            base_model_index = matched['base_model_index']
    else:
        print(f'uuid: {uuid}')
        temp_lora_dir = join_worker_data_dir(uuid, 'temp_lora')
        file_name = lora_choice
        print(lora_choice.split('.')[-1], os.path.join(temp_lora_dir, file_name))
        if lora_choice.split('.')[-1] != 'safetensors' or not os.path.exists(os.path.join(temp_lora_dir, file_name)):
            raise ValueError(f'Invalid lora file: {lora_file.name}')
        style_model_path = os.path.join(temp_lora_dir, file_name)
        base_model_index = 1

    num_images = min(6, num_images)
    print('base model index: ', base_model_index)
    
    outputs = gen_portrait(use_face_swap, num_images, base_model_index, style_model_path, pos_prompt, neg_prompt, user_images[0]['name'], pose_image, multiplier_style)

    outputs_RGB = []
    for out_tmp in outputs:
        outputs_RGB.append(cv2.cvtColor(out_tmp, cv2.COLOR_BGR2RGB))
    
    if len(outputs) > 0:
        yield ["生成完毕(Generation done)!", outputs_RGB]
    else:
        yield ["生成失败, 请重试(Generation failed, please retry)!", outputs_RGB]


def launch_pipeline_inpaint(uuid,
                            user_images,
                            num_faces=1,
                            selected_face=1,
                            template_image=None,
                            use_face_swap=0):

    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    
#    if isinstance(user_image, str):
#        if len(user_image) == 0:
#            raise gr.Error('请选择一张用户图像(Please select 1 user image)')

    if isinstance(template_image, str):
        if len(template_image) == 0:
            raise gr.Error('请选择一张模板(Please select 1 template)')

    multiplier_style = 0.05
    strength = 0.6
    output_img_size = 512

    pos_prompt = 'raw photo, masterpiece, simple background, solo, medium shot, high detail face, photorealistic, best quality, wearing T-shirt'
    neg_prompt = 'nsfw, paintings, sketches, (worst quality:2), (low quality:2) ' \
                'lowers, normal quality, ((monochrome)), ((grayscale)), logo, word, character'

    outputs = gen_portrait_inpaint(use_face_swap, template_image,
                 strength,
                 output_img_size,
                 num_faces,
                 selected_face,
                 pos_prompt,
                 neg_prompt,
                 user_images[0]['name'])
    
    outputs_RGB = []
    for out_tmp in outputs:
        outputs_RGB.append(cv2.cvtColor(out_tmp, cv2.COLOR_BGR2RGB))

    if len(outputs) > 0:
        yield ["生成完毕(Generation done)!", outputs_RGB]
    else:
        yield ["生成失败,请重试(Generation failed, please retry)!", outputs_RGB]

        
def update_lora_choice(uuid):
    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    print("uuid: ", uuid)
    temp_lora_dir = join_worker_data_dir(uuid, 'temp_lora')
    if not os.path.exists(temp_lora_dir):
        os.makedirs(temp_lora_dir)
    
    lora_list = sorted(os.listdir(temp_lora_dir))
    lora_list = ["preset"] + lora_list
    
    return gr.Dropdown.update(choices=lora_list, value="preset")

def upload_lora_file(uuid, lora_file):
    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    print("uuid: ", uuid)
    temp_lora_dir = join_worker_data_dir(uuid, 'temp_lora')
    if not os.path.exists(temp_lora_dir):
        os.makedirs(temp_lora_dir)
    shutil.copy(lora_file.name, temp_lora_dir)
    filename = os.path.basename(lora_file.name)
    newfilepath = os.path.join(temp_lora_dir, filename)
    print("newfilepath: ", newfilepath)
    
    lora_list = sorted(os.listdir(temp_lora_dir))
    lora_list = ["preset"] + lora_list
    
    return gr.Dropdown.update(choices=lora_list, value=filename)


def clear_lora_file(uuid, lora_file):
    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    
    return gr.Dropdown.update(value="preset")


def change_lora_choice(lora_choice):
    
    if lora_choice == 'preset':
        return gr.Gallery.update(value=[(item["img"], item["name"]) for item in styles], visible=True), \
               gr.Text.update(value=style_list[0])
    else:
        return gr.Gallery.update(visible=False), gr.Text.update(visible=False)


def change_style_choice(uuid, style_choice):
    if not uuid:
        if os.getenv("MODELSCOPE_ENVIRONMENT") == 'studio':
            raise gr.Error("请登陆后使用! (Please login first)")
        else:
            uuid = 'qw'
    out_path = f'{project_dir}/workspace/{uuid}/style_lora'
    if os.path.exists(out_path):
        choices = os.listdir(out_path)
    else:
        choices = []
    
    if style_choice == 0:
        return gr.Gallery.update(visible=True), gr.Radio.update(choices=choices, visible=False)
    else:
        return gr.Gallery.update(visible=False), gr.Radio.update(choices=choices, visible=True)

def select_trained_style(trained_styles):
    return gr.Text.update(value=trained_styles)

def get_tag(imgs):
    results = []
    for i in range(len(imgs)):
        file, old_prompt = imgs[i]
        img_path = file['name']
        img = Image.open(img_path)
        result = tag_model.tag(img, threshold=0.7)
        results.append([img_path, result])
        imgs[i][1] = result

    return gr.Gallery.update(value=results, visible=True)

def modify_tag(gallery, impath, tag):
    results = []
    for item in gallery:
        if item[0]['data'] == impath:
            results.append([item[0]['name'], tag])
        else:
            results.append([item[0]['name'], item[1]])
    return gr.Gallery.update(value=results)
    
def inference_input():
    with gr.Blocks() as demo:
        uuid = gr.Text(label="modelscope_uuid", visible=False)
        
        with gr.Row():
            with gr.Column():
                with gr.Box():
                    style_choice = gr.Radio(label="风格模型来源(Whether enhancing face similarity)", choices=["预设风格(Preset styles)", "用户训练风格(User-trained styles)"], type="index", value=None)
                    style_model = gr.Text(label='请选择一种风格(Select a style from the pics below):', interactive=False)
                    trained_styles = gr.Radio(label='用户训练风格列表(User-trained style list)', choices=[], value=None, type="value", visible=False)
                    
                    if find_spec('webui'):
                        gallery = gr.Gallery(value=[(item["img"], item["name"]) for item in styles],
                                            label="风格(Style)",
                                            allow_preview=False,
                                            elem_id="gallery",
                                            show_share_button=False,
                                            visible=True).style(columns=6, rows=2)
                    else:
                        gallery = gr.Gallery(value=[(item["img"], item["name"]) for item in styles],
                                            label="风格(Style)",
                                            allow_preview=False,
                                            elem_id="gallery",
                                            show_share_button=False,
                                            visible=True).style(columns=6, object_fit='contain', height=600)
                
                with gr.Box():
                    gr.Markdown('请上传一张用户人像图片(Please upload a user image):')
                    user_images = gr.Gallery(label="输入用户图片(User image)", show_label=True)
            
                    with gr.Row(elem_id="container_row"):
                        upload_button = gr.UploadButton("选择图片上传(Upload photos)", file_types=["image"],
                                                                    file_count="multiple")
                        clear_button = gr.Button("清空图片(Clear photos)")

                    clear_button.click(fn=lambda: [], inputs=None, outputs=user_images)
                    upload_button.upload(upload_file, inputs=[upload_button, user_images], outputs=user_images,
                                                     queue=False)

                with gr.Accordion("高级选项(Advanced Options)", open=False):
                    # upload one lora file and show the name or path of the file
                    with gr.Accordion("上传LoRA文件(Upload LoRA file)", open=False):
                        with gr.Row():
                            lora_choice = gr.Dropdown(choices=["preset"], type="value", value="preset", label="LoRA文件(LoRA file)", visible=True)
                            update_button = gr.Button('刷新风格LoRA列表并切换为预设风格(Refresh style LoRAs and switch to preset styles)')
                            
                        lora_file = gr.File(
                            value=None,
                            label="上传LoRA文件(Upload LoRA file)",
                            type="file",
                            file_types=[".safetensors"],
                            file_count="single",
                            visible=True,
                        )
                        
                    pos_prompt = gr.Textbox(label="提示语(Prompt)", lines=3,
                                            value=generate_pos_prompt(None, styles[0]['add_prompt_style']),
                                            interactive=True)
                    neg_prompt = gr.Textbox(label="负向提示语(Negative Prompt)", lines=3,
                                            value="",
                                            interactive=True)
                    if neg_prompt.value == '' :
                        neg_prompt.value = neg
                    multiplier_style = gr.Slider(minimum=0, maximum=1, value=0.25,
                                                 step=0.05, label='风格权重(Multiplier style)')
                    
                    with gr.Accordion("姿态控制(Pose control)", open=True):
                        with gr.Row():
                            pose_image = gr.Image(source='upload', type='filepath', label='姿态图片(Pose image)', height=250)
                            pose_res_image = gr.Image(source='upload', interactive=False, label='姿态结果(Pose result)', visible=False, height=250)
                        gr.Examples(pose_examples['man'], inputs=[pose_image], label='男性姿态示例')
                        gr.Examples(pose_examples['woman'], inputs=[pose_image], label='女性姿态示例')

                with gr.Box():
                    num_images = gr.Number(
                        label='生成图片数量(Number of photos)', value=1, precision=1, minimum=1, maximum=6)
                    use_face_swap = gr.Radio(label="是否使用人脸相似度增强(Whether enhancing face similarity)", choices=["否(No)", "是(Yes)"], type="index", value="是(Yes)")
                    gr.Markdown('''
                    注意:
                    - 最多支持生成6张图片!(You may generate a maximum of 6 photos at one time!)
                    - 可上传在定义LoRA文件使用, 否则默认使用风格模型的LoRA。(You may upload custome LoRA file, otherwise the LoRA file of the style model will be used by deault.)
                    - 使用自定义LoRA文件需手动输入prompt, 否则可能无法正常触发LoRA文件风格。(You shall provide prompt when using custom LoRA, otherwise desired LoRA style may not be triggered.)
                        ''')

        with gr.Row(elem_id="container_row"):
            display_button = gr.Button('开始生成(Start!)', variant='primary')

        with gr.Box():
            infer_progress = gr.Textbox(label="生成进度(Progress)", value="当前无生成任务(No task)", interactive=False)
        with gr.Box():
            gr.Markdown('生成结果(Result)')
            output_images = gr.Gallery(label='Output', show_label=False).style(columns=3, rows=2, height=600,
                                                                               object_fit="contain")
        
        style_choice.change(fn=change_style_choice, inputs=[uuid, style_choice], outputs=[gallery, trained_styles], queue=False)
        gallery.select(select_function, None, style_model, queue=False)
        trained_styles.change(select_trained_style, inputs=[trained_styles], outputs=[style_model], queue=False)
        
        lora_choice.change(fn=change_lora_choice, inputs=[lora_choice], outputs=[gallery, style_model], queue=False)
        
        lora_file.upload(fn=upload_lora_file, inputs=[uuid, lora_file], outputs=[lora_choice], queue=False)
        lora_file.clear(fn=clear_lora_file, inputs=[uuid, lora_file], outputs=[lora_choice], queue=False)
        
        style_model.change(update_prompt, [style_model, style_choice, uuid], [pos_prompt, multiplier_style], queue=False)
        
        display_button.click(fn=launch_pipeline,
                             inputs=[uuid, style_choice, pos_prompt, neg_prompt, user_images, num_images, style_model, lora_choice, multiplier_style,
                                     pose_image, use_face_swap],
                             outputs=[infer_progress, output_images])
        
        update_button.click(fn=update_lora_choice, inputs=[uuid], outputs=[lora_choice], queue=False)

    return demo


def inference_inpaint():
    preset_template = glob(os.path.join(f'{project_dir}/inpaint_template/*.jpg'))
    with gr.Blocks() as demo:
        uuid = gr.Text(label="modelscope_uuid", visible=False)
        # Initialize the GUI

        with gr.Row():
            with gr.Column():
                with gr.Box():
                    gr.Markdown('请选择或上传模板图片(Please select or upload a template image):')
                    template_image_list = [[i] for idx, i in enumerate(preset_template)]
                    print(template_image_list)
                    template_image = gr.Image(source='upload', type='filepath', label='模板图片(Template image)')
                    gr.Examples(template_image_list, inputs=[template_image], label='模板示例(Template examples)')
                
                with gr.Box():
                    gr.Markdown('请上传用户人像图片(Please upload a user image):')
                    user_images = gr.Gallery(label="输入用户图片(User image)", show_label=True)
            
                    with gr.Row(elem_id="container_row"):
                        upload_button = gr.UploadButton("选择图片上传(Upload photos)", file_types=["image"],
                                                                    file_count="multiple")
                        clear_button = gr.Button("清空图片(Clear photos)")

                    clear_button.click(fn=lambda: [], inputs=None, outputs=user_images)
                    upload_button.upload(upload_file, inputs=[upload_button, user_images], outputs=user_images,
                                                     queue=False)
                    
                num_faces = gr.Number(minimum=1, value=1, precision=1, label='照片中的人脸数目(Number of Faces)')
                selected_face = gr.Number(minimum=1, value=1, precision=1, label='选择重绘的人脸编号,按从左至右的顺序(Index of Face for inpainting, counting from left to right)')
                use_face_swap = gr.Radio(label="是否使用人脸相似度增强(Whether enhancing face similarity)", choices=["否(No)", "是(Yes)"], type="index", value="是(Yes)")

        with gr.Row(elem_id="container_row"):
            display_button = gr.Button('开始生成(Start Generation)', variant='primary')
        with gr.Box():
            infer_progress = gr.Textbox(
                label="生成(Generation Progress)",
                value="No task currently",
                interactive=False
            )
        with gr.Box():
            gr.Markdown('生成结果(Generated Results)')
            output_images = gr.Gallery(
                label='输出(Output)',
                show_label=False
            ).style(columns=3, rows=2, height=600, object_fit="contain")

        display_button.click(
            fn=launch_pipeline_inpaint,
            inputs=[uuid, user_images, num_faces, selected_face, template_image, use_face_swap],
            outputs=[infer_progress, output_images]
        )

    return demo


def train_input():
    with gr.Blocks() as demo:
        uuid = gr.Text(label="modelscope_uuid", visible=False)
        
        output_model_name = gr.Text(label='风格lora模型名称(Style lora name)', visible=True)
        
        gallery = gr.Gallery(type='image', label='图片列表(Photos)', height=250, columns=8, visible=True)
        with gr.Row(elem_id="container_row"):
            upload_button = gr.UploadButton("选择图片上传(Upload photos)", file_types=["image"], file_count="multiple")
        train_folder = gr.Text(label='训练文件夹(Train folder)', visible=False)

        with gr.Row(elem_id="container_row"):
            tag_btn = gr.Button(value='开始打标签(Tag prompt)')
            rank = gr.Number(label='rank', direction='row', value=32, step=1)
            num_train_epochs = gr.Number(label='num_train_epochs', direction='row', value=200, step=1)
        
        with gr.Accordion("手动修改标签(Manually modify tags)", open=False):
            with gr.Row(elem_id="container_row"):
                current_pth = gr.Text(label='当前图片(Current image)', value=None, visible=False)
                current_tag = gr.Text(label='当前标签(Current tags)', value=None, visible=True)
                mod_btn = gr.Button(value='提交修改(Submit modifications)')

        prompt_input = gr.Text(label='风格触发词(Trigger word)', visible=True)
        with gr.Row(elem_id="container_row"):
            btn = gr.Button(value='开始训练(Start train)', interactive=False)
        output_lora = gr.Files(label='输出模型(Output model)', type='file', visible=True)
        output_prompt = gr.Text(label='风格提示词(Style prompt)', visible=False)

        # 完成待训练图片上传
        upload_button.upload(fn=set_img, inputs=[upload_button, uuid, output_model_name], outputs=[train_folder, gallery, btn])
        # 完成公用提示词输入
        prompt_input.input(fn=set_prompt, outputs=[btn])
        # 开始给图片打标签(prompt)
        tag_btn.click(fn=get_tag, inputs=[gallery], outputs=[gallery])
        # 获取图片标签
        gallery.select(select_function_multi, None, [current_pth, current_tag], queue=False)
        # 手动修改标签
        mod_btn.click(fn=modify_tag, inputs=[gallery, current_pth, current_tag], outputs=[gallery], queue=False)
        # 开始训练
        btn.click(fn=train_lora, inputs=[uuid, output_model_name, prompt_input, train_folder, gallery, rank, num_train_epochs], outputs=[output_lora, output_prompt])
    return demo


styles = []
style_list = []
base_models_reverse = [base_models[1], base_models[0]]
for base_model in base_models_reverse:
    folder_path = f"{os.path.dirname(os.path.abspath(__file__))}/styles/{base_model['name']}"
    files = os.listdir(folder_path)
    files.sort()
    for file in files:
        file_path = os.path.join(folder_path, file)
        with open(file_path, "r", encoding='utf-8') as f:
            data = json.load(f)
            if data['img'][:2] == './':
                data['img'] = f"{project_dir}/{data['img'][2:]}"
                if base_model['name'] == 'leosamsMoonfilm_filmGrain20':
                    data['base_model_index'] = 0
                else:
                    data['base_model_index'] = 1
            style_list.append(data['name'])
            styles.append(data)

for style in styles:
    print(style['name'])
    if style['model_id'] is not None:
        model_dir = snapshot_download(style['model_id'], revision=style['revision'])

gen_portrait = GenPortrait()
gen_portrait_inpaint = GenPortrait_inpaint()
tag_model = init_tag()

with open(
        os.path.join(os.path.dirname(__file__), 'main.css'), "r",
        encoding="utf-8") as f:
    MAIN_CSS_CODE = f.read()

with gr.Blocks(css=MAIN_CSS_CODE, theme=gr.themes.Soft()) as demo:
    if find_spec('webui'):
        # if running as a webui extension, don't display banner self-advertisement
        gr.Markdown("# <center> \N{fire} FaceChain-FACT Portrait Generation (\N{whale} [Github star it here](https://github.com/modelscope/facechain/tree/main) \N{whale})</center>")
    else:
        gr.Markdown("# <center> \N{fire} FaceChain-FACT Portrait Generation ([Github star it here](https://github.com/modelscope/facechain/tree/main) \N{whale},   [API](https://help.aliyun.com/zh/dashscope/developer-reference/facechain-quick-start) \N{whale})</center>")
    gr.Markdown("##### <center> 本项目仅供学习交流,请勿将模型及其制作内容用于非法活动或违反他人隐私的场景。(This project is intended solely for the purpose of technological discussion, and should not be used for illegal activities and violating privacy of individuals.)</center>")
    with gr.Tabs():
        with gr.TabItem('\N{party popper}免训练无限风格形象写真(Infinite Style Portrait)'):
            inference_input()
        with gr.TabItem('\N{party popper}免训练固定模板形象写真(Fixed Templates Portrait)'):
            inference_inpaint()
        with gr.TabItem('\N{party popper}自定义风格模型训练(Style Model Training)'):
            train_input()

if __name__ == "__main__":
    demo.queue(status_update_rate=1).launch(share=False)


================================================
FILE: face_adapter/__init__.py
================================================
from .face_adapter_v1 import FaceAdapter_v1, Face_Extracter_v1

================================================
FILE: face_adapter/face_adapter_v1.py
================================================
import os
from typing import List

import torch
from diffusers import StableDiffusionPipeline
from diffusers.pipelines.controlnet import MultiControlNetModel
from PIL import Image

from torch.distributed import get_rank
import torch.nn as nn
import numpy as np
from torchvision.transforms import transforms

from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
import cv2
import math

from .utils import is_torch2_available
if is_torch2_available():
    from .face_attention_processor_v1 import FaceAttnProcessor2_0 as FaceAttnProcessor, AttnProcessor2_0 as AttnProcessor, CNAttnProcessor2_0 as CNAttnProcessor
else:
    from .face_attention_processor_v1 import FaceAttnProcessor, AttnProcessor, CNAttnProcessor
from . import vit
from . import face_preprocess

def detect(image, face_detection):
    result_det = face_detection(image)
    confs = result_det['scores']
    idx = np.argmax(confs)
    pts = result_det['keypoints'][idx]
    points_vec = np.array(pts)
    points_vec = points_vec.reshape(5,2)
    return points_vec

def get_mask_head(result):
    masks = result['masks']
    scores = result['scores']
    labels = result['labels']
    img_shape = masks[0].shape
    mask_hair = np.zeros(img_shape)
    mask_face = np.zeros(img_shape)
    mask_human = np.zeros(img_shape)
    for i in range(len(labels)):
        if scores[i] > 0.8:
            if labels[i] == 'Face':
                if np.sum(masks[i]) > np.sum(mask_face):
                    mask_face = masks[i]
            elif labels[i] == 'Human':
                if np.sum(masks[i]) > np.sum(mask_human):
                    mask_human = masks[i]
            elif labels[i] == 'Hair':
                if np.sum(masks[i]) > np.sum(mask_hair):
                    mask_hair = masks[i]
    mask_head = np.clip(mask_hair + mask_face, 0, 1)
    ksize = max(int(np.sqrt(np.sum(mask_face)) / 20), 1)
    kernel = np.ones((ksize, ksize))
    mask_head = cv2.dilate(mask_head, kernel, iterations=1) * mask_human
    _, mask_head = cv2.threshold((mask_head * 255).astype(np.uint8), 127, 255, cv2.THRESH_BINARY)
    contours, hierarchy = cv2.findContours(mask_head, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    area = []
    for j in range(len(contours)):
        area.append(cv2.contourArea(contours[j]))
    max_idx = np.argmax(area)
    mask_head = np.zeros(img_shape).astype(np.uint8)
    cv2.fillPoly(mask_head, [contours[max_idx]], 255)
    mask_head = mask_head.astype(np.float32) / 255 
    mask_head = np.clip(mask_head + mask_face, 0, 1)
    mask_head = np.expand_dims(mask_head, 2)
    return mask_head

def align(image, points_vec):
    warped = face_preprocess.preprocess(np.array(image)[:,:,::-1], bbox=None, landmark=points_vec, image_size='112, 112')
    return Image.fromarray(warped[:,:,::-1])

def face_image_preprocess(image, segmentation_pipeline, face_detection):
    result = segmentation_pipeline(image)
    mask_head = get_mask_head(result)
    image = Image.fromarray((np.array(image) * mask_head).astype(np.uint8))
    points_vec = detect(image, face_detection)
    image = align(image, points_vec)    
    return image

class Face_Transformer(nn.Module):
    def __init__(self, name='vits', weight='./ms1mv2_model_TransFace_S.pt'):
        super().__init__()

        # FR transformer
        self.net = vit.VisionTransformer(img_size=112, 
                                         patch_size=9, 
                                         num_classes=512, 
                                         embed_dim=512, 
                                         depth=12,
                                         num_heads=8, 
                                         drop_path_rate=0.1, 
                                         norm_layer="ln", 
                                         mask_ratio=0.1)
        self.net.load_state_dict(torch.load(weight, map_location='cpu'))
        self.net.eval()



    @torch.no_grad()                                    
    def forward(self, img):
        local_fac_rep, global_fac_rep = self.net(img)
        global_fac_rep = global_fac_rep.unsqueeze(1)
        return local_fac_rep, global_fac_rep


def FeedForward(dim, mult=4):
    inner_dim = int(dim * mult)
    return nn.Sequential(
        nn.LayerNorm(dim),
        nn.Linear(dim, inner_dim, bias=False),
        nn.GELU(),
        nn.Linear(inner_dim, dim, bias=False),
    )
    
    
def reshape_tensor(x, heads):
    bs, length, width = x.shape
    #(bs, length, width) --> (bs, length, n_heads, dim_per_head)
    x = x.view(bs, length, heads, -1)
    # (bs, length, n_heads, dim_per_head) --> (bs, n_heads, length, dim_per_head)
    x = x.transpose(1, 2)
    # (bs, n_heads, length, dim_per_head) --> (bs*n_heads, length, dim_per_head)
    x = x.reshape(bs, heads, length, -1)
    return x


class PerceiverAttention(nn.Module):
    def __init__(self, *, dim, dim_head=64, heads=8):
        super().__init__()
        self.scale = dim_head**-0.5
        self.dim_head = dim_head
        self.heads = heads
        inner_dim = dim_head * heads

        self.norm1 = nn.LayerNorm(dim)
        self.norm2 = nn.LayerNorm(dim)

        self.to_q = nn.Linear(dim, inner_dim, bias=False)
        self.to_kv = nn.Linear(dim, inner_dim * 2, bias=False)
        self.to_out = nn.Linear(inner_dim, dim, bias=False)


    def forward(self, x, latents):
        """
        Args:
            x (torch.Tensor): image features
                shape (b, n1, D)
            latent (torch.Tensor): latent features
                shape (b, n2, D)
        """
        x = self.norm1(x)
        latents = self.norm2(latents)
        
        b, l, _ = latents.shape

        q = self.to_q(latents)
        kv_input = torch.cat((x, latents), dim=-2)
        k, v = self.to_kv(kv_input).chunk(2, dim=-1)
        
        q = reshape_tensor(q, self.heads)
        k = reshape_tensor(k, self.heads)
        v = reshape_tensor(v, self.heads)

        # attention
        scale = 1 / math.sqrt(math.sqrt(self.dim_head))
        weight = (q * scale) @ (k * scale).transpose(-2, -1) # More stable with f16 than dividing afterwards
        weight = torch.softmax(weight.float(), dim=-1).type(weight.dtype)
        out = weight @ v
        
        out = out.permute(0, 2, 1, 3).reshape(b, l, -1)

        return self.to_out(out)

# 1x144x1280 -> 1x16x768
class Face_Prj_Resampler(nn.Module):
    def __init__(
        self,
        dim=1024,
        depth=4,
        dim_head=64,
        heads=12,
        num_queries=16,
        embedding_dim=512,
        output_dim=768,
        ff_mult=4,
    ):
        super().__init__()
        
        self.latents = nn.Parameter(torch.randn(1, num_queries, dim) / dim**0.5)
        
        self.proj_in = nn.Linear(embedding_dim, dim)

        self.proj_out = nn.Linear(dim, output_dim)
        self.norm_out = nn.LayerNorm(output_dim)
        
        self.layers = nn.ModuleList([])
        for _ in range(depth):
            self.layers.append(
                nn.ModuleList(
                    [
                        PerceiverAttention(dim=dim, dim_head=dim_head, heads=heads),
                        FeedForward(dim=dim, mult=ff_mult),
                    ]
                )
            )

    def forward(self, x):
        
        latents = self.latents.repeat(x.size(0), 1, 1)
        
        x = self.proj_in(x)
        
        for attn, ff in self.layers:
            latents = attn(x, latents) + latents
            latents = ff(latents) + latents
        
        # print(latents.shape) # 16,1024
        latents = self.proj_out(latents)
        return self.norm_out(latents)

    
    
class Face_Extracter_v1(nn.Module):
    def __init__(self, fr_weight_path, fc_weight_path):
        super().__init__()

        self.face_transformer = Face_Transformer(weight=fr_weight_path)
        self.face_prj_wofc = Face_Prj_Resampler(dim=1024, depth=4, dim_head=64, heads=12, num_queries=16, embedding_dim=512, output_dim=768, ff_mult=4)
        # now the weight is parameters of both adapter and fc
        weights = torch.load(fc_weight_path)
        # keep fc parameter
        weights_fc = {key.replace('local_fac_prj.', ''): value for key, value in weights.items() if key.startswith('local_fac_prj')}
        self.face_prj_wofc.load_state_dict(weights_fc, strict=True)
        self.face_prj_wofc.eval()

    def forward(self, face_img):

        avr_face_rep, _ = self.face_transformer(face_img)
        face_g_embed = self.face_prj_wofc(avr_face_rep)
        neg_face_g_embed = self.face_prj_wofc(torch.zeros_like(avr_face_rep))
        
        num_ims, seq_len, _ = face_g_embed.shape
        face_g_embed = face_g_embed.view(1, num_ims * seq_len, -1)
        neg_face_g_embed = neg_face_g_embed.view(1, num_ims * seq_len, -1)
        
        return face_g_embed, neg_face_g_embed

class Identity(nn.Module):
    def __init__(self):
        super().__init__()
    
    def forward(self, x):
        return x

        
class FaceAdapter_v1:
    
    def __init__(self, sd_pipe, face_detection, segmentation_pipeline, face_extracter, ckpt, device, cfg_face=False):
        
        self.device = device
        self.ckpt = ckpt
        
        # self.face_extracter = Face_Extracter(fr_weight_path='face_adapter/ms1mv2_model_TransFace_S.pt', fc_weight_path='face_adapter/mirror_adapter_20_film.ckpt').to(self.device)
        # self.face_detection = pipeline(task=Tasks.face_detection, model='damo/cv_resnet50_face-detection_retinaface')
        # self.segmentation_pipeline = pipeline(task=Tasks.image_segmentation, model='damo/cv_resnet101_image-multiple-human-parsing')
        self.face_extracter = face_extracter.to(self.device)
        self.face_detection = face_detection
        self.segmentation_pipeline = segmentation_pipeline
        
        self.pipe = sd_pipe.to(self.device)
        self.scale = 1.0
        self.delayed_face_condition = 0.0
        self.cfg_face = cfg_face
        
        self.set_adapter()        
        self.load_adapter()
        
        
    def set_adapter(self):
        unet = self.pipe.unet
        
        layer_norms = {}
        for i in range(3):
            for j in range(2):
                ln = unet.down_blocks[i].attentions[j].transformer_blocks[0].norm2
                layer_norms['down_blocks.{}.attentions.{}.transformer_blocks.0.attn2.processor'.format(i,j)] = ln
                unet.down_blocks[i].attentions[j].transformer_blocks[0].norm2 = Identity()
        
        for i in range(3):
            for j in range(3):
                ln = unet.up_blocks[i+1].attentions[j].transformer_blocks[0].norm2
                layer_norms['up_blocks.{}.attentions.{}.transformer_blocks.0.attn2.processor'.format(i+1,j)] = ln
                unet.up_blocks[i+1].attentions[j].transformer_blocks[0].norm2 = Identity()
        
        ln = unet.mid_block.attentions[0].transformer_blocks[0].norm2
        layer_norms['mid_block.attentions.0.transformer_blocks.0.attn2.processor'] = ln
        unet.mid_block.attentions[0].transformer_blocks[0].norm2 = Identity()
        
        
        attn_procs = {}
        for name in unet.attn_processors.keys():
            cross_attention_dim = None if name.endswith("attn1.processor") else unet.config.cross_attention_dim
            if name.startswith("mid_block"):
                hidden_size = unet.config.block_out_channels[-1]
            elif name.startswith("up_blocks"):
                block_id = int(name[len("up_blocks.")])
                hidden_size = list(reversed(unet.config.block_out_channels))[block_id]
            elif name.startswith("down_blocks"):
                block_id = int(name[len("down_blocks.")])
                hidden_size = unet.config.block_out_channels[block_id]
            if cross_attention_dim is None:
                attn_procs[name] = AttnProcessor()
            else:
                attn_procs[name] = FaceAttnProcessor(hidden_size=hidden_size, cross_attention_dim=cross_attention_dim,
                scale=1.0, ln=layer_norms[name]).to(self.device, dtype=torch.float16)
        unet.set_attn_processor(attn_procs)
        if hasattr(self.pipe, "controlnet"):
            if isinstance(self.pipe.controlnet, MultiControlNetModel):
                for controlnet in self.pipe.controlnet.nets:
                    controlnet.set_attn_processor(CNAttnProcessor())
            else:
                self.pipe.controlnet.set_attn_processor(CNAttnProcessor())
        
    def load_adapter(self):
        state_dict = torch.load(self.ckpt, map_location="cpu")
        # crossattn_layers = torch.nn.ModuleList(self.pipe.unet.attn_processors.values())
        new_state_dict = {}
        for k in state_dict.keys():
            if 'processor' in k:
                new_state_dict[k] = state_dict[k]
        self.pipe.unet.load_state_dict(new_state_dict, strict=False)
        
    
    def set_scale(self, scale):
        self.scale = scale
        for attn_processor in self.pipe.unet.attn_processors.values():
            if isinstance(attn_processor, FaceAttnProcessor):
                attn_processor.scale = scale
    
    def set_num_ims(self, num_ims):
        for attn_processor in self.pipe.unet.attn_processors.values():
            if isinstance(attn_processor, FaceAttnProcessor):
                attn_processor.num_ims = num_ims
        if hasattr(self.pipe, "controlnet"):
            if isinstance(self.pipe.controlnet, MultiControlNetModel):
                for controlnet in self.pipe.controlnet.nets:
                    for attn_processor in controlnet.attn_processors.values():
                        if isinstance(attn_processor, CNAttnProcessor):
                            attn_processor.num_ims = num_ims
            else:
                for attn_processor in self.pipe.controlnet.attn_processors.values():
                    if isinstance(attn_processor, CNAttnProcessor):
                        attn_processor.num_ims = num_ims
        
    def generate(
        self,
        face_image=None,
        prompt=None,
        negative_prompt=None,
        num_samples=1,
        seed=None,
        guidance_scale=5.0,
        num_inference_steps=50,
        **kwargs,
    ):
        # self.set_scale(scale)
        
        num_prompts = 1
        delayed_face_condition = self.delayed_face_condition
        
        if prompt is None:
            prompt = "best quality, high quality"
        if negative_prompt is None:
            negative_prompt = "monochrome, lowres, bad anatomy, worst quality, low quality"
            
        if not isinstance(prompt, List):
            prompt = [prompt] * num_prompts
        if not isinstance(negative_prompt, List):
            negative_prompt = [negative_prompt] * num_prompts
        
        print(prompt, negative_prompt, self.scale)
        
        
        # img = torch.rand(1, 3, 112, 112) 
        if isinstance(face_image, Image.Image):
            face_image = [face_image]
            
        num_ims = len(face_image)
        
        self.set_num_ims(num_ims)
        
        resize_images = []
        for face_image_ori in face_image:
            face_image_ori = face_image_preprocess(face_image_ori, self.segmentation_pipeline, self.face_detection)
            # face_image.save('face_image.png')
            face_image_ori = (transforms.PILToTensor()(face_image_ori).float()/255 - 0.5) / 0.5
            resize_images.append(face_image_ori.unsqueeze(0).to(self.device))
        
        
        resize_images = torch.cat(resize_images, dim=0)
        image_prompt_embeds, neg_image_prompt_embeds = self.face_extracter(resize_images)
        
        bs_embed, seq_len, _ = image_prompt_embeds.shape
        image_prompt_embeds = image_prompt_embeds.repeat(1, num_samples, 1)
        image_prompt_embeds = image_prompt_embeds.view(bs_embed * num_samples, seq_len, -1)
        
        neg_image_prompt_embeds = neg_image_prompt_embeds.repeat(1, num_samples, 1)
        neg_image_prompt_embeds = neg_image_prompt_embeds.view(bs_embed * num_samples, seq_len, -1)
        assert(seq_len == 16 * num_ims)
        

        with torch.inference_mode():
            prompt_embeds = self.pipe._encode_prompt(
                prompt, device=self.device, num_images_per_prompt=num_samples, do_classifier_free_guidance=True, negative_prompt=negative_prompt)
            negative_prompt_embeds_, prompt_embeds_ = prompt_embeds.chunk(2)
            prompt_embeds = torch.cat([prompt_embeds_, image_prompt_embeds], dim=1)
            if self.cfg_face:
                negative_prompt_embeds = torch.cat([negative_prompt_embeds_, neg_image_prompt_embeds], dim=1)
            else:
                negative_prompt_embeds = torch.cat([negative_prompt_embeds_, image_prompt_embeds], dim=1)
            
        generator = torch.Generator(self.device).manual_seed(seed) if seed is not None else None
        if delayed_face_condition > 0:
            scale = self.scale
            self.set_scale(0.0)
            latents = self.pipe(
                prompt_embeds=prompt_embeds,
                negative_prompt_embeds=negative_prompt_embeds,
                guidance_scale=guidance_scale,
                num_inference_steps=num_inference_steps,
                generator=generator,
                end_time=delayed_face_condition,
                **kwargs,
            )
            self.set_scale(scale)
            images = self.pipe(
                prompt_embeds=prompt_embeds,
                negative_prompt_embeds=negative_prompt_embeds,
                guidance_scale=guidance_scale,
                num_inference_steps=num_inference_steps,
                generator=generator,
                start_time=delayed_face_condition,
                start_latent=latents,
                **kwargs,
            ).images
        else:
            images = self.pipe(
                prompt_embeds=prompt_embeds,
                negative_prompt_embeds=negative_prompt_embeds,
                guidance_scale=guidance_scale,
                num_inference_steps=num_inference_steps,
                generator=generator,
                **kwargs,
            ).images
        
        return images
    
    
    



================================================
FILE: face_adapter/face_attention_processor_v1.py
================================================
# modified from https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py
import torch
import torch.nn as nn
import torch.nn.functional as F
from inspect import isfunction

def exists(val):
    return val is not None


def uniq(arr):
    return{el: True for el in arr}.keys()


def default(val, d):
    if exists(val):
        return val
    return d() if isfunction(d) else d

class GEGLU(nn.Module):
    def __init__(self, dim_in, dim_out):
        super().__init__()
        self.proj = nn.Linear(dim_in, dim_out * 2)

    def forward(self, x):
        x, gate = self.proj(x).chunk(2, dim=-1)
        return x * F.gelu(gate)

class FeedForward(nn.Module):
    def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.):
        super().__init__()
        inner_dim = int(dim * mult)
        dim_out = default(dim_out, dim)
        project_in = nn.Sequential(
            nn.Linear(dim, inner_dim),
            nn.GELU()
        ) if not glu else GEGLU(dim, inner_dim)

        self.net = nn.Sequential(
            project_in,
            nn.Dropout(dropout),
            nn.Linear(inner_dim, dim_out)
        )

    def forward(self, x):
        return self.net(x)

    
# class SelfAttention(nn.Module):
#     def __init__(self, query_dim, inner_dim, dropout=0.):
#         super().__init__()

#         self.to_q = nn.Linear(query_dim, inner_dim, bias=False)
#         self.to_k = nn.Linear(query_dim, inner_dim, bias=False)
#         self.to_v = nn.Linear(query_dim, inner_dim, bias=False)

#         self.to_out = nn.Sequential(nn.Linear(inner_dim, query_dim), nn.Dropout(dropout))

#     def forward(self, x, attn):
#         query = self.to_q(x) # B*N*(H*C)
#         key = self.to_k(x) # B*N*(H*C)
#         value = self.to_v(x) # B*N*(H*C)
        
#         query = attn.head_to_batch_dim(query)
#         key = attn.head_to_batch_dim(key)
#         value = attn.head_to_batch_dim(value)

#         attention_probs = attn.get_attention_scores(query, key, None)
#         hidden_states = torch.bmm(attention_probs, value)
#         hidden_states = attn.batch_to_head_dim(hidden_states)

#         return self.to_out(hidden_states)

class SelfAttention(nn.Module):
    def __init__(self, query_dim, inner_dim, dropout=0.):
        super().__init__()
        # inner_dim = dim_head * heads
        # self.scale = dim_head ** -0.5
        # self.heads = heads

        self.to_q = nn.Linear(query_dim, inner_dim, bias=False)
        self.to_k = nn.Linear(query_dim, inner_dim, bias=False)
        self.to_v = nn.Linear(query_dim, inner_dim, bias=False)

        self.to_out = nn.Sequential(nn.Linear(inner_dim, query_dim), nn.Dropout(dropout) )

    def forward(self, x, attn):
        q = self.to_q(x) # B*N*(H*C)
        k = self.to_k(x) # B*N*(H*C)
        v = self.to_v(x) # B*N*(H*C)

        B, N, HC = q.shape 
        H = attn.heads
        C = HC // H 
        scale = C ** -0.5

        q = q.view(B,N,H,C).permute(0,2,1,3).reshape(B*H,N,C) # (B*H)*N*C
        k = k.view(B,N,H,C).permute(0,2,1,3).reshape(B*H,N,C) # (B*H)*N*C
        v = v.view(B,N,H,C).permute(0,2,1,3).reshape(B*H,N,C) # (B*H)*N*C

        sim = torch.einsum('b i c, b j c -> b i j', q, k) * scale  # (B*H)*N*N
        attn = sim.softmax(dim=-1) # (B*H)*N*N

        out = torch.einsum('b i j, b j c -> b i c', attn, v) # (B*H)*N*C
        out = out.view(B,H,N,C).permute(0,2,1,3).reshape(B,N,(H*C)) # B*N*(H*C)

        return self.to_out(out)


class AttnProcessor(nn.Module):
    r"""
    Default processor for performing attention-related computations.
    """
    def __init__(
        self,
        hidden_size=None,
        cross_attention_dim=None,
    ):
        super().__init__()

    def __call__(
        self,
        attn,
        hidden_states,
        encoder_hidden_states=None,
        attention_mask=None,
        temb=None,
    ):
        residual = hidden_states

        if attn.spatial_norm is not None:
            hidden_states = attn.spatial_norm(hidden_states, temb)

        input_ndim = hidden_states.ndim

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)

        batch_size, sequence_length, _ = (
            hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
        )
        attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)

        if attn.group_norm is not None:
            hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)

        query = attn.to_q(hidden_states)

        if encoder_hidden_states is None:
            encoder_hidden_states = hidden_states
        elif attn.norm_cross:
            encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)

        key = attn.to_k(encoder_hidden_states)
        value = attn.to_v(encoder_hidden_states)

        query = attn.head_to_batch_dim(query)
        key = attn.head_to_batch_dim(key)
        value = attn.head_to_batch_dim(value)

        attention_probs = attn.get_attention_scores(query, key, attention_mask)
        hidden_states = torch.bmm(attention_probs, value)
        hidden_states = attn.batch_to_head_dim(hidden_states)

        # linear proj
        hidden_states = attn.to_out[0](hidden_states)
        # dropout
        hidden_states = attn.to_out[1](hidden_states)

        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)

        if attn.residual_connection:
            hidden_states = hidden_states + residual

        hidden_states = hidden_states / attn.rescale_output_factor

        return hidden_states

class AttnProcessor2_0(nn.Module):
    r"""
    Default processor for performing attention-related computations.
    """
    def __init__(
        self,
        hidden_size=None,
        cross_attention_dim=None,
    ):
        super().__init__()
        if not hasattr(F, "scaled_dot_product_attention"):
            raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")

    def __call__(
        self,
        attn,
        hidden_states,
        encoder_hidden_states=None,
        attention_mask=None,
        temb=None,
    ):
        residual = hidden_states

        if attn.spatial_norm is not None:
            hidden_states = attn.spatial_norm(hidden_states, temb)

        input_ndim = hidden_states.ndim

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)

        batch_size, sequence_length, _ = (
            hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
        )
        if attention_mask is not None:
            attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
            # scaled_dot_product_attention expects attention_mask shape to be
            # (batch, heads, source_length, target_length)
            attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])

        if attn.group_norm is not None:
            hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)

        query = attn.to_q(hidden_states)

        if encoder_hidden_states is None:
            encoder_hidden_states = hidden_states
        elif attn.norm_cross:
            encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)

        key = attn.to_k(encoder_hidden_states)
        value = attn.to_v(encoder_hidden_states)

        inner_dim = key.shape[-1]
        head_dim = inner_dim // attn.heads

        query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
        key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
        value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)

        # the output of sdp = (batch, num_heads, seq_len, head_dim)
        # TODO: add support for attn.scale when we move to Torch 2.1
        hidden_states = F.scaled_dot_product_attention(
            query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
        )

        hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
        hidden_states = hidden_states.to(query.dtype)

        # linear proj
        hidden_states = attn.to_out[0](hidden_states)
        # dropout
        hidden_states = attn.to_out[1](hidden_states)

        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)

        if attn.residual_connection:
            hidden_states = hidden_states + residual

        hidden_states = hidden_states / attn.rescale_output_factor

        return hidden_states

class FaceAttnProcessor(nn.Module):
    r"""
    Default processor for performing attention-related computations.
    """
    def __init__(
        self,
        hidden_size=None,
        cross_attention_dim=None,
        context_dim=None,
        scale=1.0,
        ln=None
    ):
        super().__init__()
        
        self.hidden_size = hidden_size
        self.cross_attention_dim = cross_attention_dim or hidden_size
        self.scale = scale
        
        self.linear = nn.Linear(cross_attention_dim or hidden_size, hidden_size) # Context -> q

        self.attn = SelfAttention(query_dim=hidden_size, inner_dim=hidden_size)
        self.ff = FeedForward(hidden_size, glu=True)

        self.norm1 = nn.LayerNorm(hidden_size)
        self.norm2 = nn.LayerNorm(hidden_size)
        
        self.ln = ln
        self.num_ims = 1

        self.register_parameter('alpha_attn', nn.Parameter(torch.tensor(0.)) )
        self.register_parameter('alpha_dense', nn.Parameter(torch.tensor(0.)) )


    def __call__(
        self,
        attn,
        hidden_states,
        encoder_hidden_states=None,
        attention_mask=None,
        temb=None,
    ):
        
        # perform gated-self attention:
        residual0 = hidden_states
        assert(attn.rescale_output_factor == 1)
        assert(attn.residual_connection == False)
        
        # hidden_states = hidden_states / attn.rescale_output_factor
        input_ndim = hidden_states.ndim
        

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
        
        if encoder_hidden_states is None:
            encoder_hidden_states = hidden_states
        else:
            # get encoder_hidden_states, ip_hidden_states
            end_pos = encoder_hidden_states.shape[1] - 16 * self.num_ims
            encoder_hidden_states, face_hidden_states = encoder_hidden_states[:, :end_pos, :], encoder_hidden_states[:, end_pos:, :]
            if attn.norm_cross:
                encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
                        
        N_visual = hidden_states.shape[1]
        face_hidden_states = self.linear(face_hidden_states)

        hidden_states = hidden_states + self.scale*torch.tanh(self.alpha_attn) * self.attn( self.norm1(torch.cat([hidden_states, face_hidden_states],dim=1)), attn)[:,0:N_visual,:]
        hidden_states = hidden_states + self.scale*torch.tanh(self.alpha_dense) * self.ff( self.norm2(hidden_states))
        
        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
        
        # hidden_states = hidden_states * attn.rescale_output_factor
        
        # perform cross attention:
        residual = hidden_states
        
        # print(torch.sum((residual - residual0) * (residual - residual0)))
        
        hidden_states = self.ln(hidden_states)
        
        if attn.spatial_norm is not None:
            print(attn.spatial_norm)
            hidden_states = attn.spatial_norm(hidden_states, temb)

        input_ndim = hidden_states.ndim

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)

        batch_size, sequence_length, _ = (
            hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
        )
        attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)

        if attn.group_norm is not None:
            hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
        
        
        
        query = attn.to_q(hidden_states)

        key = attn.to_k(encoder_hidden_states)
        value = attn.to_v(encoder_hidden_states)

        query = attn.head_to_batch_dim(query)
        key = attn.head_to_batch_dim(key)
        value = attn.head_to_batch_dim(value)

        attention_probs = attn.get_attention_scores(query, key, attention_mask)
        hidden_states = torch.bmm(attention_probs, value)
        hidden_states = attn.batch_to_head_dim(hidden_states)

        # linear proj
        hidden_states = attn.to_out[0](hidden_states)
        # dropout
        hidden_states = attn.to_out[1](hidden_states)

        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)

        hidden_states = hidden_states + residual
        if not attn.residual_connection:
            hidden_states = hidden_states - residual0
            

        # hidden_states = hidden_states / attn.rescale_output_factor

        return hidden_states

class FaceAttnProcessor2_0(nn.Module):
    r"""
    Default processor for performing attention-related computations.
    """
    def __init__(
        self,
        hidden_size=None,
        cross_attention_dim=None,
        context_dim=None,
        scale=1.0,
        ln=None
    ):
        super().__init__()
        if not hasattr(F, "scaled_dot_product_attention"):
            raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
        
        self.hidden_size = hidden_size
        self.cross_attention_dim = cross_attention_dim or hidden_size
        self.scale = scale
        
        self.linear = nn.Linear(cross_attention_dim or hidden_size, hidden_size) # Context -> q

        self.attn = SelfAttention(query_dim=hidden_size, inner_dim=hidden_size)
        self.ff = FeedForward(hidden_size, glu=True)

        self.norm1 = nn.LayerNorm(hidden_size)
        self.norm2 = nn.LayerNorm(hidden_size)
        
        self.ln = ln
        self.num_ims = 1

        self.register_parameter('alpha_attn', nn.Parameter(torch.tensor(0.)) )
        self.register_parameter('alpha_dense', nn.Parameter(torch.tensor(0.)) )


    def __call__(
        self,
        attn,
        hidden_states,
        encoder_hidden_states=None,
        attention_mask=None,
        temb=None,
    ):
        
        # perform gated-self attention:
        residual0 = hidden_states
        assert(attn.rescale_output_factor == 1)
        assert(attn.residual_connection == False)
        
        # hidden_states = hidden_states / attn.rescale_output_factor
        input_ndim = hidden_states.ndim
        

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
        
        if encoder_hidden_states is None:
            encoder_hidden_states = hidden_states
        else:
            # get encoder_hidden_states, ip_hidden_states
            end_pos = encoder_hidden_states.shape[1] - 16 * self.num_ims
            encoder_hidden_states, face_hidden_states = encoder_hidden_states[:, :end_pos, :], encoder_hidden_states[:, end_pos:, :]
            if attn.norm_cross:
                encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
                        
        N_visual = hidden_states.shape[1]
        face_hidden_states = self.linear(face_hidden_states)

        hidden_states = hidden_states + self.scale*torch.tanh(self.alpha_attn) * self.attn( self.norm1(torch.cat([hidden_states, face_hidden_states],dim=1)), attn)[:,0:N_visual,:]
        hidden_states = hidden_states + self.scale*torch.tanh(self.alpha_dense) * self.ff( self.norm2(hidden_states))
        
        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
        
        # hidden_states = hidden_states * attn.rescale_output_factor
        
        # perform cross attention:
        residual = hidden_states
        
        # print(torch.sum((residual - residual0) * (residual - residual0)))
        
        hidden_states = self.ln(hidden_states)
        
        if attn.spatial_norm is not None:
            print(attn.spatial_norm)
            hidden_states = attn.spatial_norm(hidden_states, temb)

        input_ndim = hidden_states.ndim

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)

        batch_size, sequence_length, _ = (
            hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
        )
        if attention_mask is not None:
            attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
            # scaled_dot_product_attention expects attention_mask shape to be
            # (batch, heads, source_length, target_length)
            attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])

        if attn.group_norm is not None:
            hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
        
        
        
        query = attn.to_q(hidden_states)

        key = attn.to_k(encoder_hidden_states)
        value = attn.to_v(encoder_hidden_states)

        inner_dim = key.shape[-1]
        head_dim = inner_dim // attn.heads

        query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)

        key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
        value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)

        # the output of sdp = (batch, num_heads, seq_len, head_dim)
        # TODO: add support for attn.scale when we move to Torch 2.1
        hidden_states = F.scaled_dot_product_attention(
            query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
        )

        hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
        hidden_states = hidden_states.to(query.dtype)

        # linear proj
        hidden_states = attn.to_out[0](hidden_states)
        # dropout
        hidden_states = attn.to_out[1](hidden_states)

        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)

        hidden_states = hidden_states + residual
        if not attn.residual_connection:
            hidden_states = hidden_states - residual0
            

        # hidden_states = hidden_states / attn.rescale_output_factor

        return hidden_states
    
## for controlnet
class CNAttnProcessor2_0:
    r"""
    Default processor for performing attention-related computations.
    """

    def __init__(self):
        super().__init__()
        if not hasattr(F, "scaled_dot_product_attention"):
            raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
        self.num_ims = 1

    def __call__(
        self,
        attn,
        hidden_states,
        encoder_hidden_states=None,
        attention_mask=None,
        temb=None
    ):
        residual = hidden_states

        if attn.spatial_norm is not None:
            hidden_states = attn.spatial_norm(hidden_states, temb)

        input_ndim = hidden_states.ndim

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
        
        if encoder_hidden_states is None:
            encoder_hidden_states = hidden_states
        else:
            end_pos = encoder_hidden_states.shape[1] - 16 * self.num_ims
            encoder_hidden_states, face_hidden_states = encoder_hidden_states[:, :end_pos, :], encoder_hidden_states[:, end_pos:, :]
            if attn.norm_cross:
                encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)

        batch_size, sequence_length, _ = (
            hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
        )
        if attention_mask is not None:
            attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
            # scaled_dot_product_attention expects attention_mask shape to be
            # (batch, heads, source_length, target_length)
            attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])

        if attn.group_norm is not None:
            hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)

        query = attn.to_q(hidden_states)

        key = attn.to_k(encoder_hidden_states)
        value = attn.to_v(encoder_hidden_states)

        inner_dim = key.shape[-1]
        head_dim = inner_dim // attn.heads

        query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)

        key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
        value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)

        # the output of sdp = (batch, num_heads, seq_len, head_dim)
        # TODO: add support for attn.scale when we move to Torch 2.1
        hidden_states = F.scaled_dot_product_attention(
            query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
        )

        hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
        hidden_states = hidden_states.to(query.dtype)

        # linear proj
        hidden_states = attn.to_out[0](hidden_states)
        # dropout
        hidden_states = attn.to_out[1](hidden_states)

        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)

        if attn.residual_connection:
            hidden_states = hidden_states + residual

        hidden_states = hidden_states / attn.rescale_output_factor

        return hidden_states

class CNAttnProcessor:
    r"""
    Default processor for performing attention-related computations.
    """

    def __init__(self):
        super().__init__()
        self.num_ims = 1

    def __call__(
        self,
        attn,
        hidden_states,
        encoder_hidden_states=None,
        attention_mask=None,
        temb=None
    ):
        residual = hidden_states

        if attn.spatial_norm is not None:
            hidden_states = attn.spatial_norm(hidden_states, temb)

        input_ndim = hidden_states.ndim

        if input_ndim == 4:
            batch_size, channel, height, width = hidden_states.shape
            hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
        
        if encoder_hidden_states is None:
            encoder_hidden_states = hidden_states
        else:
            end_pos = encoder_hidden_states.shape[1] - 16 * self.num_ims
            encoder_hidden_states, face_hidden_states = encoder_hidden_states[:, :end_pos, :], encoder_hidden_states[:, end_pos:, :]
            if attn.norm_cross:
                encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)

        batch_size, sequence_length, _ = (
            hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
        )
        attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)

        if attn.group_norm is not None:
            hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)

        query = attn.to_q(hidden_states)

        key = attn.to_k(encoder_hidden_states)
        value = attn.to_v(encoder_hidden_states)

        query = attn.head_to_batch_dim(query)
        key = attn.head_to_batch_dim(key)
        value = attn.head_to_batch_dim(value)

        attention_probs = attn.get_attention_scores(query, key, attention_mask)
        hidden_states = torch.bmm(attention_probs, value)
        hidden_states = attn.batch_to_head_dim(hidden_states)

        # linear proj
        hidden_states = attn.to_out[0](hidden_states)
        # dropout
        hidden_states = attn.to_out[1](hidden_states)

        if input_ndim == 4:
            hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)

        if attn.residual_connection:
            hidden_states = hidden_states + residual

        hidden_states = hidden_states / attn.rescale_output_factor

        return hidden_states


================================================
FILE: face_adapter/face_preprocess.py
================================================
import cv2
import numpy as np
from skimage import transform as trans

def read_image(img_path, **kwargs):
  mode = kwargs.get('mode', 'rgb')
  layout = kwargs.get('layout', 'HWC')
  if mode=='gray':
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
  else:
    img = cv2.imread(img_path, cv2.IMREAD_COLOR)
    if mode=='rgb':
      #print('to rgb')
      img = img[...,::-1]
    if layout=='CHW':
      img = np.transpose(img, (2,0,1))
  return img


def preprocess(img, bbox=None, landmark=None, **kwargs):
  if isinstance(img, str):
    img = read_image(img, **kwargs)
  M = None
  image_size = []
  str_image_size = kwargs.get('image_size', '')
  if len(str_image_size)>0:
    image_size = [int(x) for x in str_image_size.split(',')]
    if len(image_size)==1:
      image_size = [image_size[0], image_size[0]]
    assert len(image_size)==2
    assert image_size[0]==112
    assert image_size[0]==112 or image_size[1]==96
  if landmark is not None:
    assert len(image_size)==2
    src = np.array([
      [30.2946, 51.6963],
      [65.5318, 51.5014],
      [48.0252, 71.7366],
      [33.5493, 92.3655],
      [62.7299, 92.2041] ], dtype=np.float32 )
    if image_size[1]==112:
      src[:,0] += 8.0
    dst = landmark.astype(np.float32)

    tform = trans.SimilarityTransform()
    tform.estimate(dst, src)
    M = tform.params[0:2,:]
    #M = cv2.estimateRigidTransform( dst.reshape(1,5,2), src.reshape(1,5,2), False)

  if M is None:
    if bbox is None: #use center crop
      det = np.zeros(4, dtype=np.int32)
      det[0] = int(img.shape[1]*0.0625)
      det[1] = int(img.shape[0]*0.0625)
      det[2] = img.shape[1] - det[0]
      det[3] = img.shape[0] - det[1]
    else:
      det = bbox
    margin = kwargs.get('margin', 44)
    bb = np.zeros(4, dtype=np.int32)
    bb[0] = np.maximum(det[0]-margin/2, 0)
    bb[1] = np.maximum(det[1]-margin/2, 0)
    bb[2] = np.minimum(det[2]+margin/2, img.shape[1])
    bb[3] = np.minimum(det[3]+margin/2, img.shape[0])
    ret = img[bb[1]:bb[3],bb[0]:bb[2],:]
    if len(image_size)>0:
      ret = cv2.resize(ret, (image_size[1], image_size[0]))
    return ret 
  else: #do align using landmark
    assert len(image_size)==2

    #src = src[0:3,:]
    #dst = dst[0:3,:]


    #print(src.shape, dst.shape)
    #print(src)
    #print(dst)
    #print(M)
    warped = cv2.warpAffine(img,M,(image_size[1],image_size[0]), borderValue = 0.0)

    #tform3 = trans.ProjectiveTransform()
    #tform3.estimate(src, dst)
    #warped = trans.warp(img, tform3, output_shape=_shape)
    return warped


def preprocess_3pt(img, bbox=None, landmark=None, **kwargs):
  if isinstance(img, str):
    img = read_image(img, **kwargs)
  M = None
  image_size = []
  str_image_size = kwargs.get('image_size', '')
  if len(str_image_size)>0:
    image_size = [int(x) for x in str_image_size.split(',')]
    if len(image_size)==1:
      image_size = [image_size[0], image_size[0]]
    assert len(image_size)==2
    assert image_size[0]==112
    assert image_size[0]==112 or image_size[1]==96
  if landmark is not None:
    assert len(image_size)==2
    src = np.array([
      [30.2946, 51.6963],
      [65.5318, 51.5014],
      [48.0252, 71.7366]], dtype=np.float32 )
    if image_size[1]==112:
      src[:,0] += 8.0
    dst = landmark.astype(np.float32)

    tform = trans.SimilarityTransform()
    tform.estimate(dst, src)
    M = tform.params[0:2,:]
    #M = cv2.estimateRigidTransform( dst.reshape(1,5,2), src.reshape(1,5,2), False)

  if M is None:
    if bbox is None: #use center crop
      det = np.zeros(4, dtype=np.int32)
      det[0] = int(img.shape[1]*0.0625)
      det[1] = int(img.shape[0]*0.0625)
      det[2] = img.shape[1] - det[0]
      det[3] = img.shape[0] - det[1]
    else:
      det = bbox
    margin = kwargs.get('margin', 44)
    bb = np.zeros(4, dtype=np.int32)
    bb[0] = np.maximum(det[0]-margin/2, 0)
    bb[1] = np.maximum(det[1]-margin/2, 0)
    bb[2] = np.minimum(det[2]+margin/2, img.shape[1])
    bb[3] = np.minimum(det[3]+margin/2, img.shape[0])
    ret = img[bb[1]:bb[3],bb[0]:bb[2],:]
    if len(image_size)>0:
      ret = cv2.resize(ret, (image_size[1], image_size[0]))
    return ret 
  else: #do align using landmark
    assert len(image_size)==2

    #src = src[0:3,:]
    #dst = dst[0:3,:]


    #print(src.shape, dst.shape)
    #print(src)
    #print(dst)
    #print(M)
    warped = cv2.warpAffine(img,M,(image_size[1],image_size[0]), borderValue = 0.0)

    #tform3 = trans.ProjectiveTransform()
    #tform3.estimate(src, dst)
    #warped = trans.warp(img, tform3, output_shape=_shape)
    return warped


================================================
FILE: face_adapter/utils.py
================================================
import torch.nn.functional as F

def is_torch2_available():
    return hasattr(F, "scaled_dot_product_attention")




================================================
FILE: face_adapter/vit.py
================================================
import torch
import torch.nn as nn
from timm.models.layers import DropPath, to_2tuple, trunc_normal_
from typing import Optional, Callable
import math

class Mlp(nn.Module):
    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.ReLU6, drop=0.):
        super().__init__()
        out_features = out_features or in_features
        hidden_features = hidden_features or in_features
        self.fc1 = nn.Linear(in_features, hidden_features)
        self.act = act_layer()
        self.fc2 = nn.Linear(hidden_features, out_features)
        self.drop = nn.Dropout(drop)

    def forward(self, x):
        x = self.fc1(x)
        x = self.act(x)
        x = self.drop(x)
        x = self.fc2(x)
        x = self.drop(x)
        return x


class VITBatchNorm(nn.Module):
    def __init__(self, num_features):
        super().__init__()
        self.num_features = num_features
        self.bn = nn.BatchNorm1d(num_features=num_features)

    def forward(self, x):
        return self.bn(x)


class Attention(nn.Module):
    def __init__(self,
                 dim: int,
                 num_heads: int = 8,
                 qkv_bias: bool = False,
                 qk_scale: Optional[None] = None,
                 attn_drop: float = 0.,
                 proj_drop: float = 0.):
        super().__init__()
        self.num_heads = num_heads
        head_dim = dim // num_heads
        # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
        self.scale = qk_scale or head_dim ** -0.5

        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
        self.attn_drop = nn.Dropout(attn_drop)
        self.proj = nn.Linear(dim, dim)
        self.proj_drop = nn.Dropout(proj_drop)

    def forward(self, x):
        
        with torch.cuda.amp.autocast(True):
            batch_size, num_token, embed_dim = x.shape
            #qkv is [3,batch_size,num_heads,num_token, embed_dim//num_heads]
            qkv = self.qkv(x).reshape(
                batch_size, num_token, 3, self.num_heads, embed_dim // self.num_heads).permute(2, 0, 3, 1, 4)
        with torch.cuda.amp.autocast(False):
            q, k, v = qkv[0].float(), qkv[1].float(), qkv[2].float()
            attn = (q @ k.transpose(-2, -1)) * self.scale
            attn = attn.softmax(dim=-1)
            attn = self.attn_drop(attn)
            x = (attn @ v).transpose(1, 2).reshape(batch_size, num_token, embed_dim)
        with torch.cuda.amp.autocast(True):
            x = self.proj(x)
            x = self.proj_drop(x)
        return x


class Block(nn.Module):

    def __init__(self,
                 dim: int,
                 num_heads: int,
                 num_patches: int,
                 mlp_ratio: float = 4.,
                 qkv_bias: bool = False,
                 qk_scale: Optional[None] = None,
                 drop: float = 0.,
                 attn_drop: float = 0.,
                 drop_path: float = 0.,
                 act_layer: Callable = nn.ReLU6,
                 norm_layer: str = "ln", 
                 patch_n: int = 144):
        super().__init__()

        if norm_layer == "bn":
            self.norm1 = VITBatchNorm(num_features=num_patches)
            self.norm2 = VITBatchNorm(num_features=num_patches)
        elif norm_layer == "ln":
            self.norm1 = nn.LayerNorm(dim)
            self.norm2 = nn.LayerNorm(dim)

        self.attn = Attention(
            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
        self.drop_path = DropPath(
            drop_path) if drop_path > 0. else nn.Identity()
        mlp_hidden_dim = int(dim * mlp_ratio)
        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim,
                       act_layer=act_layer, drop=drop)
        self.extra_gflops = (num_heads * patch_n * (dim//num_heads)*patch_n * 2) / (1000**3)

    def forward(self, x):
        x = x + self.drop_path(self.attn(self.norm1(x)))
        with torch.cuda.amp.autocast(True):
            x = x + self.drop_path(self.mlp(self.norm2(x)))
        return x


class PatchEmbed(nn.Module):
    def __init__(self, img_size=108, patch_size=9, in_channels=3, embed_dim=768):
        super().__init__()
        img_size = to_2tuple(img_size)
        patch_size = to_2tuple(patch_size)
        num_patches = (img_size[1] // patch_size[1]) * \
            (img_size[0] // patch_size[0])
        self.img_size = img_size
        self.patch_size = patch_size
        self.num_patches = num_patches
        self.proj = nn.Conv2d(in_channels, embed_dim,
                              kernel_size=patch_size, stride=patch_size)

    def forward(self, x):
        batch_size, channels, height, width = x.shape
        assert height == self.img_size[0] and width == self.img_size[1], \
            f"Input image size ({height}*{width}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})."
        x = self.proj(x).flatten(2).transpose(1, 2)

        return x


class VisionTransformer(nn.Module):
    """ Vision Transformer with support for patch or hybrid CNN input stage
    """

    def __init__(self,
                 img_size: int = 112,
                 patch_size: int = 16,
                 in_channels: int = 3,
                 num_classes: int = 1000,
                 embed_dim: int = 768,
                 depth: int = 12,
                 num_heads: int = 12,
                 mlp_ratio: float = 4.,
                 qkv_bias: bool = False,
                 qk_scale: Optional[None] = None,
                 drop_rate: float = 0.,
                 attn_drop_rate: float = 0.,
                 drop_path_rate: float = 0.,
                 hybrid_backbone: Optional[None] = None,
                 norm_layer: str = "ln",
                 mask_ratio = 0.1,
                 using_checkpoint = False,
                 ):
        super().__init__()
        self.num_classes = num_classes
        # num_features for consistency with other models
        self.num_features = self.embed_dim = embed_dim

        if hybrid_backbone is not None:
            raise ValueError
        else:
            self.patch_embed = PatchEmbed(img_size=img_size, patch_size=patch_size, in_channels=in_channels, embed_dim=embed_dim)
        self.mask_ratio = mask_ratio
        self.using_checkpoint = using_checkpoint
        num_patches = self.patch_embed.num_patches
        self.num_patches = num_patches

        self.pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim))
        self.pos_drop = nn.Dropout(p=drop_rate)

        # stochastic depth decay rule
        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)]
        patch_n = (img_size//patch_size)**2
        self.blocks = nn.ModuleList(
            [
                Block(dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,
                      drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer,
                      num_patches=num_patches, patch_n=patch_n)
                for i in range(depth)]
        )
        self.extra_gflops = 0.0
        for _block in self.blocks:
            self.extra_gflops += _block.extra_gflops

        if norm_layer == "ln":
            self.norm = nn.LayerNorm(embed_dim)
        elif norm_layer == "bn":
            self.norm = VITBatchNorm(self.num_patches)

        # features head
        self.feature = nn.Sequential(
            nn.Linear(in_features=embed_dim * num_patches, out_features=embed_dim, bias=False),
            nn.BatchNorm1d(num_features=embed_dim, eps=2e-5),
            nn.Linear(in_features=embed_dim, out_features=num_classes, bias=False),
            nn.BatchNorm1d(num_features=num_classes, eps=2e-5)
        )

        self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
        torch.nn.init.normal_(self.mask_token, std=.02)
        trunc_normal_(self.pos_embed, std=.02)
        # trunc_normal_(self.cls_token, std=.02)
        self.apply(self._init_weights)

        ## SEModule FC
        self.senet = nn.Sequential(
            nn.Linear(in_features=embed_dim * num_patches, out_features=num_patches, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(in_features=num_patches, out_features=num_patches, bias=False),
            nn.Sigmoid()
        )
            

    def _init_weights(self, m):
        if isinstance(m, nn.Linear):
            trunc_normal_(m.weight, std=.02)
            if isinstance(m, nn.Linear) and m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.LayerNorm):
            nn.init.constant_(m.bias, 0)
            nn.init.constant_(m.weight, 1.0)

    @torch.jit.ignore
    def no_weight_decay(self):
        return {'pos_embed', 'cls_token'}

    def get_classifier(self):
        return self.head
    
    def random_masking(self, x, mask_ratio=0.1):
        """
        Perform per-sample random masking by per-sample shuffling.
        Per-sample shuffling is done by argsort random noise.
        x: [N, L, D], sequence
        """
        N, L, D = x.size()  # batch, length, dim
        len_keep = int(L * (1 - mask_ratio))

        noise = torch.rand(N, L, device=x.device)  # noise in [0, 1]

        # sort noise for each sample
        # ascend: small is keep, large is remove
        ids_shuffle = torch.argsort(noise, dim=1)
        ids_restore = torch.argsort(ids_shuffle, dim=1)

        # keep the first subset
        ids_keep = ids_shuffle[:, :len_keep]
        x_masked = torch.gather(
            x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))

        # generate the binary mask: 0 is keep, 1 is remove
        mask = torch.ones([N, L], device=x.device)
        mask[:, :len_keep] = 0
        # unshuffle to get the binary mask
        mask = torch.gather(mask, dim=1, index=ids_restore)

        return x_masked, mask, ids_restore

    def forward_features(self, x):
        B = x.shape[0]
        x = self.patch_embed(x)
        x = x + self.pos_embed
        x = self.pos_drop(x)

        if self.training and self.mask_ratio > 0:
            x, _, ids_restore = self.random_masking(x)

        for func in self.blocks:
            if self.using_checkpoint and self.training:
                from torch.utils.checkpoint import checkpoint
                x = checkpoint(func, x)
            else:
                x = func(x)
        x = self.norm(x.float())
        
        if self.training and self.mask_ratio > 0:
            mask_tokens = self.mask_token.repeat(x.shape[0], ids_restore.shape[1] - x.shape[1], 1)
            x_ = torch.cat([x[:, :, :], mask_tokens], dim=1)  # no cls token
            x_ = torch.gather(x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2]))  # unshuffle
            x = x_

        orginal = x
        out = torch.reshape(x, (B, self.num_patches * self.embed_dim))
        out = self.senet(out)
        out_softmax = out.softmax(dim=1)
        out = torch.reshape(out, (B, self.num_patches, 1))
        out = out * orginal
        return orginal, torch.reshape(out, (B, self.num_patches * self.embed_dim)), out_softmax




    def forward(self, x):
        orginal, x, weight = self.forward_features(x)
        out_x = torch.reshape(x, (x.shape[0], self.num_patches, self.embed_dim) )
        # for numerical stability
        patch_std = torch.std(out_x, dim=2)
        #patch_entropy = torch.log(patch_std) + 0.5 + 0.5*torch.log( torch.tensor(2*math.pi) )  ## Entropy
        patch_entropy = patch_std
        x = self.feature(x)
        # return x, weight, patch_entropy
        return orginal, x # local rep, global rep




================================================
FILE: face_module/DamoFD/README.md
================================================
### The code will be released in the future.


================================================
FILE: face_module/TopoFR/GUM.py
================================================
### GUM model
import numpy as np
from scipy.stats import multivariate_normal
from sklearn import preprocessing
import torch


def gauss_unif(x):
    global delta, pi, Sigma
    N, D = x.shape

    x=x.astype(float)

    x=preprocessing.scale(x)

    ###initialization
    pi = 0.1
    Mu = np.zeros([1,D])
    epsilon = x - Mu
    Sigma =1 / N *np.sum(epsilon.reshape(-1, D, 1) * epsilon.reshape(-1, 1, D), axis=0)


    c = 0.2

    log_like0 = 0
    for i in range(1000):
        ###E-step
        phi=multivariate_normal(Mu,Sigma+1e-3).pdf(x)
        gamma = phi*pi / (phi*pi + (1 - pi) * c)

        ####M-step
        N1 = gamma.sum()
        #Mu = 1 / N1 * np.sum(gamma.reshape(-1, 1) * x, axis=0)
        epsilon = x - Mu
        Sigma = 1 / N1 * np.sum(gamma.reshape(-1, 1, 1) * epsilon.reshape(-1, D, 1) * epsilon.reshape(-1, 1, D), axis=0)
        pi_new = N1 / N
        thres=0.5
        if pi_new<=thres:
            pi=pi_new
        else:
            pi=thres

        C1 = 1 / N1 * np.sum((1 - gamma.reshape(-1, 1)) / (1 - pi + 1e-10) * epsilon, axis=0)
        C2 = 1 / N1 * np.sum((1 - gamma.reshape(-1, 1)) / (1 - pi + 1e-10) * epsilon ** 2, axis=0)
        if abs(3 * C2 - C1 ** 2)<0.001:
            c=0.001
        else:
            c = 1.0 / (np.prod(2 * np.sqrt(3 * C2 - C1 ** 2)) + 1e-10)
        #c=1/(np.max(np.abs(epsilon))-np.min(np.abs(epsilon)))


        ###stopping criterion
        log_like = np.sum(pi * phi + (1 - pi) * c)
        if abs(log_like - log_like0) < 1e-10:
            break
        else:
            log_like0 = log_like

    delta = c
    return gamma,pi,Sigma[0,0]



================================================
FILE: face_module/TopoFR/README.md
================================================
<h2 align="center">TopoFR: A Closer Look at Topology Alignment on Face Recognition
<h5 align="center"> If you like TopoFR, please give us a star ⭐ on GitHub for the latest update~
</h2>

This is the official PyTorch implementation of ["[NeurIPS 2024] TopoFR: A Closer Look at Topology Alignment on Face Recognition"](https://arxiv.org/abs/2410.10587).

![image](docs/TopoFR.png)

## Requirements
* Install Pytorch (torch>=1.9.0)
* ```pip install -r requirement.txt```

## Datasets
You can download the training datasets, including MS1MV2 and Glint360K:
* MS1MV2: [Google Drive](https://drive.google.com/file/d/1SXS4-Am3bsKSK615qbYdbA_FMVh3sAvR/view)
* Glint360K: [Baidu](https://pan.baidu.com/share/init?surl=GsYqTTt7_Dn8BfxxsLFN0w) (code=:o3az)

You can download the test dataset IJB-C as follows:
* IJB-C: [Google Drive](https://drive.google.com/file/d/1aC4zf2Bn0xCVH_ZtEuQipR2JvRb1bf8o/view) 

## How to Train Models
1. You need to modify the path of training dataset in every configuration file in folder configs.

2. To run on a machine with 4 GPUs:
```
python -m torch.distributed.launch --nproc_per_node=4 --nnodes=1 --node_rank=0 --master_addr="127.0.0.1" --master_port=12581 train.py 
```

## How to Test Models
1. You need to modify the path of IJB-C dataset in eval_ijbc_ms1mv2.py and eval_ijbc_glint360k.py.

2. Run:
```
python eval_ijbc_ms1mv2.py --model-prefix work_dirs/ms1mv2_r50/model.pt --result-dir work_dirs/ms1mv2_r50 --network r50 > ijbc_ms1mv2_R50_TopoFR.log 2>&1 &
```
```
python eval_ijbc_glint360k.py --model-prefix work_dirs/glint360k_r50/model.pt --result-dir work_dirs/glint360k_r50 --network r50 > ijbc_glint360k_R50_TopoFR.log 2>&1 &
```

## TopoFR Pretrained Models 

* You can download the TopoFR models reported in our paper as follows:

Verification accuracy (%) on IJB-C benchmark. † denotes TopoFR trained by CosFace.
| Training Data | Model| IJB-C(1e-5) | IJB-C(1e-4) |
| ------ | ------ | ------ | ------ |
| MS1MV2 | [R50 TopoFR†](https://drive.google.com/file/d/1mMikKUtmMXSB8COQ8BzEh3x3u2296UHP/view?usp=sharing) | 94.79 | 96.42 |
| MS1MV2 | [R50 TopoFR](https://drive.google.com/file/d/1Q2ux_leUHni9zYQ-5i2zL09yGWaeJZkX/view?usp=sharing) | 94.71 | 96.49 |
| MS1MV2 | [R100 TopoFR†](https://drive.google.com/file/d/17A0M413lt8cFX4uuRvvpaKy5EZE5--yl/view?usp=sharing) | 95.28 | 96.96 |
| MS1MV2 | [R100 TopoFR](https://drive.google.com/file/d/1a648DCItUZpolxvMMrUHZ6OR_O5hebfT/view?usp=sharing) | 95.23 | 96.95 |
| MS1MV2 | [R200 TopoFR†](https://drive.google.com/file/d/1BuF1qU60w0y31Fddmmcl_YUbcpsj6WoF/view?usp=sharing) | 95.19 | 97.12 |
| MS1MV2 | [R200 TopoFR](https://drive.google.com/file/d/14zStJMpXgP-vx_9slj-gBCRapzU_zRrV/view?usp=sharing) | 95.15 | 97.08 |

| Training Data | Model | IJB-C(1e-5) | IJB-C(1e-4) |
| ------ | ------ | ------ | ------ |
| Glint360K | [R50 TopoFR](https://drive.google.com/file/d/1R_ffZ2GpvNrwG5ZM76LO32KTol-hXNQx/view?usp=sharing) | 95.99 | 97.27 |
| Glint360K | [R100 TopoFR](https://drive.google.com/file/d/1vQBGXc_nXytEx8fpV9jykeLdxD45cE8B/view?usp=sharing) | 96.57 | 97.60 |
| Glint360K | [R200 TopoFR](https://drive.google.com/file/d/1DXvcksXIaIXoNWxTXPWhLQaKL_aPaBAR/view?usp=sharing) | 96.71 | 97.84 |

* You can test the accuracy of these model: (e.g., Glint360K R100 TopoFR)
```
python eval_ijbc_glint360k.py --model-prefix work_dirs/glint360k_r100/Glint360K_R100_TopoFR_9760.pt --result-dir work_dirs/glint360k_r100 --network r100 > ijbc_glint360k_R100_TopoFR.log 2>&1 &
```

## Citation
* If you find it helpful for you, please consider citing our paper 📝 and giving a star ⭐.
```
@article{dan2024topofr,
  title={TopoFR: A Closer Look at Topology Alignment on Face Recognition},
  author={Dan, Jun and Liu, Yang and Deng, Jiankang and Xie, Haoyu and Li, Siyuan and Sun, Baigui and Luo, Shan},
  journal={arXiv preprint arXiv:2410.10587},
  year={2024}
}
```

## Acknowledgments
We thank Insighface for the excellent [code base](https://github.com/deepinsight/insightface/tree/master/recognition/arcface_torch).


================================================
FILE: face_module/TopoFR/backbones/__init__.py
================================================
from .iresnet import iresnet18, iresnet34, iresnet50, iresnet100, iresnet200
from .mobilefacenet import get_mbf


def get_model(name, **kwargs):
    # resnet
    if name == "r18":
        return iresnet18(False, **kwargs)
    elif name == "r34":
        return iresnet34(False, **kwargs)
    elif name == "r50":
        return iresnet50(False, **kwargs)
    elif name == "r100":
        return iresnet100(False, **kwargs)
    elif name == "r200":
        return iresnet200(False, **kwargs)
    elif name == "r2060":
        from .iresnet2060 import iresnet2060
        return iresnet2060(False, **kwargs)

    elif name == "mbf":
        fp16 = kwargs.get("fp16", False)
        num_features = kwargs.get("num_features", 512)
        return get_mbf(fp16=fp16, num_features=num_features)

    elif name == "mbf_large":
        from .mobilefacenet import get_mbf_large
        fp16 = kwargs.get("fp16", False)
        num_features = kwargs.get("num_features", 512)
        return get_mbf_large(fp16=fp16, num_features=num_features)

    elif name == "vit_t":
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=256, depth=12,
            num_heads=8, drop_path_rate=0.1, norm_layer="ln", mask_ratio=0.1)

    elif name == "vit_t_dp005_mask0": # For WebFace42M
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=256, depth=12,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.0)

    elif name == "vit_s":
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=12,
            num_heads=8, drop_path_rate=0.1, norm_layer="ln", mask_ratio=0.1)
    
    elif name == "vit_s_dp005_mask_0":  # For WebFace42M
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=12,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.0)
    
    elif name == "vit_b":
        # this is a feature
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=24,
            num_heads=8, drop_path_rate=0.1, norm_layer="ln", mask_ratio=0.1, using_checkpoint=True)

    elif name == "vit_b_dp005_mask_005":  # For WebFace42M
        # this is a feature
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=24,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.05, using_checkpoint=True)

    elif name == "vit_l_dp005_mask_005":  # For WebFace42M
        # this is a feature
        num_features = kwargs.get("num_features", 512)
        from .vit import VisionTransformer
        return VisionTransformer(  
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=768, depth=24,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.05, using_checkpoint=True)

    else:
        raise ValueError()
        

###############
"""
from .iresnet import iresnet18, iresnet34, iresnet50, iresnet100, iresnet200
from .mobilefacenet import get_mbf


def get_model_baseline(name, **kwargs):
    # resnet
    if name == "r18":
        return iresnet18(False, **kwargs)
    elif name == "r34":
        return iresnet34(False, **kwargs)
    elif name == "r50":
        return iresnet50(False, **kwargs)
    elif name == "r100":
        return iresnet100(False, **kwargs)
    elif name == "r200":
        return iresnet200(False, **kwargs)
    elif name == "r2060":
        from .iresnet2060 import iresnet2060
        return iresnet2060(False, **kwargs)

    elif name == "mbf":
        fp16 = kwargs.get("fp16", False)
        num_features = kwargs.get("num_features", 512)
        return get_mbf(fp16=fp16, num_features=num_features)

    elif name == "mbf_large":
        from .mobilefacenet import get_mbf_large
        fp16 = kwargs.get("fp16", False)
        num_features = kwargs.get("num_features", 512)
        return get_mbf_large(fp16=fp16, num_features=num_features)

    elif name == "vit_t":
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=256, depth=12,
            num_heads=8, drop_path_rate=0.1, norm_layer="ln", mask_ratio=0.1)

    elif name == "vit_t_dp005_mask0": # For WebFace42M
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=256, depth=12,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.0)

    elif name == "vit_s":
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=12,
            num_heads=8, drop_path_rate=0.1, norm_layer="ln", mask_ratio=0.1)
    
    elif name == "vit_s_dp005_mask_0":  # For WebFace42M
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=12,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.0)
    
    elif name == "vit_b":
        # this is a feature
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=24,
            num_heads=8, drop_path_rate=0.1, norm_layer="ln", mask_ratio=0.1, using_checkpoint=True)

    elif name == "vit_b_dp005_mask_005":  # For WebFace42M
        # this is a feature
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=512, depth=24,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.05, using_checkpoint=True)

    elif name == "vit_l_dp005_mask_005":  # For WebFace42M
        # this is a feature
        num_features = kwargs.get("num_features", 512)
        #from .vit import VisionTransformer
        from .vit_baseline import VisionTransformer
        return VisionTransformer(  
            img_size=112, patch_size=9, num_classes=num_features, embed_dim=768, depth=24,
            num_heads=8, drop_path_rate=0.05, norm_layer="ln", mask_ratio=0.05, using_checkpoint=True)

    else:
        raise ValueError()
        
"""


================================================
FILE: face_module/TopoFR/backbones/iresnet.py
================================================
import torch
from torch import nn
from torch.utils.checkpoint import checkpoint
from torch.nn.functional import linear, normalize

__all__ = ['iresnet18', 'iresnet34', 'iresnet50', 'iresnet100', 'iresnet200']
using_ckpt = False

def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
    """3x3 convolution with padding"""
    return nn.Conv2d(in_planes,
                     out_planes,
                     kernel_size=3,
                     stride=stride,
                     padding=dilation,
                     groups=groups,
                     bias=False,
                     dilation=dilation)


def conv1x1(in_planes, out_planes, stride=1):
    """1x1 convolution"""
    return nn.Conv2d(in_planes,
                     out_planes,
                     kernel_size=1,
                     stride=stride,
                     bias=False)


class IBasicBlock(nn.Module):
    expansion = 1
    def __init__(self, inplanes, planes, stride=1, downsample=None,
                 groups=1, base_width=64, dilation=1):
        super(IBasicBlock, self).__init__()
        if groups != 1 or base_width != 64:
            raise ValueError('BasicBlock only supports groups=1 and base_width=64')
        if dilation > 1:
            raise NotImplementedError("Dilation > 1 not supported in BasicBlock")
        self.bn1 = nn.BatchNorm2d(inplanes, eps=1e-05,)
        self.conv1 = conv3x3(inplanes, planes)
        self.bn2 = nn.BatchNorm2d(planes, eps=1e-05,)
        self.prelu = nn.PReLU(planes)
        self.conv2 = conv3x3(planes, planes, stride)
        self.bn3 = nn.BatchNorm2d(planes, eps=1e-05,)
        self.downsample = downsample
        self.stride = stride

    def forward_impl(self, x):
        identity = x
        out = self.bn1(x)
        out = self.conv1(out)
        out = self.bn2(out)
        out = self.prelu(out)
        out = self.conv2(out)
        out = self.bn3(out)
        if self.downsample is not None:
            identity = self.downsample(x)
        out += identity
        return out        

    def forward(self, x):
        if self.training and using_ckpt:
            return checkpoint(self.forward_impl, x)
        else:
            return self.forward_impl(x)


class IResNet(nn.Module):
    fc_scale = 7 * 7
    def __init__(self,
                 block, layers, dropout=0, num_features=512, zero_init_residual=False,
                 groups=1, width_per_group=64, replace_stride_with_dilation=None, fp16=False, num_classes=None):
        super(IResNet, self).__init__()
        self.extra_gflops = 0.0
        self.fp16 = fp16
        self.inplanes = 64
        self.dilation = 1
        if replace_stride_with_dilation is None:
            replace_stride_with_dilation = [False, False, False]
        if len(replace_stride_with_dilation) != 3:
            raise ValueError("replace_stride_with_dilation should be None "
                             "or a 3-element tuple, got {}".format(replace_stride_with_dilation))
        self.groups = groups
        self.base_width = width_per_group
        self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(self.inplanes, eps=1e-05)
        self.prelu = nn.PReLU(self.inplanes)
        self.layer1 = self._make_layer(block, 64, layers[0], stride=2)
        self.layer2 = self._make_layer(block,
                                       128,
                                       layers[1],
                                       stride=2,
                                       dilate=replace_stride_with_dilation[0])
        self.layer3 = self._make_layer(block,
                                       256,
                                       layers[2],
                                       stride=2,
                                       dilate=replace_stride_with_dilation[1])
        self.layer4 = self._make_layer(block,
                                       512,
                                       layers[3],
                                       stride=2,
                                       dilate=replace_stride_with_dilation[2])
        self.bn2 = nn.BatchNorm2d(512 * block.expansion, eps=1e-05,)
        self.dropout = nn.Dropout(p=dropout, inplace=True)
        self.fc = nn.Linear(512 * block.expansion * self.fc_scale, num_features)
        self.features = nn.BatchNorm1d(num_features, eps=1e-05)
        nn.init.constant_(self.features.weight, 1.0)
        #self.features.weight.requires_grad = False

        ## add fc
        self.weight = torch.nn.Parameter(torch.normal(0, 0.01, (num_classes, num_features)))
        


        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.normal_(m.weight, 0, 0.1)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

        if zero_init_residual:
            for m in self.modules():
                if isinstance(m, IBasicBlock):
                    nn.init.constant_(m.bn2.weight, 0)

    def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
        downsample = None
        previous_dilation = self.dilation
        if dilate:
            self.dilation *= stride
            stride = 1
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                conv1x1(self.inplanes, planes * block.expansion, stride),
                nn.BatchNorm2d(planes * block.expansion, eps=1e-05, ),
            )
        layers = []
        layers.append(
            block(self.inplanes, planes, stride, downsample, self.groups,
                  self.base_width, previous_dilation))
        self.inplanes = planes * block.expansion
        for _ in range(1, blocks):
            layers.append(
                block(self.inplanes,
                      planes,
                      groups=self.groups,
                      base_width=self.base_width,
                      dilation=self.dilation))

        return nn.Sequential(*layers)

    def forward(self, x, phase='train'):
        with torch.cuda.amp.autocast(self.fp16):
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.prelu(x)
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            x = self.layer4(x)
            x = self.bn2(x)
            x = torch.flatten(x, 1)
            x = self.dropout(x)
            x = self.fc(x.float() if self.fp16 else x)
            x = self.features(x)
            bottleneck_embedding = x
        if phase != 'infer':
            with torch.cuda.amp.autocast(self.fp16):
                norm_embeddings = normalize(x)
                norm_weight_activated = normalize(self.weight)
                logits = linear(norm_embeddings, norm_weight_activated)
            #return logits
            return logits, bottleneck_embedding
        else:
            return x



def _iresnet(arch, block, layers, pretrained, progress, **kwargs):
    model = IResNet(block, layers, **kwargs)
    if pretrained:
        raise ValueError()
    return model


def iresnet18(pretrained=False, progress=True, **kwargs):
    return _iresnet('iresnet18', IBasicBlock, [2, 2, 2, 2], pretrained,
                    progress, **kwargs)


def iresnet34(pretrained=False, progress=True, **kwargs):
    return _iresnet('iresnet34', IBasicBlock, [3, 4, 6, 3], pretrained,
                    progress, **kwargs)


def iresnet50(pretrained=False, progress=True, **kwargs):
    return _iresnet('iresnet50', IBasicBlock, [3, 4, 14, 3], pretrained,
                    progress, **kwargs)


def iresnet100(pretrained=False, progress=True, **kwargs):
    return _iresnet('iresnet100', IBasicBlock, [3, 13, 30, 3], pretrained,
                    progress, **kwargs)


def iresnet200(pretrained=False, progress=True, **kwargs):
    return _iresnet('iresnet200', IBasicBlock, [6, 26, 60, 6], pretrained,
                    progress, **kwargs)


================================================
FILE: face_module/TopoFR/backbones/iresnet2060.py
================================================
import torch
from torch import nn

assert torch.__version__ >= "1.8.1"
from torch.utils.checkpoint import checkpoint_sequential

__all__ = ['iresnet2060']


def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
    """3x3 convolution with padding"""
    return nn.Conv2d(in_planes,
                     out_planes,
                     kernel_size=3,
                     stride=stride,
                     padding=dilation,
                     groups=groups,
                     bias=False,
                     dilation=dilation)


def conv1x1(in_planes, out_planes, stride=1):
    """1x1 convolution"""
    return nn.Conv2d(in_planes,
                     out_planes,
                     kernel_size=1,
                     stride=stride,
                     bias=False)


class IBasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None,
                 groups=1, base_width=64, dilation=1):
        super(IBasicBlock, self).__init__()
        if groups != 1 or base_width != 64:
            raise ValueError('BasicBlock only supports groups=1 and base_width=64')
        if dilation > 1:
            raise NotImplementedError("Dilation > 1 not supported in BasicBlock")
        self.bn1 = nn.BatchNorm2d(inplanes, eps=1e-05, )
        self.conv1 = conv3x3(inplanes, planes)
        self.bn2 = nn.BatchNorm2d(planes, eps=1e-05, )
        self.prelu = nn.PReLU(planes)
        self.conv2 = conv3x3(planes, planes, stride)
        self.bn3 = nn.BatchNorm2d(planes, eps=1e-05, )
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x
        out = self.bn1(x)
        out = self.conv1(out)
        out = self.bn2(out)
        out = self.prelu(out)
        out = self.conv2(out)
        out = self.bn3(out)
        if self.downsample is not None:
            identity = self.downsample(x)
        out += identity
        return out


class IResNet(nn.Module):
    fc_scale = 7 * 7

    def __init__(self,
                 block, layers, dropout=0, num_features=512, zero_init_residual=False,
                 groups=1, width_per_group=64, replace_stride_with_dilation=None, fp16=False):
        super(IResNet, self).__init__()
        self.fp16 = fp16
        self.inplanes = 64
        self.dilation = 1
        if replace_stride_with_dilation is None:
            replace_stride_with_dilation = [False, False, False]
        if len(replace_stride_with_dilation) != 3:
            raise ValueError("replace_stride_with_dilation should be None "
                             "or a 3-element tuple, got {}".format(replace_stride_with_dilation))
        self.groups = groups
        self.base_width = width_per_group
        self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(self.inplanes, eps=1e-05)
        self.prelu = nn.PReLU(self.inplanes)
        self.layer1 = self._make_layer(block, 64, layers[0], stride=2)
        self.layer2 = self._make_layer(block,
                                       128,
                                       layers[1],
                                       stride=2,
                                       dilate=replace_stride_with_dilation[0])
        self.layer3 = self._make_layer(block,
                                       256,
                                       layers[2],
                                       stride=2,
                                       dilate=replace_stride_with_dilation[1])
        self.layer4 = self._make_layer(block,
                                       512,
                                       layers[3],
                                       stride=2,
                                       dilate=replace_stride_with_dilation[2])
        self.bn2 = nn.BatchNorm2d(512 * block.expansion, eps=1e-05, )
        self.dropout = nn.Dropout(p=dropout, inplace=True)
        self.fc = nn.Linear(512 * block.expansion * self.fc_scale, num_features)
        self.features = nn.BatchNorm1d(num_features, eps=1e-05)
        nn.init.constant_(self.features.weight, 1.0)
        self.features.weight.requires_grad = False

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.normal_(m.weight, 0, 0.1)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

        if zero_init_residual:
            for m in self.modules():
                if isinstance(m, IBasicBlock):
                    nn.init.constant_(m.bn2.weight, 0)

    def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
        downsample = None
        previous_dilation = self.dilation
        if dilate:
            self.dilation *= stride
            stride = 1
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                conv1x1(self.inplanes, planes * block.expansion, stride),
                nn.BatchNorm2d(planes * block.expansion, eps=1e-05, ),
            )
        layers = []
        layers.append(
            block(self.inplanes, planes, stride, downsample, self.groups,
                  self.base_width, previous_dilation))
        self.inplanes = planes * block.expansion
        for _ in range(1, blocks):
            layers.append(
                block(self.inplanes,
                      planes,
                      groups=self.groups,
                      base_width=self.base_width,
                      dilation=self.dilation))

        return nn.Sequential(*layers)

    def checkpoint(self, func, num_seg, x):
        if self.training:
            return checkpoint_sequential(func, num_seg, x)
        else:
            return func(x)

    def forward(self, x):
        with torch.cuda.amp.autocast(self.fp16):
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.prelu(x)
            x = self.layer1(x)
            x = self.checkpoint(self.layer2, 20, x)
            x = self.checkpoint(self.layer3, 100, x)
            x = self.layer4(x)
            x = self.bn2(x)
            x = torch.flatten(x, 1)
            x = self.dropout(x)
        x = self.fc(x.float() if self.fp16 else x)
        x = self.features(x)
        return x


def _iresnet(arch, block, layers, pretrained, progress, **kwargs):
    model = IResNet(block, layers, **kwargs)
    if pretrained:
        raise ValueError()
    return model


def iresnet2060(pretrained=False, progress=True, **kwargs):
    return _iresnet('iresnet2060', IBasicBlock, [3, 128, 1024 - 128, 3], pretrained, progress, **kwargs)


================================================
FILE: face_module/TopoFR/backbones/mobilefacenet.py
================================================
'''
Adapted from https://github.com/cavalleria/cavaface.pytorch/blob/master/backbone/mobilefacenet.py
Original author cavalleria
'''

import torch.nn as nn
from torch.nn import Linear, Conv2d, BatchNorm1d, BatchNorm2d, PReLU, Sequential, Module
import torch


class Flatten(Module):
    def forward(self, x):
        return x.view(x.size(0), -1)


class ConvBlock(Module):
    def __init__(self, in_c, out_c, kernel=(1, 1), stride=(1, 1), padding=(0, 0), groups=1):
        super(ConvBlock, self).__init__()
        self.layers = nn.Sequential(
            Conv2d(in_c, out_c, kernel, groups=groups, stride=stride, padding=padding, bias=False),
            BatchNorm2d(num_features=out_c),
            PReLU(num_parameters=out_c)
        )

    def forward(self, x):
        return self.layers(x)


class LinearBlock(Module):
    def __init__(self, in_c, out_c, kernel=(1, 1), stride=(1, 1), padding=(0, 0), groups=1):
        super(LinearBlock, self).__init__()
        self.layers = nn.Sequential(
            Conv2d(in_c, out_c, kernel, stride, padding, groups=groups, bias=False),
            BatchNorm2d(num_features=out_c)
        )

    def forward(self, x):
        return self.layers(x)


class DepthWise(Module):
    def __init__(self, in_c, out_c, residual=False, kernel=(3, 3), stride=(2, 2), padding=(1, 1), groups=1):
        super(DepthWise, self).__init__()
        self.residual = residual
        self.layers = nn.Sequential(
            ConvBlock(in_c, out_c=groups, kernel=(1, 1), padding=(0, 0), stride=(1, 1)),
            ConvBlock(groups, groups, groups=groups, kernel=kernel, padding=padding, stride=stride),
            LinearBlock(groups, out_c, kernel=(1, 1), padding=(0, 0), stride=(1, 1))
        )

    def forward(self, x):
        short_cut = None
        if self.residual:
            short_cut = x
        x = self.layers(x)
        if self.residual:
            output = short_cut + x
        else:
            output = x
        return output


class Residual(Module):
    def __init__(self, c, num_block, groups, kernel=(3, 3), stride=(1, 1), padding=(1, 1)):
        super(Residual, self).__init__()
        modules = []
        for _ in range(num_block):
            modules.append(DepthWise(c, c, True, kernel, stride, padding, groups))
        self.layers = Sequential(*modules)

    def forward(self, x):
        return self.layers(x)


class GDC(Module):
    def __init__(self, embedding_size):
        super(GDC, self).__init__()
        self.layers = nn.Sequential(
            LinearBlock(512, 512, groups=512, kernel=(7, 7), stride=(1, 1), padding=(0, 0)),
            Flatten(),
            Linear(512, embedding_size, bias=False),
            BatchNorm1d(embedding_size))

    def forward(self, x):
        return self.layers(x)


class MobileFaceNet(Module):
    def __init__(self, fp16=False, num_features=512, blocks=(1, 4, 6, 2), scale=2):
        super(MobileFaceNet, self).__init__()
        self.scale = scale
        self.fp16 = fp16
        self.layers = nn.ModuleList()
        self.layers.append(
            ConvBlock(3, 64 * self.scale, kernel=(3, 3), stride=(2, 2), padding=(1, 1))
        )
        if blocks[0] == 1:
            self.layers.append(
                ConvBlock(64 * self.scale, 64 * self.scale, kernel=(3, 3), stride=(1, 1), padding=(1, 1), groups=64)
            )
        else:
            self.layers.append(
                Residual(64 * self.scale, num_block=blocks[0], groups=128, kernel=(3, 3), stride=(1, 1), padding=(1, 1)),
            )
        
        self.layers.extend(
        [
            DepthWise(64 * self.scale, 64 * self.scale, kernel=(3, 3), stride=(2, 2), padding=(1, 1), groups=128),
            Residual(64 * self.scale, num_block=blocks[1], groups=128, kernel=(3, 3), stride=(1, 1), padding=(1, 1)),
            DepthWise(64 * self.scale, 128 * self.scale, kernel=(3, 3), stride=(2, 2), padding=(1, 1), groups=256),
            Residual(128 * self.scale, num_block=blocks[2], groups=256, kernel=(3, 3), stride=(1, 1), padding=(1, 1)),
            DepthWise(128 * self.scale, 128 * self.scale, kernel=(3, 3), stride=(2, 2), padding=(1, 1), groups=512),
            Residual(128 * self.scale, num_block=blocks[3], groups=256, kernel=(3, 3), stride=(1, 1), padding=(1, 1)),
        ])

        self.conv_sep = ConvBlock(128 * self.scale, 512, kernel=(1, 1), stride=(1, 1), padding=(0, 0))
        self.features = GDC(num_features)
        self._initialize_weights()

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    m.bias.data.zero_()

    def forward(self, x):
        with torch.cuda.amp.autocast(self.fp16):
            for func in self.layers:
                x = func(x)
        x = self.conv_sep(x.float() if self.fp16 else x)
        x = self.features(x)
        return x


def get_mbf(fp16, num_features, blocks=(1, 4, 6, 2), scale=2):
    return MobileFaceNet(fp16, num_features, blocks, scale=scale)

def get_mbf_large(fp16, num_features, blocks=(2, 8, 12, 4), scale=4):
    return MobileFaceNet(fp16, num_features, blocks, scale=scale)


================================================
FILE: face_module/TopoFR/configs/__init__.py
================================================


================================================
FILE: face_module/TopoFR/configs/base.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()

# Margin Base Softmax
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r50"
config.resume = False
config.save_all_states = False
config.output = "ms1mv3_arcface_r50"

config.embedding_size = 512

# Partial FC
config.sample_rate = 1
config.interclass_filtering_threshold = 0

config.fp16 = False
config.batch_size = 128

# For SGD 
config.optimizer = "sgd"
config.lr = 0.1
config.momentum = 0.9
config.weight_decay = 5e-4

# For AdamW
# config.optimizer = "adamw"
# config.lr = 0.001
# config.weight_decay = 0.1

config.verbose = 2000
config.frequent = 10

# For Large Sacle Dataset, such as WebFace42M
config.dali = False 

# Gradient ACC
config.gradient_acc = 1

# setup seed
config.seed = 2048

# dataload numworkers
config.num_workers = 2


================================================
FILE: face_module/TopoFR/configs/glint360k_r100.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()
#config.margin_list = (1.0, 0.0, 0.4)
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r100"
config.resume = False
config.output = None
config.embedding_size = 512
config.sample_rate = 1.0
config.fp16 = True
config.momentum = 0.9
config.weight_decay = 1e-4
config.batch_size = 128
config.lr = 0.1
config.verbose = 2000
config.dali = False

config.rec = "/mnt/workspace/glint360"  #glint360k
config.num_classes = 360232
config.num_image = 17091657
config.num_epoch = 25
config.warmup_epoch = 0
config.val_targets = ['lfw', 'cfp_fp', "agedb_30"]

# dataload numworkers
config.num_workers = 4



================================================
FILE: face_module/TopoFR/configs/glint360k_r200.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()
#config.margin_list = (1.0, 0.0, 0.4)
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r200"
config.resume = False
config.output = None
config.embedding_size = 512
config.sample_rate = 1.0
config.fp16 = True
config.momentum = 0.9
config.weight_decay = 1e-4
config.batch_size = 128
config.lr = 0.1
config.verbose = 2000
config.dali = False

config.rec = "/mnt/workspace/glint360"  #glint360k
config.num_classes = 360232
config.num_image = 17091657
config.num_epoch = 30
config.warmup_epoch = 0
config.val_targets = ['lfw', 'cfp_fp', "agedb_30"]

# dataload numworkers
config.num_workers = 4



================================================
FILE: face_module/TopoFR/configs/glint360k_r50.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()
#config.margin_list = (1.0, 0.0, 0.4)
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r50"
config.resume = False
config.output = None
config.embedding_size = 512
config.sample_rate = 1.0
config.fp16 = True
config.momentum = 0.9
config.weight_decay = 1e-4
config.batch_size = 128
config.lr = 0.1
config.verbose = 2000
config.dali = False

config.rec = "/mnt/workspace/glint360"
config.num_classes = 360232
config.num_image = 17091657
config.num_epoch = 25
config.warmup_epoch = 0
config.val_targets = ['lfw', 'cfp_fp', "agedb_30"]

# dataload numworkers
config.num_workers = 4



================================================
FILE: face_module/TopoFR/configs/ms1mv2_r100.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r100"
config.resume = False
config.output = None
config.embedding_size = 512
config.sample_rate = 1.0
config.fp16 = True
config.momentum = 0.9
config.weight_decay = 5e-4
config.batch_size = 128
config.lr = 0.1
config.verbose = 2000
config.dali = False

config.rec = "/mnt/workspace/faces_emore"
config.num_classes = 85742
config.num_image = 5822653
config.num_epoch = 25
config.warmup_epoch = 0
config.val_targets = ['lfw', 'cfp_fp', "agedb_30"]

# dataload numworkers
config.num_workers = 4


================================================
FILE: face_module/TopoFR/configs/ms1mv2_r200.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r200"
config.resume = False
config.output = None
config.embedding_size = 512
config.sample_rate = 1.0
config.fp16 = True
config.momentum = 0.9
config.weight_decay = 5e-4
config.batch_size = 128
config.lr = 0.1
config.verbose = 2000
config.dali = False

config.rec = "/mnt/workspace/faces_emore"
config.num_classes = 85742
config.num_image = 5822653
config.num_epoch = 30
config.warmup_epoch = 0
config.val_targets = ['lfw', 'cfp_fp', "agedb_30"]

# dataload numworkers
config.num_workers = 4


================================================
FILE: face_module/TopoFR/configs/ms1mv2_r50.py
================================================
from easydict import EasyDict as edict

# make training faster
# our RAM is 256G
# mount -t tmpfs -o size=140G  tmpfs /train_tmp

config = edict()
config.margin_list = (1.0, 0.5, 0.0)
config.network = "r50"
config.resume = False
config.output = None
config.embedding_size = 512
config.sample_rate = 1.0
config.fp16 = True
config.momentum = 0.9
config.weight_decay = 5e-4
config.batch_size = 128
config.lr = 0.1
config.verbose = 2000
config.dali = False

config.rec = "/mnt/workspace/faces_emore"
config.num_classes = 85742
config.num_image = 5822653
config.num_epoch = 30
config.warmup_epoch = 0
config.val_targets = ['lfw', 'cfp_fp', "agedb_30"]

# dataload numworkers
config.num_workers = 4


================================================
FILE: face_module/TopoFR/dataset.py
================================================
import numbers
import os
import queue as Queue
import threading
from typing import Iterable

import mxnet as mx
import numpy as np
import torch
from functools import partial
from torch import distributed
from torch.utils.data import DataLoader, Dataset
from torchvision import transforms
from torchvision.datasets import ImageFolder
from utils.utils_distributed_sampler import DistributedSampler
from utils.utils_distributed_sampler import get_dist_info, worker_init_fn


def get_dataloader(
    root_dir,
    local_rank,
    batch_size,
    dali = False,
    seed = 2048,
    #num_workers = 2,
    num_workers = 0,
    ) -> Iterable:

    rec = os.path.join(root_dir, 'train.rec')
    idx = os.path.join(root_dir, 'train.idx')
    train_set = None

    # Synthetic
    if root_dir == "synthetic":
        train_set = SyntheticDataset()
        dali = False

    # Mxnet RecordIO   ## data_loader this way
    elif os.path.exists(rec) and os.path.exists(idx):
        train_set = MXFaceDataset(root_dir=root_dir, local_rank=local_rank)

    # Image Folder
    else:
        transform = transforms.Compose([
             transforms.RandomHorizontalFlip(),
             transforms.ToTensor(),
             transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
             ])
        train_set = ImageFolder(root_dir, transform)

    # DALI
    if dali:
        return dali_data_iter(
            batch_size=batch_size, rec_file=rec, idx_file=idx,
            num_threads=2, local_rank=local_rank)

    rank, world_size = get_dist_info()
    train_sampler = DistributedSampler(
        train_set, num_replicas=world_size, rank=rank, shuffle=True, seed=seed)

    if seed is None:
        init_fn = None
    else:
        init_fn = partial(worker_init_fn, num_workers=num_workers, rank=rank, seed=seed)

    train_loader = DataLoaderX(
        local_rank=local_rank,
        dataset=train_set,
        batch_size=batch_size,
        sampler=train_sampler,
        num_workers=num_workers,
        pin_memory=True,
        drop_last=True,
        worker_init_fn=init_fn,
    )

    return train_loader

class BackgroundGenerator(threading.Thread):
    def __init__(self, generator, local_rank, max_prefetch=6):
        super(BackgroundGenerator, self).__init__()
        self.queue = Queue.Queue(max_prefetch)
        self.generator = generator
        self.local_rank = local_rank
        self.daemon = True
        self.start()

    def run(self):
        torch.cuda.set_device(self.local_rank)
        for item in self.generator:
            self.queue.put(item)
        self.queue.put(None)

    def next(self):
        next_item = self.queue.get()
        if next_item is None:
            raise StopIteration
        return next_item

    def __next__(self):
        return self.next()

    def __iter__(self):
        return self


class DataLoaderX(DataLoader):

    def __init__(self, local_rank, **kwargs):
        super(DataLoaderX, self).__init__(**kwargs)
        self.stream = torch.cuda.Stream(local_rank)
        self.local_rank = local_rank

    def __iter__(self):
        self.iter = super(DataLoaderX, self).__iter__()
        self.iter = BackgroundGenerator(self.iter, self.local_rank)
        self.preload()
        return self

    def preload(self):
        self.batch = next(self.iter, None)
        if self.batch is None:
            return None
        with torch.cuda.stream(self.stream):
            for k in range(len(self.batch)):
                self.batch[k] = self.batch[k].to(device=self.local_rank, non_blocking=True)

    def __next__(self):
        torch.cuda.current_stream().wait_stream(self.stream)
        batch = self.batch
        if batch is None:
            raise StopIteration
        self.preload()
        return batch


class MXFaceDataset(Dataset):         ##
    def __init__(self, root_dir, local_rank):
        super(MXFaceDataset, self).__init__()
        self.transform = transforms.Compose(
            [transforms.ToPILImage(),
             transforms.RandomHorizontalFlip(),
             transforms.ToTensor(),
             transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
             ])
        self.root_dir = root_dir
        self.local_rank = local_rank
        path_imgrec = os.path.join(root_dir, 'train.rec')
        path_imgidx = os.path.join(root_dir, 'train.idx')
        self.imgrec = mx.recordio.MXIndexedRecordIO(path_imgidx, path_imgrec, 'r')
        s = self.imgrec.read_idx(0)
        header, _ = mx.recordio.unpack(s)
        if header.flag > 0:
            self.header0 = (int(header.label[0]), int(header.label[1]))
            self.imgidx = np.array(range(1, int(header.label[0])))
        else:
            self.imgidx = np.array(list(self.imgrec.keys))

    def __getitem__(self, index):
        idx = self.imgidx[index]
        s = self.imgrec.read_idx(idx)
        header, img = mx.recordio.unpack(s)
        label = header.label
        if not isinstance(label, numbers.Number):
            label = label[0]
        label = torch.tensor(label, dtype=torch.long)
        sample = mx.image.imdecode(img).asnumpy()
        if self.transform is not None:
            sample = self.transform(sample)
        return sample, label

    def __len__(self):
        return len(self.imgidx)


class SyntheticDataset(Dataset):
    def __init__(self):
        super(SyntheticDataset, self).__init__()
        img = np.random.randint(0, 255, size=(112, 112, 3), dtype=np.int32)
        img = np.transpose(img, (2, 0, 1))
        img = torch.from_numpy(img).squeeze(0).float()
        img = ((img / 255) - 0.5) / 0.5
        self.img = img
        self.label = 1

    def __getitem__(self, index):
        return self.img, self.label

    def __len__(self):
        return 1000000


def dali_data_iter(
    batch_size: int, rec_file: str, idx_file: str, num_threads: int,
    initial_fill=32768, random_shuffle=True,
    prefetch_queue_depth=1, local_rank=0, name="reader",
    mean=(127.5, 127.5, 127.5), 
    std=(127.5, 127.5, 127.5)):
    """
    Parameters:
    ----------
    initial_fill: int
        Size of the buffer that is used for shuffling. If random_shuffle is False, this parameter is ignored.

    """
    rank: int = distributed.get_rank()
    world_size: int = distributed.get_world_size()
    import nvidia.dali.fn as fn
    import nvidia.dali.types as types
    from nvidia.dali.pipeline import Pipeline
    from nvidia.dali.plugin.pytorch import DALIClassificationIterator

    pipe = Pipeline(
        batch_size=batch_size, num_threads=num_threads,
        device_id=local_rank, prefetch_queue_depth=prefetch_queue_depth, )
    condition_flip = fn.random.coin_flip(probability=0.5)
    with pipe:
        jpegs, labels = fn.readers.mxnet(
            path=rec_file, index_path=idx_file, initial_fill=initial_fill, 
            num_shards=world_size, shard_id=rank,
            random_shuffle=random_shuffle, pad_last_batch=False, name=name)
        images = fn.decoders.image(jpegs, device="mixed", output_type=types.RGB)
        images = fn.crop_mirror_normalize(
            images, dtype=types.FLOAT, mean=mean, std=std, mirror=condition_flip)
        pipe.set_outputs(images, labels)
    pipe.build()
    return DALIWarper(DALIClassificationIterator(pipelines=[pipe], reader_name=name, ))


@torch.no_grad()
class DALIWarper(object):
    def __init__(self, dali_iter):
        self.iter = dali_iter

    def __next__(self):
        data_dict = self.iter.__next__()[0]
        tensor_data = data_dict['data'].cuda()
        tensor_label: torch.Tensor = data_dict['label'].cuda().long()
        tensor_label.squeeze_()
        return tensor_data, tensor_label

    def __iter__(self):
        return self

    def reset(self):
        self.iter.reset()


================================================
FILE: face_module/TopoFR/docs/eval.md
================================================
## Eval on ICCV2021-MFR

coming soon.


## Eval IJBC
You can eval ijbc with pytorch or onnx.


1. Eval IJBC With Onnx
```shell
CUDA_VISIBLE_DEVICES=0 python onnx_ijbc.py --model-root ms1mv3_arcface_r50 --image-path IJB_release/IJBC --result-dir ms1mv3_arcface_r50
```

2. Eval IJBC With Pytorch
```shell
CUDA_VISIBLE_DEVICES=0,1 python eval_ijbc.py \
--model-prefix ms1mv3_arcface_r50/backbone.pth \
--image-path IJB_release/IJBC \
--result-dir ms1mv3_arcface_r50 \
--batch-size 128 \
--job ms1mv3_arcface_r50 \
--target IJBC \
--network iresnet50
```


## Inference

```shell
python inference.py --weight ms1mv3_arcface_r50/backbone.pth --network r50
```


## Result

| Datasets       | Backbone            | **MFR-ALL** | IJB-C(1E-4) | IJB-C(1E-5) |
|:---------------|:--------------------|:------------|:------------|:------------|
| WF12M-PFC-0.05 | r100                | 94.05       | 97.51       | 95.75       |
| WF12M-PFC-0.1  | r100                | 94.49       | 97.56       | 95.92       |
| WF12M-PFC-0.2  | r100                | 94.75       | 97.60       | 95.90       |
| WF12M-PFC-0.3  | r100                | 94.71       | 97.64       | 96.01       |
| WF12M          | r100                | 94.69       | 97.59       | 95.97       |

================================================
FILE: face_module/TopoFR/docs/install.md
================================================
## [v1.11.0](https://pytorch.org/)

## [v1.9.0](https://pytorch.org/get-started/previous-versions/#linux-and-windows-7)
### Linux and Windows  
```shell
# CUDA 11.1
pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html

# CUDA 10.2
pip install torch==1.9.0+cu102 torchvision==0.10.0+cu102 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html
```


================================================
FILE: face_module/TopoFR/docs/install_dali.md
================================================
TODO


================================================
FILE: face_module/TopoFR/docs/modelzoo.md
================================================


================================================
FILE: face_module/TopoFR/docs/prepare_webface42m.md
================================================



## 1. Download Datasets and Unzip

Download WebFace42M from [https://www.face-benchmark.org/download.html](https://www.face-benchmark.org/download.html).  
The raw data of `WebFace42M` will have 10 directories after being unarchived:   
`WebFace4M` contains 1 directory: `0`.  
`WebFace12M` contains 3 directories: `0,1,2`.  
`WebFace42M` contains 10 directories: `0,1,2,3,4,5,6,7,8,9`.

## 2. Create Shuffled Rec File for DALI

Note: Shuffled rec is very important to DALI, and rec without shuffled can cause performance degradation, origin insightface style rec file 
do not support Nvidia DALI, you must follow this command [mxnet.tools.im2rec](https://github.com/apache/incubator-mxnet/blob/master/tools/im2rec.py) to generate a shuffled rec file.

```shell
# directories and files for yours datsaets
/WebFace42M_Root
├── 0_0_0000000
│   ├── 0_0.jpg
│   ├── 0_1.jpg
│   ├── 0_2.jpg
│   ├── 0_3.jpg
│   └── 0_4.jpg
├── 0_0_0000001
│   ├── 0_5.jpg
│   ├── 0_6.jpg
│   ├── 0_7.jpg
│   ├── 0_8.jpg
│   └── 0_9.jpg
├── 0_0_0000002
│   ├── 0_10.jpg
│   ├── 0_11.jpg
│   ├── 0_12.jpg
│   ├── 0_13.jpg
│   ├── 0_14.jpg
│   ├── 0_15.jpg
│   ├── 0_16.jpg
│   └── 0_17.jpg
├── 0_0_0000003
│   ├── 0_18.jpg
│   ├── 0_19.jpg
│   └── 0_20.jpg
├── 0_0_0000004



# 1) create train.lst using follow command
python -m mxnet.tools.im2rec --list --recursive train WebFace42M_Root

# 2) create train.rec and train.idx using train.lst using following command
python -m mxnet.tools.im2rec --num-thread 16 --quality 100 train WebFace42M_Root
```

Finally, you will get three files: `train.lst`, `train.rec`, `train.idx`. which `train.idx`, `train.rec` are using for training.


================================================
FILE: face_module/TopoFR/docs/speed_benchmark.md
================================================
## Test Training Speed

- Test Commands

You need to use the following two commands to test the Partial FC training performance. 
The number of identites is **3 millions** (synthetic data), turn mixed precision  training on, backbone is resnet50, 
batch size is 1024.
```shell
# Model Parallel
python -m torch.distributed.launch --nproc_per_node=8 --nnodes=1 --node_rank=0 --master_addr="127.0.0.1" --master_port=1234 train.py configs/3millions
# Partial FC 0.1
python -m torch.distributed.launch --nproc_per_node=8 --nnodes=1 --node_rank=0 --master_addr="127.0.0.1" --master_port=1234 train.py configs/3millions_pfc
```

- GPU Memory

```
# (Model Parallel) gpustat -i
[0] Tesla V100-SXM2-32GB | 64'C,  94 % | 30338 / 32510 MB 
[1] Tesla V100-SXM2-32GB | 60'C,  99 % | 28876 / 32510 MB 
[2] Tesla V100-SXM2-32GB | 60'C,  99 % | 28872 / 32510 MB 
[3] Tesla V100-SXM2-32GB | 69'C,  99 % | 28872 / 32510 MB 
[4] Tesla V100-SXM2-32GB | 66'C,  99 % | 28888 / 32510 MB 
[5] Tesla V100-SXM2-32GB | 60'C,  99 % | 28932 / 32510 MB 
[6] Tesla V100-SXM2-32GB | 68'C, 100 % | 28916 / 32510 MB 
[7] Tesla V100-SXM2-32GB | 65'C,  99 % | 28860 / 32510 MB 

# (Partial FC 0.1) gpustat -i
[0] Tesla V100-SXM2-32GB | 60'C,  95 % | 10488 / 32510 MB                                                                                                                                          │·······················
[1] Tesla V100-SXM2-32GB | 60'C,  97 % | 10344 / 32510 MB                                                                                                                                          │·······················
[2] Tesla V100-SXM2-32GB | 61'C,  95 % | 10340 / 32510 MB                                                                                                                                          │·······················
[3] Tesla V100-SXM2-32GB | 66'C,  95 % | 10340 / 32510 MB                                                                                                                                          │·······················
[4] Tesla V100-SXM2-32GB | 65'C,  94 % | 10356 / 32510 MB                                                                                                                                          │·······················
[5] Tesla V100-SXM2-32GB | 61'C,  95 % | 10400 / 32510 MB                                                                                                                                          │·······················
[6] Tesla V100-SXM2-32GB | 68'C,  96 % | 10384 / 32510 MB                                                                                                                                          │·······················
[7] Tesla V100-SXM2-32GB | 64'C,  95 % | 10328 / 32510 MB                                                                                                                                        │·······················
```

- Training Speed

```python
# (Model Parallel) trainging.log
Training: Speed 2271.33 samples/sec   Loss 1.1624   LearningRate 0.2000   Epoch: 0   Global Step: 100 
Training: Speed 2269.94 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 150 
Training: Speed 2272.67 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 200 
Training: Speed 2266.55 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 250 
Training: Speed 2272.54 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 300 

# (Partial FC 0.1) trainging.log
Training: Speed 5299.56 samples/sec   Loss 1.0965   LearningRate 0.2000   Epoch: 0   Global Step: 100  
Training: Speed 5296.37 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 150  
Training: Speed 5304.37 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 200  
Training: Speed 5274.43 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 250  
Training: Speed 5300.10 samples/sec   Loss 0.0000   LearningRate 0.2000   Epoch: 0   Global Step: 300   
```

In this test case, Partial FC 0.1 only use1 1/3 of the GPU memory of the model parallel, 
and the training speed is 2.5 times faster than the model parallel.


## Speed Benchmark

1. Training speed of different parallel methods (samples/second), Tesla V100 32GB * 8. (Larger is better)

| Number of Identities in Dataset | Data Parallel | Model Parallel | Partial FC 0.1 |
| :---    | :--- | :--- | :--- |
|125000   | 4681 | 4824 | 5004 |
|250000   | 4047 | 4521 | 4976 |
|500000   | 3087 | 4013 | 4900 |
|1000000  | 2090 | 3449 | 4803 |
|1400000  | 1672 | 3043 | 4738 |
|2000000  | -    | 2593 | 4626 |
|4000000  | -    | 1748 | 4208 |
|5500000  | -    | 1389 | 3975 |
|8000000  | -    | -    | 3565 |
|16000000 | -    | -    | 2679 |
|29000000 | -    | -    | 1855 |

2. GPU memory cost of different parallel methods (GB per GPU), Tesla V100 32GB * 8. (Smaller is better)

| Number of Identities in Dataset | Data Parallel | Model Parallel | Partial FC 0.1 |
| :---    | :---  | :---  | :---  |
|125000   | 7358  | 5306  | 4868  |
|250000   | 9940  | 5826  | 5004  |
|500000   | 14220 | 7114  | 5202  |
|1000000  | 23708 | 9966  | 5620  |
|1400000  | 32252 | 11178 | 6056  |
|2000000  | -     | 13978 | 6472  |
|4000000  | -     | 23238 | 8284  |
|5500000  | -     | 32188 | 9854  |
|8000000  | -     | -     | 12310 |
|16000000 | -     | -     | 19950 |
|29000000 | -     | -     | 32324 |


================================================
FILE: face_module/TopoFR/eval/__init__.py
================================================


================================================
FILE: face_module/TopoFR/eval/verification.py
================================================
"""Helper for evaluation on the Labeled Faces in the Wild dataset 
"""

# MIT License
#
# Copyright (c) 2016 David Sandberg
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


import datetime
import os
import pickle

import mxnet as mx
import numpy as np
import sklearn
import torch
from mxnet import ndarray as nd
from scipy import interpolate
from sklearn.decomposition import PCA
from sklearn.model_selection import KFold


class LFold:
    def __init__(self, n_splits=2, shuffle=False):
        self.n_splits = n_splits
        if self.n_splits > 1:
            self.k_fold = KFold(n_splits=n_splits, shuffle=shuffle)

    def split(self, indices):
        if self.n_splits > 1:
            return self.k_fold.split(indices)
        else:
            return [(indices, indices)]


def calculate_roc(thresholds,
                  embeddings1,
                  embeddings2,
                  actual_issame,
                  nrof_folds=10,
                  pca=0):
    assert (embeddings1.shape[0] == embeddings2.shape[0])
    assert (embeddings1.shape[1] == embeddings2.shape[1])
    nrof_pairs = min(len(actual_issame), embeddings1.shape[0])
    nrof_thresholds = len(thresholds)
    k_fold = LFold(n_splits=nrof_folds, shuffle=False)

    tprs = np.zeros((nrof_folds, nrof_thresholds))
    fprs = np.zeros((nrof_folds, nrof_thresholds))
    accuracy = np.zeros((nrof_folds))
    indices = np.arange(nrof_pairs)

    if pca == 0:
        diff = np.subtract(embeddings1, embeddings2)
        dist = np.sum(np.square(diff), 1)

    for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):
        if pca > 0:
            print('doing pca on', fold_idx)
            embed1_train = embeddings1[train_set]
            embed2_train = embeddings2[train_set]
            _embed_train = np.concatenate((embed1_train, embed2_train), axis=0)
            pca_model = PCA(n_components=pca)
            pca_model.fit(_embed_train)
            embed1 = pca_model.transform(embeddings1)
            embed2 = pca_model.transform(embeddings2)
            embed1 = sklearn.preprocessing.normalize(embed1)
            embed2 = sklearn.preprocessing.normalize(embed2)
            diff = np.subtract(embed1, embed2)
            dist = np.sum(np.square(diff), 1)

        # Find the best threshold for the fold
        acc_train = np.zeros((nrof_thresholds))
        for threshold_idx, threshold in enumerate(thresholds):
            _, _, acc_train[threshold_idx] = calculate_accuracy(
                threshold, dist[train_set], actual_issame[train_set])
        best_threshold_index = np.argmax(acc_train)
        for threshold_idx, threshold in enumerate(thresholds):
            tprs[fold_idx, threshold_idx], fprs[fold_idx, threshold_idx], _ = calculate_accuracy(
                threshold, dist[test_set],
                actual_issame[test_set])
        _, _, accuracy[fold_idx] = calculate_accuracy(
            thresholds[best_threshold_index], dist[test_set],
            actual_issame[test_set])

    tpr = np.mean(tprs, 0)
    fpr = np.mean(fprs, 0)
    return tpr, fpr, accuracy


def calculate_accuracy(threshold, dist, actual_issame):
    predict_issame = np.less(dist, threshold)
    tp = np.sum(np.logical_and(predict_issame, actual_issame))
    fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))
    tn = np.sum(
        np.logical_and(np.logical_not(predict_issame),
                       np.logical_not(actual_issame)))
    fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame))

    tpr = 0 if (tp + fn == 0) else float(tp) / float(tp + fn)
    fpr = 0 if (fp + tn == 0) else float(fp) / float(fp + tn)
    acc = float(tp + tn) / dist.size
    return tpr, fpr, acc


def calculate_val(thresholds,
                  embeddings1,
                  embeddings2,
                  actual_issame,
                  far_target,
                  nrof_folds=10):
    assert (embeddings1.shape[0] == embeddings2.shape[0])
    assert (embeddings1.shape[1] == embeddings2.shape[1])
    nrof_pairs = min(len(actual_issame), embeddings1.shape[0])
    nrof_thresholds = len(thresholds)
    k_fold = LFold(n_splits=nrof_folds, shuffle=False)

    val = np.zeros(nrof_folds)
    far = np.zeros(nrof_folds)

    diff = np.subtract(embeddings1, embeddings2)
    dist = np.sum(np.square(diff), 1)
    indices = np.arange(nrof_pairs)

    for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):

        # Find the threshold that gives FAR = far_target
        far_train = np.zeros(nrof_thresholds)
        for threshold_
Download .txt
gitextract_95kbsdu1/

├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── README_ZH.md
├── app.py
├── face_adapter/
│   ├── __init__.py
│   ├── face_adapter_v1.py
│   ├── face_attention_processor_v1.py
│   ├── face_preprocess.py
│   ├── utils.py
│   └── vit.py
├── face_module/
│   ├── DamoFD/
│   │   └── README.md
│   ├── TopoFR/
│   │   ├── GUM.py
│   │   ├── README.md
│   │   ├── backbones/
│   │   │   ├── __init__.py
│   │   │   ├── iresnet.py
│   │   │   ├── iresnet2060.py
│   │   │   └── mobilefacenet.py
│   │   ├── configs/
│   │   │   ├── __init__.py
│   │   │   ├── base.py
│   │   │   ├── glint360k_r100.py
│   │   │   ├── glint360k_r200.py
│   │   │   ├── glint360k_r50.py
│   │   │   ├── ms1mv2_r100.py
│   │   │   ├── ms1mv2_r200.py
│   │   │   └── ms1mv2_r50.py
│   │   ├── dataset.py
│   │   ├── docs/
│   │   │   ├── eval.md
│   │   │   ├── install.md
│   │   │   ├── install_dali.md
│   │   │   ├── modelzoo.md
│   │   │   ├── prepare_webface42m.md
│   │   │   └── speed_benchmark.md
│   │   ├── eval/
│   │   │   ├── __init__.py
│   │   │   └── verification.py
│   │   ├── eval_ijbc_glint360k.py
│   │   ├── eval_ijbc_ms1mv2.py
│   │   ├── flops.py
│   │   ├── inference.py
│   │   ├── losses.py
│   │   ├── lr_scheduler.py
│   │   ├── onnx_helper.py
│   │   ├── onnx_ijbc.py
│   │   ├── partial_fc.py
│   │   ├── persistent_homology.py
│   │   ├── requirement.txt
│   │   ├── topology.py
│   │   ├── torch2onnx.py
│   │   ├── train.py
│   │   └── utils/
│   │       ├── __init__.py
│   │       ├── plot.py
│   │       ├── utils_callbacks.py
│   │       ├── utils_config.py
│   │       ├── utils_distributed_sampler.py
│   │       └── utils_logging.py
│   └── TransFace/
│       ├── FFT.py
│       ├── README.md
│       ├── backbones/
│       │   ├── __init__.py
│       │   ├── iresnet.py
│       │   ├── iresnet2060.py
│       │   ├── mobilefacenet.py
│       │   └── vit.py
│       ├── configs/
│       │   ├── __init__.py
│       │   ├── base.py
│       │   ├── glint360k_vit_s.py
│       │   └── ms1mv2_vit_s.py
│       ├── dataset.py
│       ├── dist.sh
│       ├── docs/
│       │   ├── eval.md
│       │   ├── install.md
│       │   ├── install_dali.md
│       │   ├── modelzoo.md
│       │   ├── prepare_webface42m.md
│       │   └── speed_benchmark.md
│       ├── eval/
│       │   ├── __init__.py
│       │   └── verification.py
│       ├── eval_ijbc.py
│       ├── flops.py
│       ├── inference.py
│       ├── losses.py
│       ├── lr_scheduler.py
│       ├── onnx_helper.py
│       ├── onnx_ijbc.py
│       ├── partial_fc_exp.py
│       ├── requirement.txt
│       ├── run.sh
│       ├── torch2onnx.py
│       ├── train.py
│       └── utils/
│           ├── __init__.py
│           ├── plot.py
│           ├── utils_callbacks.py
│           ├── utils_config.py
│           ├── utils_distributed_sampler.py
│           └── utils_logging.py
├── facechain/
│   ├── constants.py
│   ├── inference_fact.py
│   ├── inference_inpaint_fact.py
│   ├── merge_lora.py
│   └── utils.py
├── install.py
├── main.css
├── more_apps/
│   └── Facechain-SuDe/
│       ├── README.md
│       ├── configs/
│       │   ├── autoencoder/
│       │   │   ├── autoencoder_kl_16x16x16.yaml
│       │   │   ├── autoencoder_kl_32x32x4.yaml
│       │   │   ├── autoencoder_kl_64x64x3.yaml
│       │   │   └── autoencoder_kl_8x8x64.yaml
│       │   ├── latent-diffusion/
│       │   │   ├── celebahq-ldm-vq-4.yaml
│       │   │   ├── cin-ldm-vq-f8.yaml
│       │   │   ├── cin256-v2.yaml
│       │   │   ├── ffhq-ldm-vq-4.yaml
│       │   │   ├── lsun_bedrooms-ldm-vq-4.yaml
│       │   │   ├── lsun_churches-ldm-kl-8.yaml
│       │   │   ├── txt2img-1p4B-eval.yaml
│       │   │   ├── txt2img-1p4B-eval_with_tokens.yaml
│       │   │   ├── txt2img-1p4B-finetune.yaml
│       │   │   └── txt2img-1p4B-finetune_style.yaml
│       │   └── stable-diffusion/
│       │       ├── v1-finetune_unfrozen.yaml
│       │       └── v1-inference.yaml
│       ├── environment.yaml
│       ├── ldm/
│       │   ├── data/
│       │   │   ├── __init__.py
│       │   │   ├── base.py
│       │   │   ├── imagenet.py
│       │   │   ├── lsun.py
│       │   │   ├── personalized.py
│       │   │   └── personalized_style.py
│       │   ├── lr_scheduler.py
│       │   ├── models/
│       │   │   ├── autoencoder.py
│       │   │   └── diffusion/
│       │   │       ├── __init__.py
│       │   │       ├── classifier.py
│       │   │       ├── ddim.py
│       │   │       ├── ddpm.py
│       │   │       └── plms.py
│       │   ├── modules/
│       │   │   ├── attention.py
│       │   │   ├── diffusionmodules/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── model.py
│       │   │   │   ├── openaimodel.py
│       │   │   │   └── util.py
│       │   │   ├── distributions/
│       │   │   │   ├── __init__.py
│       │   │   │   └── distributions.py
│       │   │   ├── ema.py
│       │   │   ├── embedding_manager.py
│       │   │   ├── encoders/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── modules.py
│       │   │   │   └── modules_bak.py
│       │   │   ├── image_degradation/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── bsrgan.py
│       │   │   │   ├── bsrgan_light.py
│       │   │   │   └── utils_image.py
│       │   │   ├── losses/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── contperceptual.py
│       │   │   │   └── vqperceptual.py
│       │   │   └── x_transformer.py
│       │   └── util.py
│       ├── main.py
│       ├── main.sh
│       ├── merge_embeddings.py
│       ├── scripts/
│       │   ├── download_first_stages.sh
│       │   ├── download_models.sh
│       │   ├── evaluate_model.py
│       │   ├── inpaint.py
│       │   ├── latent_imagenet_diffusion.ipynb
│       │   ├── sample_diffusion.py
│       │   ├── stable_txt2img.py
│       │   └── txt2img.py
│       └── setup.py
├── run_inference.py
├── run_inference_inpaint.py
├── scripts/
│   └── facechain_sdwebui.py
├── styles/
│   ├── MajicmixRealistic_v6/
│   │   ├── Autumn_populus.json
│   │   ├── Bleak_autumn.json
│   │   ├── Cartoon.json
│   │   ├── Cheongsam.json
│   │   ├── Chinese_New_Year.json
│   │   ├── Chinese_winter_hanfu.json
│   │   ├── Christmas.json
│   │   ├── Colorful_rainbow.json
│   │   ├── Cool_tones.json
│   │   ├── Cowboy.json
│   │   ├── Deer_girl.json
│   │   ├── Disneyland.json
│   │   ├── DreamyOcean.json
│   │   ├── Dunhuang.json
│   │   ├── Duobaan.json
│   │   ├── Embroidery.json
│   │   ├── European_fields.json
│   │   ├── Fairy_style.json
│   │   ├── Fashion_glasses.json
│   │   ├── Flame_red_style.json
│   │   ├── Flowers.json
│   │   ├── Gentleman.json
│   │   ├── GuoFeng.json
│   │   ├── Hiphop.json
│   │   ├── Hong_Kong_night_style.json
│   │   ├── India.json
│   │   ├── Jacket_in_Snow_Mountain.json
│   │   ├── Kimono.json
│   │   ├── Li.json
│   │   ├── Lolita.json
│   │   ├── Luolita.json
│   │   ├── Maid.json
│   │   ├── Mechnical.json
│   │   ├── Men_suit.json
│   │   ├── Miaozu.json
│   │   ├── Model_style.json
│   │   ├── Mongolian.json
│   │   ├── Motorcycle_race_style.json
│   │   ├── Ocean_Summer_vibe.json
│   │   ├── PekingOpera_female_role.json
│   │   ├── Polaroid_style.json
│   │   ├── Princess_style.json
│   │   ├── Rainy_night.json
│   │   ├── Redstyle.json
│   │   ├── Retro_style.json
│   │   ├── Roaming_Astronaut.json
│   │   ├── School_uniform.json
│   │   ├── Science_fiction.json
│   │   ├── Soccer.json
│   │   ├── Street_style.json
│   │   ├── Tibetan_clothing.json
│   │   ├── Traditional_chinese_style.json
│   │   ├── Tyndall.json
│   │   ├── Underwater.json
│   │   ├── Wedding_dress.json
│   │   ├── Wedding_dress_2.json
│   │   ├── West_cowboy.json
│   │   ├── Wild_west.json
│   │   ├── Witch.json
│   │   ├── Wizard_of_Oz.json
│   │   ├── ZangZu.json
│   │   └── Zhuang_style.json
│   └── leosamsMoonfilm_filmGrain20/
│       ├── Armor.json
│       ├── Barbie_Doll.json
│       ├── Casual_Lifestyle.json
│       ├── Chinese_traditional_gorgeous_suit.json
│       ├── Cybernetics_punk.json
│       ├── Elegant_Princess.json
│       ├── Gown.json
│       ├── Hanfu.json
│       ├── Innocent_Girl_in_White_Dress.json
│       ├── Pixy_Girl.json
│       ├── Snow_white.json
│       ├── T-shirt.json
│       └── Working_suit.json
└── train_style/
    ├── __init__.py
    ├── convert_lora.py
    ├── deepbooru.py
    ├── demo.py
    └── train_text_to_image_lora.py
Download .txt
SYMBOL INDEX (1328 symbols across 97 files)

FILE: app.py
  class UploadTarget (line 32) | class UploadTarget(enum.Enum):
  function concatenate_images (line 38) | def concatenate_images(images):
  function select_function (line 50) | def select_function(evt: gr.SelectData):
  function select_function_multi (line 56) | def select_function_multi(evt: gr.SelectData):
  function get_selected_image (line 61) | def get_selected_image(state_image_list, evt: gr.SelectData):
  function upload_file (line 64) | def upload_file(files, current_files):
  function update_prompt (line 69) | def update_prompt(style_model, style_choice, uuid):
  function update_pose_model (line 92) | def update_pose_model(pose_image, pose_model):
  function generate_pos_prompt (line 103) | def generate_pos_prompt(style_model, prompt_cloth):
  function launch_pipeline (line 118) | def launch_pipeline(uuid,
  function launch_pipeline_inpaint (line 190) | def launch_pipeline_inpaint(uuid,
  function update_lora_choice (line 238) | def update_lora_choice(uuid):
  function upload_lora_file (line 254) | def upload_lora_file(uuid, lora_file):
  function clear_lora_file (line 275) | def clear_lora_file(uuid, lora_file):
  function change_lora_choice (line 285) | def change_lora_choice(lora_choice):
  function change_style_choice (line 294) | def change_style_choice(uuid, style_choice):
  function select_trained_style (line 311) | def select_trained_style(trained_styles):
  function get_tag (line 314) | def get_tag(imgs):
  function modify_tag (line 326) | def modify_tag(gallery, impath, tag):
  function inference_input (line 335) | def inference_input():
  function inference_inpaint (line 450) | def inference_inpaint():
  function train_input (line 506) | def train_input():

FILE: face_adapter/face_adapter_v1.py
  function detect (line 28) | def detect(image, face_detection):
  function get_mask_head (line 37) | def get_mask_head(result):
  function align (line 73) | def align(image, points_vec):
  function face_image_preprocess (line 77) | def face_image_preprocess(image, segmentation_pipeline, face_detection):
  class Face_Transformer (line 85) | class Face_Transformer(nn.Module):
    method __init__ (line 86) | def __init__(self, name='vits', weight='./ms1mv2_model_TransFace_S.pt'):
    method forward (line 105) | def forward(self, img):
  function FeedForward (line 111) | def FeedForward(dim, mult=4):
  function reshape_tensor (line 121) | def reshape_tensor(x, heads):
  class PerceiverAttention (line 132) | class PerceiverAttention(nn.Module):
    method __init__ (line 133) | def __init__(self, *, dim, dim_head=64, heads=8):
    method forward (line 148) | def forward(self, x, latents):
  class Face_Prj_Resampler (line 180) | class Face_Prj_Resampler(nn.Module):
    method __init__ (line 181) | def __init__(
    method forward (line 212) | def forward(self, x):
  class Face_Extracter_v1 (line 228) | class Face_Extracter_v1(nn.Module):
    method __init__ (line 229) | def __init__(self, fr_weight_path, fc_weight_path):
    method forward (line 241) | def forward(self, face_img):
  class Identity (line 253) | class Identity(nn.Module):
    method __init__ (line 254) | def __init__(self):
    method forward (line 257) | def forward(self, x):
  class FaceAdapter_v1 (line 261) | class FaceAdapter_v1:
    method __init__ (line 263) | def __init__(self, sd_pipe, face_detection, segmentation_pipeline, fac...
    method set_adapter (line 284) | def set_adapter(self):
    method load_adapter (line 329) | def load_adapter(self):
    method set_scale (line 339) | def set_scale(self, scale):
    method set_num_ims (line 345) | def set_num_ims(self, num_ims):
    method generate (line 360) | def generate(

FILE: face_adapter/face_attention_processor_v1.py
  function exists (line 7) | def exists(val):
  function uniq (line 11) | def uniq(arr):
  function default (line 15) | def default(val, d):
  class GEGLU (line 20) | class GEGLU(nn.Module):
    method __init__ (line 21) | def __init__(self, dim_in, dim_out):
    method forward (line 25) | def forward(self, x):
  class FeedForward (line 29) | class FeedForward(nn.Module):
    method __init__ (line 30) | def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.):
    method forward (line 45) | def forward(self, x):
  class SelfAttention (line 74) | class SelfAttention(nn.Module):
    method __init__ (line 75) | def __init__(self, query_dim, inner_dim, dropout=0.):
    method forward (line 87) | def forward(self, x, attn):
  class AttnProcessor (line 110) | class AttnProcessor(nn.Module):
    method __init__ (line 114) | def __init__(
    method __call__ (line 121) | def __call__(
  class AttnProcessor2_0 (line 181) | class AttnProcessor2_0(nn.Module):
    method __init__ (line 185) | def __init__(
    method __call__ (line 194) | def __call__(
  class FaceAttnProcessor (line 266) | class FaceAttnProcessor(nn.Module):
    method __init__ (line 270) | def __init__(
    method __call__ (line 299) | def __call__(
  class FaceAttnProcessor2_0 (line 398) | class FaceAttnProcessor2_0(nn.Module):
    method __init__ (line 402) | def __init__(
    method __call__ (line 433) | def __call__(
  class CNAttnProcessor2_0 (line 546) | class CNAttnProcessor2_0:
    method __init__ (line 551) | def __init__(self):
    method __call__ (line 557) | def __call__(
  class CNAttnProcessor (line 633) | class CNAttnProcessor:
    method __init__ (line 638) | def __init__(self):
    method __call__ (line 642) | def __call__(

FILE: face_adapter/face_preprocess.py
  function read_image (line 5) | def read_image(img_path, **kwargs):
  function preprocess (line 20) | def preprocess(img, bbox=None, landmark=None, **kwargs):
  function preprocess_3pt (line 88) | def preprocess_3pt(img, bbox=None, landmark=None, **kwargs):

FILE: face_adapter/utils.py
  function is_torch2_available (line 3) | def is_torch2_available():

FILE: face_adapter/vit.py
  class Mlp (line 7) | class Mlp(nn.Module):
    method __init__ (line 8) | def __init__(self, in_features, hidden_features=None, out_features=Non...
    method forward (line 17) | def forward(self, x):
  class VITBatchNorm (line 26) | class VITBatchNorm(nn.Module):
    method __init__ (line 27) | def __init__(self, num_features):
    method forward (line 32) | def forward(self, x):
  class Attention (line 36) | class Attention(nn.Module):
    method __init__ (line 37) | def __init__(self,
    method forward (line 55) | def forward(self, x):
  class Block (line 74) | class Block(nn.Module):
    method __init__ (line 76) | def __init__(self,
    method forward (line 108) | def forward(self, x):
  class PatchEmbed (line 115) | class PatchEmbed(nn.Module):
    method __init__ (line 116) | def __init__(self, img_size=108, patch_size=9, in_channels=3, embed_di...
    method forward (line 128) | def forward(self, x):
  class VisionTransformer (line 137) | class VisionTransformer(nn.Module):
    method __init__ (line 141) | def __init__(self,
    method _init_weights (line 219) | def _init_weights(self, m):
    method no_weight_decay (line 229) | def no_weight_decay(self):
    method get_classifier (line 232) | def get_classifier(self):
    method random_masking (line 235) | def random_masking(self, x, mask_ratio=0.1):
    method forward_features (line 264) | def forward_features(self, x):
    method forward (line 298) | def forward(self, x):

FILE: face_module/TopoFR/GUM.py
  function gauss_unif (line 8) | def gauss_unif(x):

FILE: face_module/TopoFR/backbones/__init__.py
  function get_model (line 5) | def get_model(name, **kwargs):

FILE: face_module/TopoFR/backbones/iresnet.py
  function conv3x3 (line 9) | def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
  function conv1x1 (line 21) | def conv1x1(in_planes, out_planes, stride=1):
  class IBasicBlock (line 30) | class IBasicBlock(nn.Module):
    method __init__ (line 32) | def __init__(self, inplanes, planes, stride=1, downsample=None,
    method forward_impl (line 48) | def forward_impl(self, x):
    method forward (line 61) | def forward(self, x):
  class IResNet (line 68) | class IResNet(nn.Module):
    method __init__ (line 70) | def __init__(self,
    method _make_layer (line 128) | def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
    method forward (line 154) | def forward(self, x, phase='train'):
  function _iresnet (line 181) | def _iresnet(arch, block, layers, pretrained, progress, **kwargs):
  function iresnet18 (line 188) | def iresnet18(pretrained=False, progress=True, **kwargs):
  function iresnet34 (line 193) | def iresnet34(pretrained=False, progress=True, **kwargs):
  function iresnet50 (line 198) | def iresnet50(pretrained=False, progress=True, **kwargs):
  function iresnet100 (line 203) | def iresnet100(pretrained=False, progress=True, **kwargs):
  function iresnet200 (line 208) | def iresnet200(pretrained=False, progress=True, **kwargs):

FILE: face_module/TopoFR/backbones/iresnet2060.py
  function conv3x3 (line 10) | def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
  function conv1x1 (line 22) | def conv1x1(in_planes, out_planes, stride=1):
  class IBasicBlock (line 31) | class IBasicBlock(nn.Module):
    method __init__ (line 34) | def __init__(self, inplanes, planes, stride=1, downsample=None,
    method forward (line 50) | def forward(self, x):
  class IResNet (line 64) | class IResNet(nn.Module):
    method __init__ (line 67) | def __init__(self,
    method _make_layer (line 119) | def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
    method checkpoint (line 145) | def checkpoint(self, func, num_seg, x):
    method forward (line 151) | def forward(self, x):
  function _iresnet (line 168) | def _iresnet(arch, block, layers, pretrained, progress, **kwargs):
  function iresnet2060 (line 175) | def iresnet2060(pretrained=False, progress=True, **kwargs):

FILE: face_module/TopoFR/backbones/mobilefacenet.py
  class Flatten (line 11) | class Flatten(Module):
    method forward (line 12) | def forward(self, x):
  class ConvBlock (line 16) | class ConvBlock(Module):
    method __init__ (line 17) | def __init__(self, in_c, out_c, kernel=(1, 1), stride=(1, 1), padding=...
    method forward (line 25) | def forward(self, x):
  class LinearBlock (line 29) | class LinearBlock(Module):
    method __init__ (line 30) | def __init__(self, in_c, out_c, kernel=(1, 1), stride=(1, 1), padding=...
    method forward (line 37) | def forward(self, x):
  class DepthWise (line 41) | class DepthWise(Module):
    method __init__ (line 42) | def __init__(self, in_c, out_c, residual=False, kernel=(3, 3), stride=...
    method forward (line 51) | def forward(self, x):
  class Residual (line 63) | class Residual(Module):
    method __init__ (line 64) | def __init__(self, c, num_block, groups, kernel=(3, 3), stride=(1, 1),...
    method forward (line 71) | def forward(self, x):
  class GDC (line 75) | class GDC(Module):
    method __init__ (line 76) | def __init__(self, embedding_size):
    method forward (line 84) | def forward(self, x):
  class MobileFaceNet (line 88) | class MobileFaceNet(Module):
    method __init__ (line 89) | def __init__(self, fp16=False, num_features=512, blocks=(1, 4, 6, 2), ...
    method _initialize_weights (line 120) | def _initialize_weights(self):
    method forward (line 134) | def forward(self, x):
  function get_mbf (line 143) | def get_mbf(fp16, num_features, blocks=(1, 4, 6, 2), scale=2):
  function get_mbf_large (line 146) | def get_mbf_large(fp16, num_features, blocks=(2, 8, 12, 4), scale=4):

FILE: face_module/TopoFR/dataset.py
  function get_dataloader (line 19) | def get_dataloader(
  class BackgroundGenerator (line 79) | class BackgroundGenerator(threading.Thread):
    method __init__ (line 80) | def __init__(self, generator, local_rank, max_prefetch=6):
    method run (line 88) | def run(self):
    method next (line 94) | def next(self):
    method __next__ (line 100) | def __next__(self):
    method __iter__ (line 103) | def __iter__(self):
  class DataLoaderX (line 107) | class DataLoaderX(DataLoader):
    method __init__ (line 109) | def __init__(self, local_rank, **kwargs):
    method __iter__ (line 114) | def __iter__(self):
    method preload (line 120) | def preload(self):
    method __next__ (line 128) | def __next__(self):
  class MXFaceDataset (line 137) | class MXFaceDataset(Dataset):         ##
    method __init__ (line 138) | def __init__(self, root_dir, local_rank):
    method __getitem__ (line 159) | def __getitem__(self, index):
    method __len__ (line 172) | def __len__(self):
  class SyntheticDataset (line 176) | class SyntheticDataset(Dataset):
    method __init__ (line 177) | def __init__(self):
    method __getitem__ (line 186) | def __getitem__(self, index):
    method __len__ (line 189) | def __len__(self):
  function dali_data_iter (line 193) | def dali_data_iter(
  class DALIWarper (line 231) | class DALIWarper(object):
    method __init__ (line 232) | def __init__(self, dali_iter):
    method __next__ (line 235) | def __next__(self):
    method __iter__ (line 242) | def __iter__(self):
    method reset (line 245) | def reset(self):

FILE: face_module/TopoFR/eval/verification.py
  class LFold (line 41) | class LFold:
    method __init__ (line 42) | def __init__(self, n_splits=2, shuffle=False):
    method split (line 47) | def split(self, indices):
  function calculate_roc (line 54) | def calculate_roc(thresholds,
  function calculate_accuracy (line 109) | def calculate_accuracy(threshold, dist, actual_issame):
  function calculate_val (line 124) | def calculate_val(thresholds,
  function calculate_val_far (line 165) | def calculate_val_far(threshold, dist, actual_issame):
  function evaluate (line 179) | def evaluate(embeddings, actual_issame, nrof_folds=10, pca=0):
  function load_bin (line 200) | def load_bin(path, image_size):
  function test (line 227) | def test(data_set, backbone, batch_size, nfolds=10):
  function dumpR (line 278) | def dumpR(data_set,

FILE: face_module/TopoFR/eval_ijbc_glint360k.py
  class Embedding (line 56) | class Embedding(object):
    method __init__ (line 57) | def __init__(self, prefix, data_shape, batch_size=1):
    method get (line 79) | def get(self, rimg, landmark):
    method forward_db (line 108) | def forward_db(self, batch_data):
  function divideIntoNstrand (line 118) | def divideIntoNstrand(listTemp, n):
  function read_template_media_list (line 125) | def read_template_media_list(path):
  function read_template_pair_list (line 136) | def read_template_pair_list(path):
  function read_image_feature (line 150) | def read_image_feature(path):
  function get_image_feature (line 159) | def get_image_feature(img_path, files_list, model_path, epoch, gpu_id):
  function image2template_feature (line 217) | def image2template_feature(img_feats=None, templates=None, medias=None):
  function verification (line 257) | def verification(template_norm_feats=None,
  function verification2 (line 287) | def verification2(template_norm_feats=None,
  function read_score (line 311) | def read_score(path):

FILE: face_module/TopoFR/eval_ijbc_ms1mv2.py
  class Embedding (line 56) | class Embedding(object):
    method __init__ (line 57) | def __init__(self, prefix, data_shape, batch_size=1):
    method get (line 78) | def get(self, rimg, landmark):
    method forward_db (line 107) | def forward_db(self, batch_data):
  function divideIntoNstrand (line 117) | def divideIntoNstrand(listTemp, n):
  function read_template_media_list (line 124) | def read_template_media_list(path):
  function read_template_pair_list (line 135) | def read_template_pair_list(path):
  function read_image_feature (line 149) | def read_image_feature(path):
  function get_image_feature (line 158) | def get_image_feature(img_path, files_list, model_path, epoch, gpu_id):
  function image2template_feature (line 216) | def image2template_feature(img_feats=None, templates=None, medias=None):
  function verification (line 256) | def verification(template_norm_feats=None,
  function verification2 (line 286) | def verification2(template_norm_feats=None,
  function read_score (line 310) | def read_score(path):

FILE: face_module/TopoFR/inference.py
  function inference (line 11) | def inference(weight, name, img):

FILE: face_module/TopoFR/losses.py
  class CombinedMarginLoss (line 5) | class CombinedMarginLoss(torch.nn.Module):
    method __init__ (line 6) | def __init__(self,
    method forward (line 27) | def forward(self, logits, labels):
  class ArcFace (line 60) | class ArcFace(torch.nn.Module):
    method __init__ (line 63) | def __init__(self, s=64.0, margin=0.5):
    method forward (line 73) | def forward(self, logits: torch.Tensor, labels: torch.Tensor):
  class CosFace (line 98) | class CosFace(torch.nn.Module):
    method __init__ (line 99) | def __init__(self, s=64.0, m=0.40):
    method forward (line 104) | def forward(self, logits: torch.Tensor, labels: torch.Tensor):

FILE: face_module/TopoFR/lr_scheduler.py
  class PolyScheduler (line 4) | class PolyScheduler(_LRScheduler):
    method __init__ (line 5) | def __init__(self, optimizer, base_lr, max_steps, warmup_steps, last_e...
    method get_warmup_lr (line 14) | def get_warmup_lr(self):
    method get_lr (line 18) | def get_lr(self):

FILE: face_module/TopoFR/onnx_helper.py
  class ArcFaceORT (line 15) | class ArcFaceORT:
    method __init__ (line 16) | def __init__(self, model_path, cpu=False):
    method check (line 22) | def check(self, track='cfat', test_img = None):
    method check_batch (line 184) | def check_batch(self, img):
    method meta_info (line 202) | def meta_info(self):
    method forward (line 206) | def forward(self, imgs):
    method benchmark (line 222) | def benchmark(self, img):

FILE: face_module/TopoFR/onnx_ijbc.py
  class AlignedDataSet (line 30) | class AlignedDataSet(mx.gluon.data.Dataset):
    method __init__ (line 31) | def __init__(self, root, lines, align=True):
    method __len__ (line 36) | def __len__(self):
    method __getitem__ (line 39) | def __getitem__(self, idx):
  function extract (line 56) | def extract(model_root, dataset):
  function read_template_media_list (line 79) | def read_template_media_list(path):
  function read_template_pair_list (line 86) | def read_template_pair_list(path):
  function read_image_feature (line 94) | def read_image_feature(path):
  function image2template_feature (line 100) | def image2template_feature(img_feats=None,
  function verification (line 126) | def verification(template_norm_feats=None,
  function verification2 (line 148) | def verification2(template_norm_feats=None,
  function main (line 170) | def main(args):

FILE: face_module/TopoFR/partial_fc.py
  class PartialFC (line 12) | class PartialFC(torch.nn.Module):
    method __init__ (line 35) | def __init__(
    method sample (line 100) | def sample(self,
    method update (line 142) | def update(self):
    method forward (line 154) | def forward(
    method state_dict (line 220) | def state_dict(self, destination=None, prefix="", keep_vars=False):
    method load_state_dict (line 234) | def load_state_dict(self, state_dict, strict: bool = True):
  class PartialFCAdamW (line 245) | class PartialFCAdamW(torch.nn.Module):     # Adam
    method __init__ (line 246) | def __init__(self,
    method sample (line 316) | def sample(self, labels, index_positive, optimizer):   #
    method update (line 343) | def update(self):
    method forward (line 355) | def forward(
    method state_dict (line 421) | def state_dict(self, destination=None, prefix="", keep_vars=False):
    method load_state_dict (line 435) | def load_state_dict(self, state_dict, strict: bool = True):
  class DistCrossEntropyFunc (line 447) | class DistCrossEntropyFunc(torch.autograd.Function):
    method forward (line 454) | def forward(ctx, logits: torch.Tensor, label: torch.Tensor):
    method backward (line 476) | def backward(ctx, loss_gradient):
  class DistCrossEntropy (line 499) | class DistCrossEntropy(torch.nn.Module):
    method __init__ (line 500) | def __init__(self):
    method forward (line 503) | def forward(self, logit_part, label_part):
  class AllGatherFunc (line 506) | class AllGatherFunc(torch.autograd.Function):
    method forward (line 510) | def forward(ctx, tensor, *gather_list):
    method backward (line 516) | def backward(ctx, *grads):
  function Entropy (line 538) | def Entropy(input_):

FILE: face_module/TopoFR/persistent_homology.py
  function compute_distance_matrix (line 13) | def compute_distance_matrix(x, p=2):
  function compute_topological_loss (line 18) | def compute_topological_loss(input_space, feature_space, use_grad=False):
  class TopologicalSignatureDistance (line 46) | class TopologicalSignatureDistance(nn.Module):
    method __init__ (line 49) | def __init__(self, sort_selected=False, use_cycles=False,
    method _get_pairings (line 64) | def _get_pairings(self, distances):
    method _select_distances_from_pairs (line 70) | def _select_distances_from_pairs(self, distance_matrix, pairs):
    method sig_error (line 86) | def sig_error(signature1, signature2):
    method _count_matching_pairs (line 91) | def _count_matching_pairs(pairs1, pairs2):
    method _get_nonzero_cycles (line 97) | def _get_nonzero_cycles(pairs):
    method forward (line 102) | def forward(self, distances1, distances2):

FILE: face_module/TopoFR/topology.py
  class UnionFind (line 8) | class UnionFind:
    method __init__ (line 15) | def __init__(self, n_vertices):
    method find (line 23) | def find(self, u):
    method merge (line 35) | def merge(self, u, v):
    method roots (line 44) | def roots(self):
  class PersistentHomologyCalculation (line 55) | class PersistentHomologyCalculation:
    method __call__ (line 56) | def __call__(self, matrix):
  class AlephPersistenHomologyCalculation (line 95) | class AlephPersistenHomologyCalculation():
    method __init__ (line 96) | def __init__(self, compute_cycles, sort_selected):
    method __call__ (line 108) | def __call__(self, distance_matrix):

FILE: face_module/TopoFR/torch2onnx.py
  function convert_onnx (line 6) | def convert_onnx(net, path_module, output, opset=11, simplify=False):

FILE: face_module/TopoFR/train.py
  function Entropy (line 48) | def Entropy(input_):
  function main (line 55) | def main(args):

FILE: face_module/TopoFR/utils/plot.py
  function read_template_pair_list (line 18) | def read_template_pair_list(path):

FILE: face_module/TopoFR/utils/utils_callbacks.py
  class CallBackVerification (line 14) | class CallBackVerification(object):
    method __init__ (line 16) | def __init__(self, val_targets, rec_prefix, summary_writer=None, image...
    method ver_test (line 27) | def ver_test(self, backbone: torch.nn.Module, global_step: int):
    method init_dataset (line 44) | def init_dataset(self, val_targets, data_dir, image_size):
    method __call__ (line 52) | def __call__(self, num_update, backbone: torch.nn.Module):
  class CallBackLogging (line 59) | class CallBackLogging(object):
    method __init__ (line 60) | def __init__(self, frequent, total_step, batch_size, start_step=0,writ...
    method __call__ (line 73) | def __call__(self,

FILE: face_module/TopoFR/utils/utils_config.py
  function get_config (line 5) | def get_config(config_file):

FILE: face_module/TopoFR/utils/utils_distributed_sampler.py
  function setup_seed (line 11) | def setup_seed(seed, cuda_deterministic=True):
  function worker_init_fn (line 25) | def worker_init_fn(worker_id, num_workers, rank, seed):
  function get_dist_info (line 34) | def get_dist_info():
  function sync_random_seed (line 45) | def sync_random_seed(seed=None, device="cuda"):
  class DistributedSampler (line 82) | class DistributedSampler(_DistributedSampler):
    method __init__ (line 83) | def __init__(
    method __iter__ (line 102) | def __iter__(self):

FILE: face_module/TopoFR/utils/utils_logging.py
  class AverageMeter (line 6) | class AverageMeter(object):
    method __init__ (line 10) | def __init__(self):
    method reset (line 17) | def reset(self):
    method update (line 23) | def update(self, val, n=1):
  function init_logging (line 30) | def init_logging(rank, models_root):

FILE: face_module/TransFace/FFT.py
  function amplitude_spectrum_mix (line 5) | def amplitude_spectrum_mix(img1, img2, alpha, ratio=1.0):   #img_src, im...

FILE: face_module/TransFace/backbones/__init__.py
  function get_model (line 5) | def get_model(name, **kwargs):

FILE: face_module/TransFace/backbones/iresnet.py
  function conv3x3 (line 8) | def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
  function conv1x1 (line 20) | def conv1x1(in_planes, out_planes, stride=1):
  class IBasicBlock (line 29) | class IBasicBlock(nn.Module):
    method __init__ (line 31) | def __init__(self, inplanes, planes, stride=1, downsample=None,
    method forward_impl (line 47) | def forward_impl(self, x):
    method forward (line 60) | def forward(self, x):
  class IResNet (line 67) | class IResNet(nn.Module):
    method __init__ (line 69) | def __init__(self,
    method _make_layer (line 122) | def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
    method forward (line 148) | def forward(self, x):
  function _iresnet (line 165) | def _iresnet(arch, block, layers, pretrained, progress, **kwargs):
  function iresnet18 (line 172) | def iresnet18(pretrained=False, progress=True, **kwargs):
  function iresnet34 (line 177) | def iresnet34(pretrained=False, progress=True, **kwargs):
  function iresnet50 (line 182) | def iresnet50(pretrained=False, progress=True, **kwargs):
  function iresnet100 (line 187) | def iresnet100(pretrained=False, progress=True, **kwargs):
  function iresnet200 (line 192) | def iresnet200(pretrained=False, progress=True, **kwargs):

FILE: face_module/TransFace/backbones/iresnet2060.py
  function conv3x3 (line 10) | def conv3x3(in_planes, out_planes, stride=1, groups=1, dilation=1):
  function conv1x1 (line 22) | def conv1x1(in_planes, out_planes, stride=1):
  class IBasicBlock (line 31) | class IBasicBlock(nn.Module):
    method __init__ (line 34) | def __init__(self, inplanes, planes, stride=1, downsample=None,
    method forward (line 50) | def forward(self, x):
  class IResNet (line 64) | class IResNet(nn.Module):
    method __init__ (line 67) | def __init__(self,
    method _make_layer (line 119) | def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
    method checkpoint (line 145) | def checkpoint(self, func, num_seg, x):
    method forward (line 151) | def forward(self, x):
  function _iresnet (line 168) | def _iresnet(arch, block, layers, pretrained, progress, **kwargs):
  function iresnet2060 (line 175) | def iresnet2060(pretrained=False, progress=True, **kwargs):

FILE: face_module/TransFace/backbones/mobilefacenet.py
  class Flatten (line 11) | class Flatten(Module):
    method forward (line 12) | def forward(self, x):
  class ConvBlock (line 16) | class ConvBlock(Module):
    method __init__ (line 17) | def __init__(self, in_c, out_c, kernel=(1, 1), stride=(1, 1), padding=...
    method forward (line 25) | def forward(self, x):
  class LinearBlock (line 29) | class LinearBlock(Module):
    method __init__ (line 30) | def __init__(self, in_c, out_c, kernel=(1, 1), stride=(1, 1), padding=...
    method forward (line 37) | def forward(self, x):
  class DepthWise (line 41) | class DepthWise(Module):
    method __init__ (line 42) | def __init__(self, in_c, out_c, residual=False, kernel=(3, 3), stride=...
    method forward (line 51) | def forward(self, x):
  class Residual (line 63) | class Residual(Module):
    method __init__ (line 64) | def __init__(self, c, num_block, groups, kernel=(3, 3), stride=(1, 1),...
    method forward (line 71) | def forward(self, x):
  class GDC (line 75) | class GDC(Module):
    method __init__ (line 76) | def __init__(self, embedding_size):
    method forward (line 84) | def forward(self, x):
  class MobileFaceNet (line 88) | class MobileFaceNet(Module):
    method __init__ (line 89) | def __init__(self, fp16=False, num_features=512, blocks=(1, 4, 6, 2), ...
    method _initialize_weights (line 120) | def _initialize_weights(self):
    method forward (line 134) | def forward(self, x):
  function get_mbf (line 143) | def get_mbf(fp16, num_features, blocks=(1, 4, 6, 2), scale=2):
  function get_mbf_large (line 146) | def get_mbf_large(fp16, num_features, blocks=(2, 8, 12, 4), scale=4):

FILE: face_module/TransFace/backbones/vit.py
  class Mlp (line 7) | class Mlp(nn.Module):
    method __init__ (line 8) | def __init__(self, in_features, hidden_features=None, out_features=Non...
    method forward (line 17) | def forward(self, x):
  class VITBatchNorm (line 26) | class VITBatchNorm(nn.Module):
    method __init__ (line 27) | def __init__(self, num_features):
    method forward (line 32) | def forward(self, x):
  class Attention (line 36) | class Attention(nn.Module):
    method __init__ (line 37) | def __init__(self,
    method forward (line 55) | def forward(self, x):
  class Block (line 74) | class Block(nn.Module):
    method __init__ (line 76) | def __init__(self,
    method forward (line 108) | def forward(self, x):
  class PatchEmbed (line 115) | class PatchEmbed(nn.Module):
    method __init__ (line 116) | def __init__(self, img_size=108, patch_size=9, in_channels=3, embed_di...
    method forward (line 128) | def forward(self, x):
  class VisionTransformer (line 137) | class VisionTransformer(nn.Module):
    method __init__ (line 141) | def __init__(self,
    method _init_weights (line 219) | def _init_weights(self, m):
    method no_weight_decay (line 229) | def no_weight_decay(self):
    method get_classifier (line 232) | def get_classifier(self):
    method random_masking (line 235) | def random_masking(self, x, mask_ratio=0.1):
    method forward_features (line 264) | def forward_features(self, x):
    method forward (line 298) | def forward(self, x):

FILE: face_module/TransFace/dataset.py
  function get_dataloader (line 19) | def get_dataloader(
  class BackgroundGenerator (line 78) | class BackgroundGenerator(threading.Thread):
    method __init__ (line 79) | def __init__(self, generator, local_rank, max_prefetch=6):
    method run (line 87) | def run(self):
    method next (line 93) | def next(self):
    method __next__ (line 99) | def __next__(self):
    method __iter__ (line 102) | def __iter__(self):
  class DataLoaderX (line 106) | class DataLoaderX(DataLoader):
    method __init__ (line 108) | def __init__(self, local_rank, **kwargs):
    method __iter__ (line 113) | def __iter__(self):
    method preload (line 119) | def preload(self):
    method __next__ (line 127) | def __next__(self):
  class MXFaceDataset (line 136) | class MXFaceDataset(Dataset):
    method __init__ (line 137) | def __init__(self, root_dir, local_rank):
    method __getitem__ (line 158) | def __getitem__(self, index):
    method __len__ (line 171) | def __len__(self):
  class SyntheticDataset (line 175) | class SyntheticDataset(Dataset):
    method __init__ (line 176) | def __init__(self):
    method __getitem__ (line 185) | def __getitem__(self, index):
    method __len__ (line 188) | def __len__(self):
  function dali_data_iter (line 192) | def dali_data_iter(
  class DALIWarper (line 230) | class DALIWarper(object):
    method __init__ (line 231) | def __init__(self, dali_iter):
    method __next__ (line 234) | def __next__(self):
    method __iter__ (line 241) | def __iter__(self):
    method reset (line 244) | def reset(self):

FILE: face_module/TransFace/eval/verification.py
  class LFold (line 41) | class LFold:
    method __init__ (line 42) | def __init__(self, n_splits=2, shuffle=False):
    method split (line 47) | def split(self, indices):
  function calculate_roc (line 54) | def calculate_roc(thresholds,
  function calculate_accuracy (line 109) | def calculate_accuracy(threshold, dist, actual_issame):
  function calculate_val (line 124) | def calculate_val(thresholds,
  function calculate_val_far (line 165) | def calculate_val_far(threshold, dist, actual_issame):
  function evaluate (line 179) | def evaluate(embeddings, actual_issame, nrof_folds=10, pca=0):
  function load_bin (line 200) | def load_bin(path, image_size):
  function test (line 227) | def test(data_set, backbone, batch_size, nfolds=10):
  function dumpR (line 277) | def dumpR(data_set,

FILE: face_module/TransFace/eval_ijbc.py
  class Embedding (line 54) | class Embedding(object):
    method __init__ (line 55) | def __init__(self, prefix, data_shape, batch_size=1):
    method get (line 75) | def get(self, rimg, landmark):
    method forward_db (line 104) | def forward_db(self, batch_data):
  function divideIntoNstrand (line 112) | def divideIntoNstrand(listTemp, n):
  function read_template_media_list (line 119) | def read_template_media_list(path):
  function read_template_pair_list (line 130) | def read_template_pair_list(path):
  function read_image_feature (line 144) | def read_image_feature(path):
  function get_image_feature (line 153) | def get_image_feature(img_path, files_list, model_path, epoch, gpu_id):
  function image2template_feature (line 211) | def image2template_feature(img_feats=None, templates=None, medias=None):
  function verification (line 251) | def verification(template_norm_feats=None,
  function verification2 (line 281) | def verification2(template_norm_feats=None,
  function read_score (line 305) | def read_score(path):

FILE: face_module/TransFace/inference.py
  function inference (line 11) | def inference(weight, name, img):

FILE: face_module/TransFace/losses.py
  class CombinedMarginLoss (line 5) | class CombinedMarginLoss(torch.nn.Module):
    method __init__ (line 6) | def __init__(self,
    method forward (line 27) | def forward(self, logits, labels):
  class ArcFace (line 60) | class ArcFace(torch.nn.Module):
    method __init__ (line 63) | def __init__(self, s=64.0, margin=0.5):
    method forward (line 73) | def forward(self, logits: torch.Tensor, labels: torch.Tensor):
  class CosFace (line 91) | class CosFace(torch.nn.Module):
    method __init__ (line 92) | def __init__(self, s=64.0, m=0.40):
    method forward (line 97) | def forward(self, logits: torch.Tensor, labels: torch.Tensor):

FILE: face_module/TransFace/lr_scheduler.py
  class PolyScheduler (line 4) | class PolyScheduler(_LRScheduler):
    method __init__ (line 5) | def __init__(self, optimizer, base_lr, max_steps, warmup_steps, last_e...
    method get_warmup_lr (line 14) | def get_warmup_lr(self):
    method get_lr (line 18) | def get_lr(self):

FILE: face_module/TransFace/onnx_helper.py
  class ArcFaceORT (line 15) | class ArcFaceORT:
    method __init__ (line 16) | def __init__(self, model_path, cpu=False):
    method check (line 22) | def check(self, track='cfat', test_img = None):
    method check_batch (line 184) | def check_batch(self, img):
    method meta_info (line 202) | def meta_info(self):
    method forward (line 206) | def forward(self, imgs):
    method benchmark (line 222) | def benchmark(self, img):

FILE: face_module/TransFace/onnx_ijbc.py
  class AlignedDataSet (line 30) | class AlignedDataSet(mx.gluon.data.Dataset):
    method __init__ (line 31) | def __init__(self, root, lines, align=True):
    method __len__ (line 36) | def __len__(self):
    method __getitem__ (line 39) | def __getitem__(self, idx):
  function extract (line 56) | def extract(model_root, dataset):
  function read_template_media_list (line 79) | def read_template_media_list(path):
  function read_template_pair_list (line 86) | def read_template_pair_list(path):
  function read_image_feature (line 94) | def read_image_feature(path):
  function image2template_feature (line 100) | def image2template_feature(img_feats=None,
  function verification (line 126) | def verification(template_norm_feats=None,
  function verification2 (line 148) | def verification2(template_norm_feats=None,
  function main (line 170) | def main(args):

FILE: face_module/TransFace/partial_fc_exp.py
  class PartialFC (line 10) | class PartialFC(torch.nn.Module):
    method __init__ (line 33) | def __init__(
    method sample (line 98) | def sample(self,
    method update (line 140) | def update(self):
    method forward (line 152) | def forward(
    method state_dict (line 217) | def state_dict(self, destination=None, prefix="", keep_vars=False):
    method load_state_dict (line 231) | def load_state_dict(self, state_dict, strict: bool = True):
  class PartialFCAdamW (line 242) | class PartialFCAdamW(torch.nn.Module):     # Adam Optimization
    method __init__ (line 243) | def __init__(self,
    method sample (line 313) | def sample(self, labels, index_positive, optimizer):
    method update (line 340) | def update(self):
    method forward (line 352) | def forward(
    method state_dict (line 434) | def state_dict(self, destination=None, prefix="", keep_vars=False):
    method load_state_dict (line 448) | def load_state_dict(self, state_dict, strict: bool = True):
  class DistCrossEntropyFunc (line 460) | class DistCrossEntropyFunc(torch.autograd.Function):
    method forward (line 467) | def forward(ctx, logits: torch.Tensor, label: torch.Tensor):
    method backward (line 494) | def backward(ctx, loss_gradient):
  class DistCrossEntropy (line 519) | class DistCrossEntropy(torch.nn.Module):
    method __init__ (line 520) | def __init__(self):
    method forward (line 523) | def forward(self, logit_part, label_part):
  class AllGatherFunc (line 526) | class AllGatherFunc(torch.autograd.Function):
    method forward (line 530) | def forward(ctx, tensor, *gather_list):
    method backward (line 536) | def backward(ctx, *grads):

FILE: face_module/TransFace/torch2onnx.py
  function convert_onnx (line 6) | def convert_onnx(net, path_module, output, opset=11, simplify=False):

FILE: face_module/TransFace/train.py
  function main (line 43) | def main(args):

FILE: face_module/TransFace/utils/plot.py
  function read_template_pair_list (line 18) | def read_template_pair_list(path):

FILE: face_module/TransFace/utils/utils_callbacks.py
  class CallBackVerification (line 14) | class CallBackVerification(object):
    method __init__ (line 16) | def __init__(self, val_targets, rec_prefix, summary_writer=None, image...
    method ver_test (line 27) | def ver_test(self, backbone: torch.nn.Module, global_step: int):
    method init_dataset (line 44) | def init_dataset(self, val_targets, data_dir, image_size):
    method __call__ (line 52) | def __call__(self, num_update, backbone: torch.nn.Module):
  class CallBackLogging (line 59) | class CallBackLogging(object):
    method __init__ (line 60) | def __init__(self, frequent, total_step, batch_size, start_step=0,writ...
    method __call__ (line 73) | def __call__(self,

FILE: face_module/TransFace/utils/utils_config.py
  function get_config (line 5) | def get_config(config_file):

FILE: face_module/TransFace/utils/utils_distributed_sampler.py
  function setup_seed (line 11) | def setup_seed(seed, cuda_deterministic=True):
  function worker_init_fn (line 25) | def worker_init_fn(worker_id, num_workers, rank, seed):
  function get_dist_info (line 34) | def get_dist_info():
  function sync_random_seed (line 45) | def sync_random_seed(seed=None, device="cuda"):
  class DistributedSampler (line 82) | class DistributedSampler(_DistributedSampler):
    method __init__ (line 83) | def __init__(
    method __iter__ (line 102) | def __iter__(self):

FILE: face_module/TransFace/utils/utils_logging.py
  class AverageMeter (line 6) | class AverageMeter(object):
    method __init__ (line 10) | def __init__(self):
    method reset (line 17) | def reset(self):
    method update (line 23) | def update(self, val, n=1):
  function init_logging (line 30) | def init_logging(rank, models_root):

FILE: facechain/inference_fact.py
  function txt2img (line 26) | def txt2img(pipe, face_image, pos_prompt, neg_prompt, num_images=10):
  function img_pad (line 43) | def img_pad(pil_file, fixed_height=512, fixed_width=512):
  function txt2img_multi (line 70) | def txt2img_multi(pipe,
  function get_mask (line 97) | def get_mask(result):
  function main_diffusion_inference_multi (line 125) | def main_diffusion_inference_multi(num_gen_images,
  function stylization_fn (line 174) | def stylization_fn(use_stylization, rank_results):
  function main_model_inference (line 182) | def main_model_inference(num_gen_images,
  function face_swap_fn (line 219) | def face_swap_fn(use_face_swap, gen_results, template_face, image_face_f...
  function post_process_fn (line 237) | def post_process_fn(use_post_process, swap_results_ori, selected_face,
  class GenPortrait (line 278) | class GenPortrait:
    method __init__ (line 280) | def __init__(self):
    method __call__ (line 373) | def __call__(self,
  function compress_image (line 512) | def compress_image(input_path, target_size):
  function change_extension_to_jpg (line 530) | def change_extension_to_jpg(image_path):

FILE: facechain/inference_inpaint_fact.py
  function concatenate_images (line 34) | def concatenate_images(images):
  function call_face_crop (line 47) | def call_face_crop(det_pipeline, image, crop_ratio):
  function crop_and_paste (line 81) | def crop_and_paste(Source_image,
  function segment (line 123) | def segment(segmentation_pipeline,
  function crop_bottom (line 196) | def crop_bottom(pil_file, width):
  function img2img_multicontrol (line 212) | def img2img_multicontrol(img,
  function get_mask (line 246) | def get_mask(result):
  function main_diffusion_inference_inpaint (line 271) | def main_diffusion_inference_inpaint(num_gen_images,
  function stylization_fn (line 470) | def stylization_fn(use_stylization, rank_results):
  function main_model_inference (line 478) | def main_model_inference(num_gen_images,
  function select_high_quality_face (line 515) | def select_high_quality_face(input_img_dir, face_quality_func):
  function face_swap_fn (line 541) | def face_swap_fn(use_face_swap, gen_results, template_face, image_face_f...
  function post_process_fn (line 562) | def post_process_fn(use_post_process, swap_results_ori, selected_face,
  function process_inpaint_img (line 595) | def process_inpaint_img(inpaint_img, resize_size=(1024, 1024)):
  function postprocess_inpaint_img (line 613) | def postprocess_inpaint_img(img2img_res, output_size=(768, 1024)):
  class GenPortrait_inpaint (line 622) | class GenPortrait_inpaint:
    method __init__ (line 624) | def __init__(self):
    method __call__ (line 711) | def __call__(self,
  function compress_image (line 916) | def compress_image(input_path, target_size):
  function change_extension_to_jpg (line 934) | def change_extension_to_jpg(image_path):

FILE: facechain/merge_lora.py
  function merge_lora (line 10) | def merge_lora(pipeline,
  function restore_lora (line 94) | def restore_lora(pipeline,

FILE: facechain/utils.py
  function max_retries (line 11) | def max_retries(max_attempts):
  function snapshot_download (line 29) | def snapshot_download(*args, **kwargs):
  function pre_download_models (line 33) | def pre_download_models():
  function set_spawn_method (line 44) | def set_spawn_method():
  function check_install (line 50) | def check_install(*args):
  function check_ffmpeg (line 57) | def check_ffmpeg():
  function get_worker_data_dir (line 64) | def get_worker_data_dir() -> str:
  function join_worker_data_dir (line 71) | def join_worker_data_dir(*kwargs) -> str:

FILE: install.py
  function get_pytorch_version (line 32) | def get_pytorch_version():
  function get_python_version (line 36) | def get_python_version():

FILE: more_apps/Facechain-SuDe/ldm/data/base.py
  class Txt2ImgIterableBaseDataset (line 5) | class Txt2ImgIterableBaseDataset(IterableDataset):
    method __init__ (line 9) | def __init__(self, num_records=0, valid_ids=None, size=256):
    method __len__ (line 18) | def __len__(self):
    method __iter__ (line 22) | def __iter__(self):

FILE: more_apps/Facechain-SuDe/ldm/data/imagenet.py
  function synset2idx (line 20) | def synset2idx(path_to_yaml="data/index_synset.yaml"):
  class ImageNetBase (line 26) | class ImageNetBase(Dataset):
    method __init__ (line 27) | def __init__(self, config=None):
    method __len__ (line 39) | def __len__(self):
    method __getitem__ (line 42) | def __getitem__(self, i):
    method _prepare (line 45) | def _prepare(self):
    method _filter_relpaths (line 48) | def _filter_relpaths(self, relpaths):
    method _prepare_synset_to_human (line 66) | def _prepare_synset_to_human(self):
    method _prepare_idx_to_synset (line 74) | def _prepare_idx_to_synset(self):
    method _prepare_human_to_integer_label (line 80) | def _prepare_human_to_integer_label(self):
    method _load (line 93) | def _load(self):
  class ImageNetTrain (line 134) | class ImageNetTrain(ImageNetBase):
    method __init__ (line 145) | def __init__(self, process_images=True, data_root=None, **kwargs):
    method _prepare (line 150) | def _prepare(self):
  class ImageNetValidation (line 197) | class ImageNetValidation(ImageNetBase):
    method __init__ (line 211) | def __init__(self, process_images=True, data_root=None, **kwargs):
    method _prepare (line 216) | def _prepare(self):
  class ImageNetSR (line 272) | class ImageNetSR(Dataset):
    method __init__ (line 273) | def __init__(self, size=None,
    method __len__ (line 336) | def __len__(self):
    method __getitem__ (line 339) | def __getitem__(self, i):
  class ImageNetSRTrain (line 375) | class ImageNetSRTrain(ImageNetSR):
    method __init__ (line 376) | def __init__(self, **kwargs):
    method get_base (line 379) | def get_base(self):
  class ImageNetSRValidation (line 386) | class ImageNetSRValidation(ImageNetSR):
    method __init__ (line 387) | def __init__(self, **kwargs):
    method get_base (line 390) | def get_base(self):

FILE: more_apps/Facechain-SuDe/ldm/data/lsun.py
  class LSUNBase (line 9) | class LSUNBase(Dataset):
    method __init__ (line 10) | def __init__(self,
    method __len__ (line 36) | def __len__(self):
    method __getitem__ (line 39) | def __getitem__(self, i):
  class LSUNChurchesTrain (line 62) | class LSUNChurchesTrain(LSUNBase):
    method __init__ (line 63) | def __init__(self, **kwargs):
  class LSUNChurchesValidation (line 67) | class LSUNChurchesValidation(LSUNBase):
    method __init__ (line 68) | def __init__(self, flip_p=0., **kwargs):
  class LSUNBedroomsTrain (line 73) | class LSUNBedroomsTrain(LSUNBase):
    method __init__ (line 74) | def __init__(self, **kwargs):
  class LSUNBedroomsValidation (line 78) | class LSUNBedroomsValidation(LSUNBase):
    method __init__ (line 79) | def __init__(self, flip_p=0.0, **kwargs):
  class LSUNCatsTrain (line 84) | class LSUNCatsTrain(LSUNBase):
    method __init__ (line 85) | def __init__(self, **kwargs):
  class LSUNCatsValidation (line 89) | class LSUNCatsValidation(LSUNBase):
    method __init__ (line 90) | def __init__(self, flip_p=0., **kwargs):

FILE: more_apps/Facechain-SuDe/ldm/data/personalized.py
  class PersonalizedBase (line 144) | class PersonalizedBase(Dataset):
    method __init__ (line 145) | def __init__(self,
    method __len__ (line 191) | def __len__(self):
    method __getitem__ (line 194) | def __getitem__(self, i):

FILE: more_apps/Facechain-SuDe/ldm/data/personalized_style.py
  class PersonalizedBase (line 56) | class PersonalizedBase(Dataset):
    method __init__ (line 57) | def __init__(self,
    method __len__ (line 96) | def __len__(self):
    method __getitem__ (line 99) | def __getitem__(self, i):

FILE: more_apps/Facechain-SuDe/ldm/lr_scheduler.py
  class LambdaWarmUpCosineScheduler (line 4) | class LambdaWarmUpCosineScheduler:
    method __init__ (line 8) | def __init__(self, warm_up_steps, lr_min, lr_max, lr_start, max_decay_...
    method schedule (line 17) | def schedule(self, n, **kwargs):
    method __call__ (line 32) | def __call__(self, n, **kwargs):
  class LambdaWarmUpCosineScheduler2 (line 36) | class LambdaWarmUpCosineScheduler2:
    method __init__ (line 41) | def __init__(self, warm_up_steps, f_min, f_max, f_start, cycle_lengths...
    method find_in_interval (line 52) | def find_in_interval(self, n):
    method schedule (line 59) | def schedule(self, n, **kwargs):
    method __call__ (line 77) | def __call__(self, n, **kwargs):
  class LambdaLinearScheduler (line 81) | class LambdaLinearScheduler(LambdaWarmUpCosineScheduler2):
    method schedule (line 83) | def schedule(self, n, **kwargs):

FILE: more_apps/Facechain-SuDe/ldm/models/autoencoder.py
  class VQModel (line 14) | class VQModel(pl.LightningModule):
    method __init__ (line 15) | def __init__(self,
    method ema_scope (line 64) | def ema_scope(self, context=None):
    method init_from_ckpt (line 78) | def init_from_ckpt(self, path, ignore_keys=list()):
    method on_train_batch_end (line 92) | def on_train_batch_end(self, *args, **kwargs):
    method encode (line 96) | def encode(self, x):
    method encode_to_prequant (line 102) | def encode_to_prequant(self, x):
    method decode (line 107) | def decode(self, quant):
    method decode_code (line 112) | def decode_code(self, code_b):
    method forward (line 117) | def forward(self, input, return_pred_indices=False):
    method get_input (line 124) | def get_input(self, batch, k):
    method training_step (line 142) | def training_step(self, batch, batch_idx, optimizer_idx):
    method validation_step (line 164) | def validation_step(self, batch, batch_idx):
    method _validation_step (line 170) | def _validation_step(self, batch, batch_idx, suffix=""):
    method configure_optimizers (line 197) | def configure_optimizers(self):
    method get_last_layer (line 230) | def get_last_layer(self):
    method log_images (line 233) | def log_images(self, batch, only_inputs=False, plot_ema=False, **kwargs):
    method to_rgb (line 255) | def to_rgb(self, x):
  class VQModelInterface (line 264) | class VQModelInterface(VQModel):
    method __init__ (line 265) | def __init__(self, embed_dim, *args, **kwargs):
    method encode (line 269) | def encode(self, x):
    method decode (line 274) | def decode(self, h, force_not_quantize=False):
  class AutoencoderKL (line 285) | class AutoencoderKL(pl.LightningModule):
    method __init__ (line 286) | def __init__(self,
    method init_from_ckpt (line 313) | def init_from_ckpt(self, path, ignore_keys=list()):
    method encode (line 324) | def encode(self, x):
    method decode (line 330) | def decode(self, z):
    method forward (line 335) | def forward(self, input, sample_posterior=True):
    method get_input (line 344) | def get_input(self, batch, k):
    method training_step (line 351) | def training_step(self, batch, batch_idx, optimizer_idx):
    method validation_step (line 372) | def validation_step(self, batch, batch_idx):
    method configure_optimizers (line 386) | def configure_optimizers(self):
    method get_last_layer (line 397) | def get_last_layer(self):
    method log_images (line 401) | def log_images(self, batch, only_inputs=False, **kwargs):
    method to_rgb (line 417) | def to_rgb(self, x):
  class IdentityFirstStage (line 426) | class IdentityFirstStage(torch.nn.Module):
    method __init__ (line 427) | def __init__(self, *args, vq_interface=False, **kwargs):
    method encode (line 431) | def encode(self, x, *args, **kwargs):
    method decode (line 434) | def decode(self, x, *args, **kwargs):
    method quantize (line 437) | def quantize(self, x, *args, **kwargs):
    method forward (line 442) | def forward(self, x, *args, **kwargs):

FILE: more_apps/Facechain-SuDe/ldm/models/diffusion/classifier.py
  function disabled_train (line 22) | def disabled_train(self, mode=True):
  class NoisyLatentImageClassifier (line 28) | class NoisyLatentImageClassifier(pl.LightningModule):
    method __init__ (line 30) | def __init__(self,
    method init_from_ckpt (line 70) | def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
    method load_diffusion (line 88) | def load_diffusion(self):
    method load_classifier (line 95) | def load_classifier(self, ckpt_path, pool):
    method get_x_noisy (line 110) | def get_x_noisy(self, x, t, noise=None):
    method forward (line 120) | def forward(self, x_noisy, t, *args, **kwargs):
    method get_input (line 124) | def get_input(self, batch, k):
    method get_conditioning (line 133) | def get_conditioning(self, batch, k=None):
    method compute_top_k (line 150) | def compute_top_k(self, logits, labels, k, reduction="mean"):
    method on_train_epoch_start (line 157) | def on_train_epoch_start(self):
    method write_logs (line 162) | def write_logs(self, loss, logits, targets):
    method shared_step (line 179) | def shared_step(self, batch, t=None):
    method training_step (line 198) | def training_step(self, batch, batch_idx):
    method reset_noise_accs (line 202) | def reset_noise_accs(self):
    method on_validation_start (line 206) | def on_validation_start(self):
    method validation_step (line 210) | def validation_step(self, batch, batch_idx):
    method configure_optimizers (line 220) | def configure_optimizers(self):
    method log_images (line 238) | def log_images(self, batch, N=8, *args, **kwargs):

FILE: more_apps/Facechain-SuDe/ldm/models/diffusion/ddim.py
  class DDIMSampler (line 12) | class DDIMSampler(object):
    method __init__ (line 13) | def __init__(self, model, schedule="linear", **kwargs):
    method register_buffer (line 19) | def register_buffer(self, name, attr):
    method make_schedule (line 25) | def make_schedule(self, ddim_num_steps, ddim_discretize="uniform", ddi...
    method sample (line 57) | def sample(self,
    method ddim_sampling (line 114) | def ddim_sampling(self, cond, shape,
    method p_sample_ddim (line 165) | def p_sample_ddim(self, x, c, t, index, repeat_noise=False, use_origin...
    method stochastic_encode (line 208) | def stochastic_encode(self, x0, t, use_original_steps=False, noise=None):
    method decode (line 224) | def decode(self, x_latent, cond, t_start, unconditional_guidance_scale...

FILE: more_apps/Facechain-SuDe/ldm/models/diffusion/ddpm.py
  function disabled_train (line 40) | def disabled_train(self, mode=True):
  function uniform_on_device (line 46) | def uniform_on_device(r1, r2, shape, device):
  class DDPM (line 50) | class DDPM(pl.LightningModule):
    method __init__ (line 52) | def __init__(self,
    method register_schedule (line 133) | def register_schedule(self, given_betas=None, beta_schedule="linear", ...
    method ema_scope (line 188) | def ema_scope(self, context=None):
    method init_from_ckpt (line 202) | def init_from_ckpt(self, path, ignore_keys=list(), only_model=False):
    method q_mean_variance (line 220) | def q_mean_variance(self, x_start, t):
    method predict_start_from_noise (line 232) | def predict_start_from_noise(self, x_t, t, noise):
    method q_posterior (line 240) | def q_posterior(self, x_start, x_t, t):
    method p_mean_variance (line 249) | def p_mean_variance(self, x, t, clip_denoised: bool):
    method p_sample (line 262) | def p_sample(self, x, t, clip_denoised=True, repeat_noise=False):
    method p_sample_loop (line 271) | def p_sample_loop(self, shape, return_intermediates=False):
    method sample (line 286) | def sample(self, batch_size=16, return_intermediates=False):
    method q_sample (line 292) | def q_sample(self, x_start, t, noise=None):
    method get_loss (line 297) | def get_loss(self, pred, target, mean=True):
    method p_losses (line 312) | def p_losses(self, x_start, t, noise=None):
    method forward (line 341) | def forward(self, x, *args, **kwargs):
    method get_input (line 347) | def get_input(self, batch, k):
    method shared_step (line 355) | def shared_step(self, batch):
    method training_step (line 360) | def training_step(self, batch, batch_idx):
    method validation_step (line 376) | def validation_step(self, batch, batch_idx):
    method on_train_batch_end (line 384) | def on_train_batch_end(self, *args, **kwargs):
    method _get_rows_from_list (line 388) | def _get_rows_from_list(self, samples):
    method log_images (line 396) | def log_images(self, batch, N=8, n_row=2, sample=True, return_keys=Non...
    method configure_optimizers (line 433) | def configure_optimizers(self):
  class LatentDiffusion (line 442) | class LatentDiffusion(DDPM):
    method __init__ (line 444) | def __init__(self,
    method make_cond_schedule (line 515) | def make_cond_schedule(self, ):
    method on_train_batch_start (line 522) | def on_train_batch_start(self, batch, batch_idx, dataloader_idx):
    method register_schedule (line 538) | def register_schedule(self,
    method instantiate_first_stage (line 547) | def instantiate_first_stage(self, config):
    method instantiate_cond_stage (line 554) | def instantiate_cond_stage(self, config):
    method _get_denoise_row_from_list (line 584) | def _get_denoise_row_from_list(self, samples, desc='', force_no_decode...
    method get_first_stage_encoding (line 596) | def get_first_stage_encoding(self, encoder_posterior):
    method get_learned_conditioning (line 606) | def get_learned_conditioning(self, c):
    method meshgrid (line 621) | def meshgrid(self, h, w):
    method delta_border (line 628) | def delta_border(self, h, w):
    method get_weighting (line 642) | def get_weighting(self, h, w, Ly, Lx, device):
    method get_fold_unfold (line 658) | def get_fold_unfold(self, x, kernel_size, stride, uf=1, df=1):  # todo...
    method get_input_original (line 712) | def get_input_original(self, batch, k, return_first_stage_outputs=Fals...
    method get_input (line 767) | def get_input(self, batch, k, return_first_stage_outputs=False, force_...
    method decode_first_stage (line 830) | def decode_first_stage(self, z, predict_cids=False, force_not_quantize...
    method differentiable_decode_first_stage (line 890) | def differentiable_decode_first_stage(self, z, predict_cids=False, for...
    method encode_first_stage (line 950) | def encode_first_stage(self, x):
    method shared_step (line 989) | def shared_step(self, batch, **kwargs):
    method training_step (line 1001) | def training_step(self, batch, batch_idx):
    method forward (line 1024) | def forward(self, x, c, c_class, is_reg, *args, **kwargs):
    method _rescale_annotations (line 1042) | def _rescale_annotations(self, bboxes, crop_coordinates):  # TODO: mov...
    method apply_model (line 1052) | def apply_model(self, x_noisy, t, cond, return_ids=False):
    method _predict_eps_from_xstart (line 1151) | def _predict_eps_from_xstart(self, x_t, t, pred_xstart):
    method _prior_bpd (line 1155) | def _prior_bpd(self, x_start):
    method norm (line 1170) | def norm(self, x):
    method prob_loss_func_class (line 1176) | def prob_loss_func_class(self, model_output, mu_c, mu, t, x_t, var_t, ...
    method p_losses (line 1210) | def p_losses(self, x_start, cond, cond_class, uc, t, is_reg, noise=None):
    method p_mean_variance (line 1268) | def p_mean_variance(self, x, c, t, clip_denoised: bool, return_codeboo...
    method p_sample (line 1305) | def p_sample(self, x, c, t, clip_denoised=False, repeat_noise=False,
    method progressive_denoising (line 1336) | def progressive_denoising(self, cond, shape, verbose=True, callback=No...
    method p_sample_loop (line 1392) | def p_sample_loop(self, cond, shape, return_intermediates=False,
    method sample (line 1443) | def sample(self, cond, batch_size=16, return_intermediates=False, x_T=...
    method sample_log (line 1461) | def sample_log(self,cond,batch_size,ddim, ddim_steps,**kwargs):
    method log_images (line 1476) | def log_images(self, batch, N=8, n_row=4, sample=True, ddim_steps=200,...
    method configure_optimizers (line 1597) | def configure_optimizers(self):
    method configure_opt_embedding (line 1621) | def configure_opt_embedding(self):
    method configure_opt_model (line 1640) | def configure_opt_model(self):
    method to_rgb (line 1656) | def to_rgb(self, x):
  class DiffusionWrapper (line 1676) | class DiffusionWrapper(pl.LightningModule):
    method __init__ (line 1677) | def __init__(self, diff_model_config, conditioning_key):
    method forward (line 1683) | def forward(self, x, t, c_class: list = None, c_concat: list = None, c...
  class Layout2ImgDiffusion (line 1710) | class Layout2ImgDiffusion(LatentDiffusion):
    method __init__ (line 1712) | def __init__(self, cond_stage_key, *args, **kwargs):
    method log_images (line 1716) | def log_images(self, batch, N=8, *args, **kwargs):
  class FrozenClipImageEmbedder (line 1736) | class FrozenClipImageEmbedder(nn.Module):
    method __init__ (line 1740) | def __init__(
    method preprocess (line 1755) | def preprocess(self, x):
    method forward (line 1765) | def forward(self, x):
    method get_image_features (line 1770) | def get_image_features(self, img: torch.Tensor, norm: bool = True) -> ...
    method img_to_img_similarity (line 1778) | def img_to_img_similarity(self, src_images, generated_images):

FILE: more_apps/Facechain-SuDe/ldm/models/diffusion/plms.py
  class PLMSSampler (line 11) | class PLMSSampler(object):
    method __init__ (line 12) | def __init__(self, model, schedule="linear", **kwargs):
    method register_buffer (line 18) | def register_buffer(self, name, attr):
    method make_schedule (line 24) | def make_schedule(self, ddim_num_steps, ddim_discretize="uniform", ddi...
    method sample (line 58) | def sample(self,
    method plms_sampling (line 115) | def plms_sampling(self, cond, shape,
    method p_sample_plms (line 173) | def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_origin...

FILE: more_apps/Facechain-SuDe/ldm/modules/attention.py
  function exists (line 13) | def exists(val):
  function uniq (line 17) | def uniq(arr):
  function default (line 21) | def default(val, d):
  function max_neg_value (line 27) | def max_neg_value(t):
  function init_ (line 31) | def init_(tensor):
  class GEGLU (line 39) | class GEGLU(nn.Module):
    method __init__ (line 40) | def __init__(self, dim_in, dim_out):
    method forward (line 44) | def forward(self, x):
  class FeedForward (line 49) | class FeedForward(nn.Module):
    method __init__ (line 50) | def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.):
    method forward (line 65) | def forward(self, x):
  function zero_module (line 69) | def zero_module(module):
  function Normalize (line 78) | def Normalize(in_channels):
  class LinearAttention (line 82) | class LinearAttention(nn.Module):
    method __init__ (line 83) | def __init__(self, dim, heads=4, dim_head=32):
    method forward (line 90) | def forward(self, x):
  class SpatialSelfAttention (line 101) | class SpatialSelfAttention(nn.Module):
    method __init__ (line 102) | def __init__(self, in_channels):
    method forward (line 128) | def forward(self, x):
  class CrossAttention (line 155) | class CrossAttention(nn.Module):
    method __init__ (line 156) | def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, ...
    method forward (line 173) | def forward(self, x, context=None, mask=None):
  class BasicTransformerBlock (line 214) | class BasicTransformerBlock(nn.Module):
    method __init__ (line 215) | def __init__(self, dim, n_heads, d_head, dropout=0., context_dim=None,...
    method forward (line 226) | def forward(self, x, context=None):
    method _forward (line 229) | def _forward(self, x, context=None):
  class SpatialTransformer (line 236) | class SpatialTransformer(nn.Module):
    method __init__ (line 244) | def __init__(self, in_channels, n_heads, d_head,
    method forward (line 268) | def forward(self, x, context=None):

FILE: more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/model.py
  function get_timestep_embedding (line 12) | def get_timestep_embedding(timesteps, embedding_dim):
  function nonlinearity (line 33) | def nonlinearity(x):
  function Normalize (line 38) | def Normalize(in_channels, num_groups=32):
  class Upsample (line 42) | class Upsample(nn.Module):
    method __init__ (line 43) | def __init__(self, in_channels, with_conv):
    method forward (line 53) | def forward(self, x):
  class Downsample (line 60) | class Downsample(nn.Module):
    method __init__ (line 61) | def __init__(self, in_channels, with_conv):
    method forward (line 72) | def forward(self, x):
  class ResnetBlock (line 82) | class ResnetBlock(nn.Module):
    method __init__ (line 83) | def __init__(self, *, in_channels, out_channels=None, conv_shortcut=Fa...
    method forward (line 121) | def forward(self, x, temb):
  class LinAttnBlock (line 144) | class LinAttnBlock(LinearAttention):
    method __init__ (line 146) | def __init__(self, in_channels):
  class AttnBlock (line 150) | class AttnBlock(nn.Module):
    method __init__ (line 151) | def __init__(self, in_channels):
    method forward (line 178) | def forward(self, x):
  function make_attn (line 205) | def make_attn(in_channels, attn_type="vanilla"):
  class Model (line 216) | class Model(nn.Module):
    method __init__ (line 217) | def __init__(self, *, ch, out_ch, ch_mult=(1,2,4,8), num_res_blocks,
    method forward (line 316) | def forward(self, x, t=None, context=None):
    method get_last_layer (line 364) | def get_last_layer(self):
  class Encoder (line 368) | class Encoder(nn.Module):
    method __init__ (line 369) | def __init__(self, *, ch, out_ch, ch_mult=(1,2,4,8), num_res_blocks,
    method forward (line 434) | def forward(self, x):
  class Decoder (line 462) | class Decoder(nn.Module):
    method __init__ (line 463) | def __init__(self, *, ch, out_ch, ch_mult=(1,2,4,8), num_res_blocks,
    method forward (line 535) | def forward(self, z):
  class SimpleDecoder (line 571) | class SimpleDecoder(nn.Module):
    method __init__ (line 572) | def __init__(self, in_channels, out_channels, *args, **kwargs):
    method forward (line 594) | def forward(self, x):
  class UpsampleDecoder (line 607) | class UpsampleDecoder(nn.Module):
    method __init__ (line 608) | def __init__(self, in_channels, out_channels, ch, num_res_blocks, reso...
    method forward (line 641) | def forward(self, x):
  class LatentRescaler (line 655) | class LatentRescaler(nn.Module):
    method __init__ (line 656) | def __init__(self, factor, in_channels, mid_channels, out_channels, de...
    method forward (line 680) | def forward(self, x):
  class MergedRescaleEncoder (line 692) | class MergedRescaleEncoder(nn.Module):
    method __init__ (line 693) | def __init__(self, in_channels, ch, resolution, out_ch, num_res_blocks,
    method forward (line 705) | def forward(self, x):
  class MergedRescaleDecoder (line 711) | class MergedRescaleDecoder(nn.Module):
    method __init__ (line 712) | def __init__(self, z_channels, out_ch, resolution, num_res_blocks, att...
    method forward (line 722) | def forward(self, x):
  class Upsampler (line 728) | class Upsampler(nn.Module):
    method __init__ (line 729) | def __init__(self, in_size, out_size, in_channels, out_channels, ch_mu...
    method forward (line 741) | def forward(self, x):
  class Resize (line 747) | class Resize(nn.Module):
    method __init__ (line 748) | def __init__(self, in_channels=None, learned=False, mode="bilinear"):
    method forward (line 763) | def forward(self, x, scale_factor=1.0):
  class FirstStagePostProcessor (line 770) | class FirstStagePostProcessor(nn.Module):
    method __init__ (line 772) | def __init__(self, ch_mult:list, in_channels,
    method instantiate_pretrained (line 807) | def instantiate_pretrained(self, config):
    method encode_with_pretrained (line 816) | def encode_with_pretrained(self,x):
    method forward (line 822) | def forward(self,x):

FILE: more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/openaimodel.py
  function convert_module_to_f16 (line 25) | def convert_module_to_f16(x):
  function convert_module_to_f32 (line 28) | def convert_module_to_f32(x):
  class AttentionPool2d (line 33) | class AttentionPool2d(nn.Module):
    method __init__ (line 38) | def __init__(
    method forward (line 52) | def forward(self, x):
  class TimestepBlock (line 63) | class TimestepBlock(nn.Module):
    method forward (line 69) | def forward(self, x, emb):
  class TimestepEmbedSequential (line 75) | class TimestepEmbedSequential(nn.Sequential, TimestepBlock):
    method forward (line 81) | def forward(self, x, emb, context=None, adj_index=None):
  class Upsample (line 94) | class Upsample(nn.Module):
    method __init__ (line 103) | def __init__(self, channels, use_conv, dims=2, out_channels=None, padd...
    method forward (line 112) | def forward(self, x):
  class TransposedUpsample (line 126) | class TransposedUpsample(nn.Module):
    method __init__ (line 128) | def __init__(self, channels, out_channels=None, ks=5):
    method forward (line 135) | def forward(self,x):
  class Downsample (line 139) | class Downsample(nn.Module):
    method __init__ (line 148) | def __init__(self, channels, use_conv, dims=2, out_channels=None,paddi...
    method forward (line 163) | def forward(self, x):
  class ResBlock (line 168) | class ResBlock(TimestepBlock):
    method __init__ (line 184) | def __init__(
    method forward (line 248) | def forward(self, x, emb):
    method _forward (line 260) | def _forward(self, x, emb):
  class AttentionBlock (line 283) | class AttentionBlock(nn.Module):
    method __init__ (line 290) | def __init__(
    method forward (line 319) | def forward(self, x):
    method _forward (line 323) | def _forward(self, x):
  function count_flops_attn (line 332) | def count_flops_attn(model, _x, y):
  class QKVAttentionLegacy (line 352) | class QKVAttentionLegacy(nn.Module):
    method __init__ (line 357) | def __init__(self, n_heads):
    method forward (line 361) | def forward(self, qkv):
    method count_flops (line 381) | def count_flops(model, _x, y):
  class QKVAttention (line 385) | class QKVAttention(nn.Module):
    method __init__ (line 390) | def __init__(self, n_heads):
    method forward (line 394) | def forward(self, qkv):
    method count_flops (line 415) | def count_flops(model, _x, y):
  class UNetModel (line 419) | class UNetModel(nn.Module):
    method __init__ (line 449) | def __init__(
    method convert_to_fp16 (line 700) | def convert_to_fp16(self):
    method convert_to_fp32 (line 708) | def convert_to_fp32(self):
    method forward (line 716) | def forward(self, x, timesteps=None, context=None, y=None,**kwargs):
  class EncoderUNetModel (line 760) | class EncoderUNetModel(nn.Module):
    method __init__ (line 766) | def __init__(
    method convert_to_fp16 (line 939) | def convert_to_fp16(self):
    method convert_to_fp32 (line 946) | def convert_to_fp32(self):
    method forward (line 953) | def forward(self, x, timesteps):

FILE: more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/util.py
  function make_beta_schedule (line 21) | def make_beta_schedule(schedule, n_timestep, linear_start=1e-4, linear_e...
  function make_ddim_timesteps (line 46) | def make_ddim_timesteps(ddim_discr_method, num_ddim_timesteps, num_ddpm_...
  function make_ddim_sampling_parameters (line 63) | def make_ddim_sampling_parameters(alphacums, ddim_timesteps, eta, verbos...
  function betas_for_alpha_bar (line 77) | def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.9...
  function extract_into_tensor (line 96) | def extract_into_tensor(a, t, x_shape):
  function checkpoint (line 102) | def checkpoint(func, inputs, params, flag):
  class CheckpointFunction (line 119) | class CheckpointFunction(torch.autograd.Function):
    method forward (line 121) | def forward(ctx, run_function, length, *args):
    method backward (line 131) | def backward(ctx, *output_grads):
  function timestep_embedding (line 151) | def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=Fal...
  function zero_module (line 174) | def zero_module(module):
  function scale_module (line 183) | def scale_module(module, scale):
  function mean_flat (line 192) | def mean_flat(tensor):
  function normalization (line 199) | def normalization(channels):
  class SiLU (line 209) | class SiLU(nn.Module):
    method forward (line 210) | def forward(self, x):
  class GroupNorm32 (line 214) | class GroupNorm32(nn.GroupNorm):
    method forward (line 215) | def forward(self, x):
  function conv_nd (line 218) | def conv_nd(dims, *args, **kwargs):
  function linear (line 231) | def linear(*args, **kwargs):
  function avg_pool_nd (line 238) | def avg_pool_nd(dims, *args, **kwargs):
  class HybridConditioner (line 251) | class HybridConditioner(nn.Module):
    method __init__ (line 253) | def __init__(self, c_concat_config, c_crossattn_config):
    method forward (line 258) | def forward(self, c_concat, c_crossattn):
  function noise_like (line 264) | def noise_like(shape, device, repeat=False):

FILE: more_apps/Facechain-SuDe/ldm/modules/distributions/distributions.py
  class AbstractDistribution (line 5) | class AbstractDistribution:
    method sample (line 6) | def sample(self):
    method mode (line 9) | def mode(self):
  class DiracDistribution (line 13) | class DiracDistribution(AbstractDistribution):
    method __init__ (line 14) | def __init__(self, value):
    method sample (line 17) | def sample(self):
    method mode (line 20) | def mode(self):
  class DiagonalGaussianDistribution (line 24) | class DiagonalGaussianDistribution(object):
    method __init__ (line 25) | def __init__(self, parameters, deterministic=False):
    method sample (line 35) | def sample(self):
    method kl (line 39) | def kl(self, other=None):
    method nll (line 53) | def nll(self, sample, dims=[1,2,3]):
    method mode (line 61) | def mode(self):
  function normal_kl (line 65) | def normal_kl(mean1, logvar1, mean2, logvar2):

FILE: more_apps/Facechain-SuDe/ldm/modules/ema.py
  class LitEma (line 5) | class LitEma(nn.Module):
    method __init__ (line 6) | def __init__(self, model, decay=0.9999, use_num_upates=True):
    method forward (line 25) | def forward(self,model):
    method copy_to (line 46) | def copy_to(self, model):
    method store (line 55) | def store(self, parameters):
    method restore (line 64) | def restore(self, parameters):

FILE: more_apps/Facechain-SuDe/ldm/modules/embedding_manager.py
  function get_clip_token_for_string (line 13) | def get_clip_token_for_string(tokenizer, string):
  function get_bert_token_for_string (line 21) | def get_bert_token_for_string(tokenizer, string):
  function get_embedding_for_clip_token (line 29) | def get_embedding_for_clip_token(embedder, token):
  class EmbeddingManager (line 33) | class EmbeddingManager(nn.Module):
    method __init__ (line 34) | def __init__(
    method forward (line 93) | def forward(
    method save (line 138) | def save(self, ckpt_path):
    method load (line 142) | def load(self, ckpt_path):
    method get_embedding_norms_squared (line 148) | def get_embedding_norms_squared(self):
    method embedding_parameters (line 154) | def embedding_parameters(self):
    method embedding_to_coarse_loss (line 157) | def embedding_to_coarse_loss(self):

FILE: more_apps/Facechain-SuDe/ldm/modules/encoders/modules.py
  function _expand_mask (line 11) | def _expand_mask(mask, dtype, tgt_len = None):
  function _build_causal_attention_mask (line 24) | def _build_causal_attention_mask(bsz, seq_len, dtype):
  class AbstractEncoder (line 33) | class AbstractEncoder(nn.Module):
    method __init__ (line 34) | def __init__(self):
    method encode (line 37) | def encode(self, *args, **kwargs):
  class ClassEmbedder (line 42) | class ClassEmbedder(nn.Module):
    method __init__ (line 43) | def __init__(self, embed_dim, n_classes=1000, key='class'):
    method forward (line 48) | def forward(self, batch, key=None):
  class TransformerEmbedder (line 57) | class TransformerEmbedder(AbstractEncoder):
    method __init__ (line 59) | def __init__(self, n_embed, n_layer, vocab_size, max_seq_len=77, devic...
    method forward (line 65) | def forward(self, tokens):
    method encode (line 70) | def encode(self, x):
  class BERTTokenizer (line 74) | class BERTTokenizer(AbstractEncoder):
    method __init__ (line 76) | def __init__(self, device="cuda", vq_interface=True, max_length=77):
    method forward (line 84) | def forward(self, text):
    method encode (line 91) | def encode(self, text):
    method decode (line 97) | def decode(self, text):
  class BERTEmbedder (line 101) | class BERTEmbedder(AbstractEncoder):
    method __init__ (line 103) | def __init__(self, n_embed, n_layer, vocab_size=30522, max_seq_len=77,
    method forward (line 114) | def forward(self, text, embedding_manager=None):
    method encode (line 124) | def encode(self, text, **kwargs):
  class SpatialRescaler (line 128) | class SpatialRescaler(nn.Module):
    method __init__ (line 129) | def __init__(self,
    method forward (line 147) | def forward(self,x):
    method encode (line 156) | def encode(self, x):
  class FrozenCLIPEmbedder (line 159) | class FrozenCLIPEmbedder(AbstractEncoder):
    method __init__ (line 161) | def __init__(self, version="openai/clip-vit-large-patch14", device="cu...
    method freeze (line 314) | def freeze(self):
    method forward (line 319) | def forward(self, text, **kwargs):
    method encode (line 331) | def encode(self, text, **kwargs):
  class FrozenCLIPTextEmbedder (line 335) | class FrozenCLIPTextEmbedder(nn.Module):
    method __init__ (line 339) | def __init__(self, version='ViT-L/14', device="cuda", max_length=77, n...
    method freeze (line 347) | def freeze(self):
    method forward (line 352) | def forward(self, text):
    method encode (line 359) | def encode(self, text):
  class FrozenClipImageEmbedder (line 367) | class FrozenClipImageEmbedder(nn.Module):
    method __init__ (line 371) | def __init__(
    method preprocess (line 386) | def preprocess(self, x):
    method forward (line 396) | def forward(self, x):

FILE: more_apps/Facechain-SuDe/ldm/modules/encoders/modules_bak.py
  function _expand_mask (line 11) | def _expand_mask(mask, dtype, tgt_len = None):
  function _build_causal_attention_mask (line 24) | def _build_causal_attention_mask(bsz, seq_len, dtype):
  class AbstractEncoder (line 33) | class AbstractEncoder(nn.Module):
    method __init__ (line 34) | def __init__(self):
    method encode (line 37) | def encode(self, *args, **kwargs):
  class ClassEmbedder (line 42) | class ClassEmbedder(nn.Module):
    method __init__ (line 43) | def __init__(self, embed_dim, n_classes=1000, key='class'):
    method forward (line 48) | def forward(self, batch, key=None):
  class TransformerEmbedder (line 57) | class TransformerEmbedder(AbstractEncoder):
    method __init__ (line 59) | def __init__(self, n_embed, n_layer, vocab_size, max_seq_len=77, devic...
    method forward (line 65) | def forward(self, tokens):
    method encode (line 70) | def encode(self, x):
  class BERTTokenizer (line 74) | class BERTTokenizer(AbstractEncoder):
    method __init__ (line 76) | def __init__(self, device="cuda", vq_interface=True, max_length=77):
    method forward (line 84) | def forward(self, text):
    method encode (line 91) | def encode(self, text):
    method decode (line 97) | def decode(self, text):
  class BERTEmbedder (line 101) | class BERTEmbedder(AbstractEncoder):
    method __init__ (line 103) | def __init__(self, n_embed, n_layer, vocab_size=30522, max_seq_len=77,
    method forward (line 114) | def forward(self, text, embedding_manager=None):
    method encode (line 122) | def encode(self, text, **kwargs):
  class SpatialRescaler (line 126) | class SpatialRescaler(nn.Module):
    method __init__ (line 127) | def __init__(self,
    method forward (line 145) | def forward(self,x):
    method encode (line 154) | def encode(self, x):
  class FrozenCLIPEmbedder (line 157) | class FrozenCLIPEmbedder(AbstractEncoder):
    method __init__ (line 159) | def __init__(self, version="openai/clip-vit-large-patch14", device="cu...
    method freeze (line 410) | def freeze(self):
    method forward (line 415) | def forward(self, text, **kwargs):
    method encode (line 423) | def encode(self, text, **kwargs):
  class FrozenCLIPTextEmbedder (line 427) | class FrozenCLIPTextEmbedder(nn.Module):
    method __init__ (line 431) | def __init__(self, version='ViT-L/14', device="cuda", max_length=77, n...
    method freeze (line 439) | def freeze(self):
    method forward (line 444) | def forward(self, text):
    method encode (line 451) | def encode(self, text):
  class FrozenClipImageEmbedder (line 459) | class FrozenClipImageEmbedder(nn.Module):
    method __init__ (line 463) | def __init__(
    method preprocess (line 478) | def preprocess(self, x):
    method forward (line 488) | def forward(self, x):

FILE: more_apps/Facechain-SuDe/ldm/modules/image_degradation/bsrgan.py
  function modcrop_np (line 29) | def modcrop_np(img, sf):
  function analytic_kernel (line 49) | def analytic_kernel(k):
  function anisotropic_Gaussian (line 65) | def anisotropic_Gaussian(ksize=15, theta=np.pi, l1=6, l2=6):
  function gm_blur_kernel (line 86) | def gm_blur_kernel(mean, cov, size=15):
  function shift_pixel (line 99) | def shift_pixel(x, sf, upper_left=True):
  function blur (line 128) | def blur(x, k):
  function gen_kernel (line 145) | def gen_kernel(k_size=np.array([15, 15]), scale_factor=np.array([4, 4]),...
  function fspecial_gaussian (line 187) | def fspecial_gaussian(hsize, sigma):
  function fspecial_laplacian (line 201) | def fspecial_laplacian(alpha):
  function fspecial (line 210) | def fspecial(filter_type, *args, **kwargs):
  function bicubic_degradation (line 228) | def bicubic_degradation(x, sf=3):
  function srmd_degradation (line 240) | def srmd_degradation(x, k, sf=3):
  function dpsr_degradation (line 262) | def dpsr_degradation(x, k, sf=3):
  function classical_degradation (line 284) | def classical_degradation(x, k, sf=3):
  function add_sharpening (line 299) | def add_sharpening(img, weight=0.5, radius=50, threshold=10):
  function add_blur (line 325) | def add_blur(img, sf=4):
  function add_resize (line 339) | def add_resize(img, sf=4):
  function add_Gaussian_noise (line 369) | def add_Gaussian_noise(img, noise_level1=2, noise_level2=25):
  function add_speckle_noise (line 386) | def add_speckle_noise(img, noise_level1=2, noise_level2=25):
  function add_Poisson_noise (line 404) | def add_Poisson_noise(img):
  function add_JPEG_noise (line 418) | def add_JPEG_noise(img):
  function random_crop (line 427) | def random_crop(lq, hq, sf=4, lq_patchsize=64):
  function degradation_bsrgan (line 438) | def degradation_bsrgan(img, sf=4, lq_patchsize=72, isp_model=None):
  function degradation_bsrgan_variant (line 530) | def degradation_bsrgan_variant(image, sf=4, isp_model=None):
  function degradation_bsrgan_plus (line 617) | def degradation_bsrgan_plus(img, sf=4, shuffle_prob=0.5, use_sharp=True,...

FILE: more_apps/Facechain-SuDe/ldm/modules/image_degradation/bsrgan_light.py
  function modcrop_np (line 29) | def modcrop_np(img, sf):
  function analytic_kernel (line 49) | def analytic_kernel(k):
  function anisotropic_Gaussian (line 65) | def anisotropic_Gaussian(ksize=15, theta=np.pi, l1=6, l2=6):
  function gm_blur_kernel (line 86) | def gm_blur_kernel(mean, cov, size=15):
  function shift_pixel (line 99) | def shift_pixel(x, sf, upper_left=True):
  function blur (line 128) | def blur(x, k):
  function gen_kernel (line 145) | def gen_kernel(k_size=np.array([15, 15]), scale_factor=np.array([4, 4]),...
  function fspecial_gaussian (line 187) | def fspecial_gaussian(hsize, sigma):
  function fspecial_laplacian (line 201) | def fspecial_laplacian(alpha):
  function fspecial (line 210) | def fspecial(filter_type, *args, **kwargs):
  function bicubic_degradation (line 228) | def bicubic_degradation(x, sf=3):
  function srmd_degradation (line 240) | def srmd_degradation(x, k, sf=3):
  function dpsr_degradation (line 262) | def dpsr_degradation(x, k, sf=3):
  function classical_degradation (line 284) | def classical_degradation(x, k, sf=3):
  function add_sharpening (line 299) | def add_sharpening(img, weight=0.5, radius=50, threshold=10):
  function add_blur (line 325) | def add_blur(img, sf=4):
  function add_resize (line 343) | def add_resize(img, sf=4):
  function add_Gaussian_noise (line 373) | def add_Gaussian_noise(img, noise_level1=2, noise_level2=25):
  function add_speckle_noise (line 390) | def add_speckle_noise(img, noise_level1=2, noise_level2=25):
  function add_Poisson_noise (line 408) | def add_Poisson_noise(img):
  function add_JPEG_noise (line 422) | def add_JPEG_noise(img):
  function random_crop (line 431) | def random_crop(lq, hq, sf=4, lq_patchsize=64):
  function degradation_bsrgan (line 442) | def degradation_bsrgan(img, sf=4, lq_patchsize=72, isp_model=None):
  function degradation_bsrgan_variant (line 534) | def degradation_bsrgan_variant(image, sf=4, isp_model=None):

FILE: more_apps/Facechain-SuDe/ldm/modules/image_degradation/utils_image.py
  function is_image_file (line 29) | def is_image_file(filename):
  function get_timestamp (line 33) | def get_timestamp():
  function imshow (line 37) | def imshow(x, title=None, cbar=False, figsize=None):
  function surf (line 47) | def surf(Z, cmap='rainbow', figsize=None):
  function get_image_paths (line 67) | def get_image_paths(dataroot):
  function _get_paths_from_images (line 74) | def _get_paths_from_images(path):
  function patches_from_image (line 93) | def patches_from_image(img, p_size=512, p_overlap=64, p_max=800):
  function imssave (line 112) | def imssave(imgs, img_path):
  function split_imageset (line 125) | def split_imageset(original_dataroot, taget_dataroot, n_channels=3, p_si...
  function mkdir (line 153) | def mkdir(path):
  function mkdirs (line 158) | def mkdirs(paths):
  function mkdir_and_rename (line 166) | def mkdir_and_rename(path):
  function imread_uint (line 185) | def imread_uint(path, n_channels=3):
  function imsave (line 203) | def imsave(img, img_path):
  function imwrite (line 209) | def imwrite(img, img_path):
  function read_img (line 220) | def read_img(path):
  function uint2single (line 249) | def uint2single(img):
  function single2uint (line 254) | def single2uint(img):
  function uint162single (line 259) | def uint162single(img):
  function single2uint16 (line 264) | def single2uint16(img):
  function uint2tensor4 (line 275) | def uint2tensor4(img):
  function uint2tensor3 (line 282) | def uint2tensor3(img):
  function tensor2uint (line 289) | def tensor2uint(img):
  function single2tensor3 (line 302) | def single2tensor3(img):
  function single2tensor4 (line 307) | def single2tensor4(img):
  function tensor2single (line 312) | def tensor2single(img):
  function tensor2single3 (line 320) | def tensor2single3(img):
  function single2tensor5 (line 329) | def single2tensor5(img):
  function single32tensor5 (line 333) | def single32tensor5(img):
  function single42tensor4 (line 337) | def single42tensor4(img):
  function tensor2img (line 342) | def tensor2img(tensor, out_type=np.uint8, min_max=(0, 1)):
  function augment_img (line 380) | def augment_img(img, mode=0):
  function augment_img_tensor4 (line 401) | def augment_img_tensor4(img, mode=0):
  function augment_img_tensor (line 422) | def augment_img_tensor(img, mode=0):
  function augment_img_np3 (line 441) | def augment_img_np3(img, mode=0):
  function augment_imgs (line 469) | def augment_imgs(img_list, hflip=True, rot=True):
  function modcrop (line 494) | def modcrop(img_in, scale):
  function shave (line 510) | def shave(img_in, border=0):
  function rgb2ycbcr (line 529) | def rgb2ycbcr(img, only_y=True):
  function ycbcr2rgb (line 553) | def ycbcr2rgb(img):
  function bgr2ycbcr (line 573) | def bgr2ycbcr(img, only_y=True):
  function channel_convert (line 597) | def channel_convert(in_c, tar_type, img_list):
  function calculate_psnr (line 621) | def calculate_psnr(img1, img2, border=0):
  function calculate_ssim (line 642) | def calculate_ssim(img1, img2, border=0):
  function ssim (line 669) | def ssim(img1, img2):
  function cubic (line 700) | def cubic(x):
  function calculate_weights_indices (line 708) | def calculate_weights_indices(in_length, out_length, scale, kernel, kern...
  function imresize (line 766) | def imresize(img, scale, antialiasing=True):
  function imresize_np (line 839) | def imresize_np(img, scale, antialiasing=True):

FILE: more_apps/Facechain-SuDe/ldm/modules/losses/contperceptual.py
  class LPIPSWithDiscriminator (line 7) | class LPIPSWithDiscriminator(nn.Module):
    method __init__ (line 8) | def __init__(self, disc_start, logvar_init=0.0, kl_weight=1.0, pixello...
    method calculate_adaptive_weight (line 32) | def calculate_adaptive_weight(self, nll_loss, g_loss, last_layer=None):
    method forward (line 45) | def forward(self, inputs, reconstructions, posteriors, optimizer_idx,

FILE: more_apps/Facechain-SuDe/ldm/modules/losses/vqperceptual.py
  function hinge_d_loss_with_exemplar_weights (line 11) | def hinge_d_loss_with_exemplar_weights(logits_real, logits_fake, weights):
  function adopt_weight (line 20) | def adopt_weight(weight, global_step, threshold=0, value=0.):
  function measure_perplexity (line 26) | def measure_perplexity(predicted_indices, n_embed):
  function l1 (line 35) | def l1(x, y):
  function l2 (line 39) | def l2(x, y):
  class VQLPIPSWithDiscriminator (line 43) | class VQLPIPSWithDiscriminator(nn.Module):
    method __init__ (line 44) | def __init__(self, disc_start, codebook_weight=1.0, pixelloss_weight=1.0,
    method calculate_adaptive_weight (line 85) | def calculate_adaptive_weight(self, nll_loss, g_loss, last_layer=None):
    method forward (line 98) | def forward(self, codebook_loss, inputs, reconstructions, optimizer_idx,

FILE: more_apps/Facechain-SuDe/ldm/modules/x_transformer.py
  class AbsolutePositionalEmbedding (line 25) | class AbsolutePositionalEmbedding(nn.Module):
    method __init__ (line 26) | def __init__(self, dim, max_seq_len):
    method init_ (line 31) | def init_(self):
    method forward (line 34) | def forward(self, x):
  class FixedPositionalEmbedding (line 39) | class FixedPositionalEmbedding(nn.Module):
    method __init__ (line 40) | def __init__(self, dim):
    method forward (line 45) | def forward(self, x, seq_dim=1, offset=0):
  function exists (line 54) | def exists(val):
  function default (line 58) | def default(val, d):
  function always (line 64) | def always(val):
  function not_equals (line 70) | def not_equals(val):
  function equals (line 76) | def equals(val):
  function max_neg_value (line 82) | def max_neg_value(tensor):
  function pick_and_pop (line 88) | def pick_and_pop(keys, d):
  function group_dict_by_key (line 93) | def group_dict_by_key(cond, d):
  function string_begins_with (line 102) | def string_begins_with(prefix, str):
  function group_by_key_prefix (line 106) | def group_by_key_prefix(prefix, d):
  function groupby_prefix_and_trim (line 110) | def groupby_prefix_and_trim(prefix, d):
  class Scale (line 117) | class Scale(nn.Module):
    method __init__ (line 118) | def __init__(self, value, fn):
    method forward (line 123) | def forward(self, x, **kwargs):
  class Rezero (line 128) | class Rezero(nn.Module):
    method __init__ (line 129) | def __init__(self, fn):
    method forward (line 134) | def forward(self, x, **kwargs):
  class ScaleNorm (line 139) | class ScaleNorm(nn.Module):
    method __init__ (line 140) | def __init__(self, dim, eps=1e-5):
    method forward (line 146) | def forward(self, x):
  class RMSNorm (line 151) | class RMSNorm(nn.Module):
    method __init__ (line 152) | def __init__(self, dim, eps=1e-8):
    method forward (line 158) | def forward(self, x):
  class Residual (line 163) | class Residual(nn.Module):
    method forward (line 164) | def forward(self, x, residual):
  class GRUGating (line 168) | class GRUGating(nn.Module):
    method __init__ (line 169) | def __init__(self, dim):
    method forward (line 173) | def forward(self, x, residual):
  class GEGLU (line 184) | class GEGLU(nn.Module):
    method __init__ (line 185) | def __init__(self, dim_in, dim_out):
    method forward (line 189) | def forward(self, x):
  class FeedForward (line 194) | class FeedForward(nn.Module):
    method __init__ (line 195) | def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.):
    method forward (line 210) | def forward(self, x):
  class Attention (line 215) | class Attention(nn.Module):
    method __init__ (line 216) | def __init__(
    method forward (line 268) | def forward(
  class AttentionLayers (line 370) | class AttentionLayers(nn.Module):
    method __init__ (line 371) | def __init__(
    method forward (line 481) | def forward(
  class Encoder (line 542) | class Encoder(AttentionLayers):
    method __init__ (line 543) | def __init__(self, **kwargs):
  class TransformerWrapper (line 549) | class TransformerWrapper(nn.Module):
    method __init__ (line 550) | def __init__(
    method init_ (line 596) | def init_(self):
    method forward (line 599) | def forward(

FILE: more_apps/Facechain-SuDe/ldm/util.py
  function log_txt_as_img (line 17) | def log_txt_as_img(wh, xc, size=10):
  function ismap (line 41) | def ismap(x):
  function isimage (line 47) | def isimage(x):
  function exists (line 53) | def exists(x):
  function default (line 57) | def default(val, d):
  function mean_flat (line 63) | def mean_flat(tensor):
  function count_params (line 71) | def count_params(model, verbose=False):
  function instantiate_from_config (line 78) | def instantiate_from_config(config, **kwargs):
  function get_obj_from_str (line 88) | def get_obj_from_str(string, reload=False):
  function _do_parallel_data_prefetch (line 96) | def _do_parallel_data_prefetch(func, Q, data, idx, idx_to_fn=False):
  function parallel_data_prefetch (line 108) | def parallel_data_prefetch(

FILE: more_apps/Facechain-SuDe/main.py
  function load_model_from_config (line 24) | def load_model_from_config(config, ckpt, verbose=False):
  function get_parser (line 41) | def get_parser(**parser_kwargs):
  function nondefault_trainer_args (line 186) | def nondefault_trainer_args(opt):
  class WrappedDataset (line 193) | class WrappedDataset(Dataset):
    method __init__ (line 196) | def __init__(self, dataset):
    method __len__ (line 199) | def __len__(self):
    method __getitem__ (line 202) | def __getitem__(self, idx):
  function worker_init_fn (line 206) | def worker_init_fn(_):
  class ConcatDataset (line 221) | class ConcatDataset(Dataset):
    method __init__ (line 222) | def __init__(self, *datasets):
    method __getitem__ (line 225) | def __getitem__(self, idx):
    method __len__ (line 228) | def __len__(self):
  class DataModuleFromConfig (line 231) | class DataModuleFromConfig(pl.LightningDataModule):
    method __init__ (line 232) | def __init__(self, batch_size, train=None, reg=None, validation=None, ...
    method prepare_data (line 258) | def prepare_data(self):
    method setup (line 262) | def setup(self, stage=None):
    method _train_dataloader (line 270) | def _train_dataloader(self):
    method _val_dataloader (line 284) | def _val_dataloader(self, shuffle=False):
    method _test_dataloader (line 295) | def _test_dataloader(self, shuffle=False):
    method _predict_dataloader (line 308) | def _predict_dataloader(self, shuffle=False):
  class SetupCallback (line 317) | class SetupCallback(Callback):
    method __init__ (line 318) | def __init__(self, resume, now, logdir, ckptdir, cfgdir, config, light...
    method on_keyboard_interrupt (line 328) | def on_keyboard_interrupt(self, trainer, pl_module):
    method on_pretrain_routine_start (line 334) | def on_pretrain_routine_start(self, trainer, pl_module):
  class ImageLogger (line 366) | class ImageLogger(Callback):
    method __init__ (line 367) | def __init__(self, batch_frequency, max_images, clamp=True, increase_l...
    method _testtube (line 387) | def _testtube(self, pl_module, images, batch_idx, split):
    method log_local (line 398) | def log_local(self, save_dir, split, images,
    method log_img (line 417) | def log_img(self, pl_module, batch, batch_idx, split="train"):
    method check_frequency (line 449) | def check_frequency(self, check_idx):
    method on_train_batch_end (line 460) | def on_train_batch_end(self, trainer, pl_module, outputs, batch, batch...
    method on_validation_batch_end (line 464) | def on_validation_batch_end(self, trainer, pl_module, outputs, batch, ...
  class CUDACallback (line 472) | class CUDACallback(Callback):
    method on_train_epoch_start (line 474) | def on_train_epoch_start(self, trainer, pl_module):
    method on_train_epoch_end (line 480) | def on_train_epoch_end(self, trainer, pl_module):
  class ModeSwapCallback (line 494) | class ModeSwapCallback(Callback):
    method __init__ (line 496) | def __init__(self, swap_step=2000):
    method on_train_epoch_start (line 501) | def on_train_epoch_start(self, trainer, pl_module):
  function melk (line 815) | def melk(*args, **kwargs):
  function divein (line 823) | def divein(*args, **kwargs):

FILE: more_apps/Facechain-SuDe/merge_embeddings.py
  function get_placeholder_loop (line 9) | def get_placeholder_loop(placeholder_string, embedder, is_sd):
  function get_clip_token_for_string (line 24) | def get_clip_token_for_string(tokenizer, string):
  function get_bert_token_for_string (line 34) | def get_bert_token_for_string(tokenizer, string):

FILE: more_apps/Facechain-SuDe/scripts/evaluate_model.py
  function load_model_from_config (line 21) | def load_model_from_config(config, ckpt, verbose=False):
  function evaluate_model_func (line 40) | def evaluate_model_func(temp_prompt_adj, prompt, ckpt_path, data_dir, ou...
  function extract_all_images (line 67) | def extract_all_images(images, model, datasetclass, device, batch_size=6...
  function dinoeval_image (line 86) | def dinoeval_image(image_dir, image_dir_ref, device):
  function Convert (line 109) | def Convert(image):
  class DINOImageDataset (line 113) | class DINOImageDataset(torch.utils.data.Dataset):
    method __init__ (line 114) | def __init__(self, data):
    method _transform_test (line 119) | def _transform_test(self, n_px):
    method __getitem__ (line 128) | def __getitem__(self, idx):
    method __len__ (line 134) | def __len__(self):

FILE: more_apps/Facechain-SuDe/scripts/inpaint.py
  function make_batch (line 11) | def make_batch(image, mask, device):

FILE: more_apps/Facechain-SuDe/scripts/sample_diffusion.py
  function custom_to_pil (line 15) | def custom_to_pil(x):
  function custom_to_np (line 27) | def custom_to_np(x):
  function logs2pil (line 36) | def logs2pil(logs, keys=["sample"]):
  function convsample (line 54) | def convsample(model, shape, return_intermediates=True,
  function convsample_ddim (line 69) | def convsample_ddim(model, steps, shape, eta=1.0
  function make_convolutional_sample (line 79) | def make_convolutional_sample(model, batch_size, vanilla=False, custom_s...
  function run (line 108) | def run(model, logdir, batch_size=50, vanilla=False, custom_steps=None, ...
  function save_logs (line 143) | def save_logs(logs, path, n_saved=0, key="sample", np_path=None):
  function get_parser (line 162) | def get_parser():
  function load_model_from_config (line 220) | def load_model_from_config(config, sd):
  function load_model (line 228) | def load_model(config, ckpt, gpu, eval_mode):

FILE: more_apps/Facechain-SuDe/scripts/stable_txt2img.py
  function chunk (line 22) | def chunk(it, size):
  function load_model_from_config (line 27) | def load_model_from_config(config, ckpt, verbose=False):
  function load_model_from_config_st (line 47) | def load_model_from_config_st(config, ckpt, verbose=False):
  function main (line 68) | def main():

FILE: more_apps/Facechain-SuDe/scripts/txt2img.py
  function load_model_from_config (line 14) | def load_model_from_config(config, ckpt, verbose=False):

FILE: run_inference.py
  function generate_pos_prompt (line 10) | def generate_pos_prompt(style_model, prompt_cloth):

FILE: scripts/facechain_sdwebui.py
  function on_ui_tabs (line 8) | def on_ui_tabs():
  function on_ui_settings (line 32) | def on_ui_settings():

FILE: train_style/convert_lora.py
  function convert_lora (line 4) | def convert_lora(src, dst):

FILE: train_style/deepbooru.py
  class DeepDanbooruModel (line 20) | class DeepDanbooruModel(nn.Module):
    method __init__ (line 21) | def __init__(self):
    method forward (line 207) | def forward(self, *inputs):
    method load_state_dict (line 685) | def load_state_dict(self, state_dict, **kwargs):
  function resize_image (line 691) | def resize_image(im, width, height):
  class DeepDanbooru (line 716) | class DeepDanbooru:
    method __init__ (line 717) | def __init__(self):
    method start (line 728) | def start(self):
    method stop (line 731) | def stop(self):
    method tag (line 736) | def tag(self, pil_image, threshold=0.5):

FILE: train_style/demo.py
  function set_img (line 13) | def set_img(files, uuid, output_model_name):
  function init_tag (line 50) | def init_tag():
  function cut_img (line 55) | def cut_img(img_path):
  function train_lora (line 85) | def train_lora(uuid, output_model_name, prompt_input, train_folder, gall...
  function set_prompt (line 167) | def set_prompt():

FILE: train_style/train_text_to_image_lora.py
  function save_model_card (line 74) | def save_model_card(
  function log_validation (line 115) | def log_validation(
  function parse_args (line 157) | def parse_args():
  function main (line 449) | def main():
Condensed preview — 249 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,478K chars).
[
  {
    "path": ".gitattributes",
    "chars": 50,
    "preview": "*.safetensors filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".gitignore",
    "chars": 1465,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\ntest.py\n# C extensions\n*.so\n\n# Distribution / "
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 21071,
    "preview": "<p align=\"center\">\n    <br>\n    <img src=\"https://modelscope.oss-cn-beijing.aliyuncs.com/modelscope.gif\" width=\"400\"/>\n "
  },
  {
    "path": "README_ZH.md",
    "chars": 12665,
    "preview": "<p align=\"center\">\n    <br>\n    <img src=\"https://modelscope.oss-cn-beijing.aliyuncs.com/modelscope.gif\" width=\"400\"/>\n "
  },
  {
    "path": "app.py",
    "chars": 26956,
    "preview": "# Copyright (c) Alibaba, Inc. and its affiliates.\nimport enum\nimport os\nimport json\nimport shutil\nimport slugify\nimport "
  },
  {
    "path": "face_adapter/__init__.py",
    "chars": 62,
    "preview": "from .face_adapter_v1 import FaceAdapter_v1, Face_Extracter_v1"
  },
  {
    "path": "face_adapter/face_adapter_v1.py",
    "chars": 18223,
    "preview": "import os\nfrom typing import List\n\nimport torch\nfrom diffusers import StableDiffusionPipeline\nfrom diffusers.pipelines.c"
  },
  {
    "path": "face_adapter/face_attention_processor_v1.py",
    "chars": 25561,
    "preview": "# modified from https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py\nimport to"
  },
  {
    "path": "face_adapter/face_preprocess.py",
    "chars": 4575,
    "preview": "import cv2\nimport numpy as np\nfrom skimage import transform as trans\n\ndef read_image(img_path, **kwargs):\n  mode = kwarg"
  },
  {
    "path": "face_adapter/utils.py",
    "chars": 116,
    "preview": "import torch.nn.functional as F\n\ndef is_torch2_available():\n    return hasattr(F, \"scaled_dot_product_attention\")\n\n\n"
  },
  {
    "path": "face_adapter/vit.py",
    "chars": 11792,
    "preview": "import torch\nimport torch.nn as nn\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\nfrom typing import "
  },
  {
    "path": "face_module/DamoFD/README.md",
    "chars": 45,
    "preview": "### The code will be released in the future.\n"
  },
  {
    "path": "face_module/TopoFR/GUM.py",
    "chars": 1618,
    "preview": "### GUM model\nimport numpy as np\nfrom scipy.stats import multivariate_normal\nfrom sklearn import preprocessing\nimport to"
  },
  {
    "path": "face_module/TopoFR/README.md",
    "chars": 4005,
    "preview": "<h2 align=\"center\">TopoFR: A Closer Look at Topology Alignment on Face Recognition\n<h5 align=\"center\"> If you like TopoF"
  },
  {
    "path": "face_module/TopoFR/backbones/__init__.py",
    "chars": 7741,
    "preview": "from .iresnet import iresnet18, iresnet34, iresnet50, iresnet100, iresnet200\nfrom .mobilefacenet import get_mbf\n\n\ndef ge"
  },
  {
    "path": "face_module/TopoFR/backbones/iresnet.py",
    "chars": 8040,
    "preview": "import torch\nfrom torch import nn\nfrom torch.utils.checkpoint import checkpoint\nfrom torch.nn.functional import linear, "
  },
  {
    "path": "face_module/TopoFR/backbones/iresnet2060.py",
    "chars": 6708,
    "preview": "import torch\nfrom torch import nn\n\nassert torch.__version__ >= \"1.8.1\"\nfrom torch.utils.checkpoint import checkpoint_seq"
  },
  {
    "path": "face_module/TopoFR/backbones/mobilefacenet.py",
    "chars": 5591,
    "preview": "'''\nAdapted from https://github.com/cavalleria/cavaface.pytorch/blob/master/backbone/mobilefacenet.py\nOriginal author ca"
  },
  {
    "path": "face_module/TopoFR/configs/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TopoFR/configs/base.py",
    "chars": 896,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/configs/glint360k_r100.py",
    "chars": 744,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/configs/glint360k_r200.py",
    "chars": 744,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/configs/glint360k_r50.py",
    "chars": 731,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/configs/ms1mv2_r100.py",
    "chars": 694,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/configs/ms1mv2_r200.py",
    "chars": 694,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/configs/ms1mv2_r50.py",
    "chars": 693,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TopoFR/dataset.py",
    "chars": 7773,
    "preview": "import numbers\nimport os\nimport queue as Queue\nimport threading\nfrom typing import Iterable\n\nimport mxnet as mx\nimport n"
  },
  {
    "path": "face_module/TopoFR/docs/eval.md",
    "chars": 1249,
    "preview": "## Eval on ICCV2021-MFR\n\ncoming soon.\n\n\n## Eval IJBC\nYou can eval ijbc with pytorch or onnx.\n\n\n1. Eval IJBC With Onnx\n``"
  },
  {
    "path": "face_module/TopoFR/docs/install.md",
    "chars": 440,
    "preview": "## [v1.11.0](https://pytorch.org/)\n\n## [v1.9.0](https://pytorch.org/get-started/previous-versions/#linux-and-windows-7)\n"
  },
  {
    "path": "face_module/TopoFR/docs/install_dali.md",
    "chars": 5,
    "preview": "TODO\n"
  },
  {
    "path": "face_module/TopoFR/docs/modelzoo.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TopoFR/docs/prepare_webface42m.md",
    "chars": 1660,
    "preview": "\n\n\n## 1. Download Datasets and Unzip\n\nDownload WebFace42M from [https://www.face-benchmark.org/download.html](https://ww"
  },
  {
    "path": "face_module/TopoFR/docs/speed_benchmark.md",
    "chars": 5465,
    "preview": "## Test Training Speed\n\n- Test Commands\n\nYou need to use the following two commands to test the Partial FC training perf"
  },
  {
    "path": "face_module/TopoFR/eval/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TopoFR/eval/verification.py",
    "chars": 16212,
    "preview": "\"\"\"Helper for evaluation on the Labeled Faces in the Wild dataset \n\"\"\"\n\n# MIT License\n#\n# Copyright (c) 2016 David Sandb"
  },
  {
    "path": "face_module/TopoFR/eval_ijbc_glint360k.py",
    "chars": 17492,
    "preview": "# coding: utf-8\n\nimport os\nimport pickle\n\nimport matplotlib\nimport pandas as pd\n\nmatplotlib.use('Agg')\nimport matplotlib"
  },
  {
    "path": "face_module/TopoFR/eval_ijbc_ms1mv2.py",
    "chars": 17434,
    "preview": "# coding: utf-8\n\nimport os\nimport pickle\n\nimport matplotlib\nimport pandas as pd\n\nmatplotlib.use('Agg')\nimport matplotlib"
  },
  {
    "path": "face_module/TopoFR/flops.py",
    "chars": 686,
    "preview": "from ptflops import get_model_complexity_info\nfrom backbones import get_model\nimport argparse\n\nif __name__ == '__main__'"
  },
  {
    "path": "face_module/TopoFR/inference.py",
    "chars": 1033,
    "preview": "import argparse\n\nimport cv2\nimport numpy as np\nimport torch\n\nfrom backbones import get_model\n\n\n@torch.no_grad()\ndef infe"
  },
  {
    "path": "face_module/TopoFR/losses.py",
    "chars": 3897,
    "preview": "import torch\nimport math\n\n\nclass CombinedMarginLoss(torch.nn.Module):\n    def __init__(self, \n                 s, \n     "
  },
  {
    "path": "face_module/TopoFR/lr_scheduler.py",
    "chars": 1145,
    "preview": "from torch.optim.lr_scheduler import _LRScheduler\n\n\nclass PolyScheduler(_LRScheduler):\n    def __init__(self, optimizer,"
  },
  {
    "path": "face_module/TopoFR/onnx_helper.py",
    "chars": 10422,
    "preview": "from __future__ import division\nimport datetime\nimport os\nimport os.path as osp\nimport glob\nimport numpy as np\nimport cv"
  },
  {
    "path": "face_module/TopoFR/onnx_ijbc.py",
    "chars": 10317,
    "preview": "import argparse\nimport os\nimport pickle\nimport timeit\n\nimport cv2\nimport mxnet as mx\nimport numpy as np\nimport pandas as"
  },
  {
    "path": "face_module/TopoFR/partial_fc.py",
    "chars": 19912,
    "preview": "import collections\nfrom typing import Callable\n\nimport torch\nfrom torch import distributed\nfrom torch.nn.functional impo"
  },
  {
    "path": "face_module/TopoFR/persistent_homology.py",
    "chars": 6810,
    "preview": "import copy\nimport torch\nimport torch.backends.cudnn as cudnn\nimport torch.nn as nn\nimport torch.nn.functional as F\nimpo"
  },
  {
    "path": "face_module/TopoFR/requirement.txt",
    "chars": 40,
    "preview": "tensorboard\neasydict\nmxnet\nonnx\nsklearn\n"
  },
  {
    "path": "face_module/TopoFR/topology.py",
    "chars": 4670,
    "preview": "'''\nMethods for calculating lower-dimensional persistent homology.\n'''\n\nimport numpy as np\n\n\nclass UnionFind:\n    '''\n  "
  },
  {
    "path": "face_module/TopoFR/torch2onnx.py",
    "chars": 2236,
    "preview": "import numpy as np\nimport onnx\nimport torch\n\n\ndef convert_onnx(net, path_module, output, opset=11, simplify=False):\n    "
  },
  {
    "path": "face_module/TopoFR/train.py",
    "chars": 9813,
    "preview": "import argparse\nimport logging\nimport os\n\nimport numpy as np\nimport torch\nfrom torch import distributed\nfrom torch.utils"
  },
  {
    "path": "face_module/TopoFR/utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TopoFR/utils/plot.py",
    "chars": 2176,
    "preview": "import os\nimport sys\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom menpo.visualize.viewma"
  },
  {
    "path": "face_module/TopoFR/utils/utils_callbacks.py",
    "chars": 5092,
    "preview": "import logging\nimport os\nimport time\nfrom typing import List\n\nimport torch\n\nfrom eval import verification\nfrom utils.uti"
  },
  {
    "path": "face_module/TopoFR/utils/utils_config.py",
    "chars": 571,
    "preview": "import importlib\nimport os.path as osp\n\n\ndef get_config(config_file):\n    assert config_file.startswith('configs/'), 'co"
  },
  {
    "path": "face_module/TopoFR/utils/utils_distributed_sampler.py",
    "chars": 4264,
    "preview": "import math\nimport os\nimport random\n\nimport numpy as np\nimport torch\nimport torch.distributed as dist\nfrom torch.utils.d"
  },
  {
    "path": "face_module/TopoFR/utils/utils_logging.py",
    "chars": 1110,
    "preview": "import logging\nimport os\nimport sys\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current val"
  },
  {
    "path": "face_module/TransFace/FFT.py",
    "chars": 1550,
    "preview": "import cv2\nimport numpy as np\nfrom math import sqrt\n\ndef amplitude_spectrum_mix(img1, img2, alpha, ratio=1.0):   #img_sr"
  },
  {
    "path": "face_module/TransFace/README.md",
    "chars": 6360,
    "preview": "<h2 align=\"center\">TransFace: Calibrating Transformer Training for Face Recognition from a Data-Centric Perspective\n<h5 "
  },
  {
    "path": "face_module/TransFace/backbones/__init__.py",
    "chars": 3680,
    "preview": "from .iresnet import iresnet18, iresnet34, iresnet50, iresnet100, iresnet200\nfrom .mobilefacenet import get_mbf\n\n\ndef ge"
  },
  {
    "path": "face_module/TransFace/backbones/iresnet.py",
    "chars": 7431,
    "preview": "import torch\nfrom torch import nn\nfrom torch.utils.checkpoint import checkpoint\n\n__all__ = ['iresnet18', 'iresnet34', 'i"
  },
  {
    "path": "face_module/TransFace/backbones/iresnet2060.py",
    "chars": 6708,
    "preview": "import torch\nfrom torch import nn\n\nassert torch.__version__ >= \"1.8.1\"\nfrom torch.utils.checkpoint import checkpoint_seq"
  },
  {
    "path": "face_module/TransFace/backbones/mobilefacenet.py",
    "chars": 5591,
    "preview": "'''\nAdapted from https://github.com/cavalleria/cavaface.pytorch/blob/master/backbone/mobilefacenet.py\nOriginal author ca"
  },
  {
    "path": "face_module/TransFace/backbones/vit.py",
    "chars": 11722,
    "preview": "import torch\nimport torch.nn as nn\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\nfrom typing import "
  },
  {
    "path": "face_module/TransFace/configs/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TransFace/configs/base.py",
    "chars": 896,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TransFace/configs/glint360k_vit_s.py",
    "chars": 726,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TransFace/configs/ms1mv2_vit_s.py",
    "chars": 682,
    "preview": "from easydict import EasyDict as edict\n\n# make training faster\n# our RAM is 256G\n# mount -t tmpfs -o size=140G  tmpfs /t"
  },
  {
    "path": "face_module/TransFace/dataset.py",
    "chars": 7714,
    "preview": "import numbers\nimport os\nimport queue as Queue\nimport threading\nfrom typing import Iterable\n\nimport mxnet as mx\nimport n"
  },
  {
    "path": "face_module/TransFace/dist.sh",
    "chars": 428,
    "preview": "ip_list=(\"ip1\" \"ip2\" \"ip3\" \"ip4\")\n\nconfig=wf42m_pfc03_32gpu_r100\n\nfor((node_rank=0;node_rank<${#ip_list[*]};node_rank++)"
  },
  {
    "path": "face_module/TransFace/docs/eval.md",
    "chars": 1249,
    "preview": "## Eval on ICCV2021-MFR\n\ncoming soon.\n\n\n## Eval IJBC\nYou can eval ijbc with pytorch or onnx.\n\n\n1. Eval IJBC With Onnx\n``"
  },
  {
    "path": "face_module/TransFace/docs/install.md",
    "chars": 440,
    "preview": "## [v1.11.0](https://pytorch.org/)\n\n## [v1.9.0](https://pytorch.org/get-started/previous-versions/#linux-and-windows-7)\n"
  },
  {
    "path": "face_module/TransFace/docs/install_dali.md",
    "chars": 5,
    "preview": "TODO\n"
  },
  {
    "path": "face_module/TransFace/docs/modelzoo.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TransFace/docs/prepare_webface42m.md",
    "chars": 1660,
    "preview": "\n\n\n## 1. Download Datasets and Unzip\n\nDownload WebFace42M from [https://www.face-benchmark.org/download.html](https://ww"
  },
  {
    "path": "face_module/TransFace/docs/speed_benchmark.md",
    "chars": 5465,
    "preview": "## Test Training Speed\n\n- Test Commands\n\nYou need to use the following two commands to test the Partial FC training perf"
  },
  {
    "path": "face_module/TransFace/eval/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TransFace/eval/verification.py",
    "chars": 16205,
    "preview": "\"\"\"Helper for evaluation on the Labeled Faces in the Wild dataset \n\"\"\"\n\n# MIT License\n#\n# Copyright (c) 2016 David Sandb"
  },
  {
    "path": "face_module/TransFace/eval_ijbc.py",
    "chars": 17282,
    "preview": "# coding: utf-8\n\nimport os\nimport pickle\n\nimport matplotlib\nimport pandas as pd\n\nmatplotlib.use('Agg')\nimport matplotlib"
  },
  {
    "path": "face_module/TransFace/flops.py",
    "chars": 702,
    "preview": "from ptflops import get_model_complexity_info\nfrom backbones import get_model\nimport argparse\n\nif __name__ == '__main__'"
  },
  {
    "path": "face_module/TransFace/inference.py",
    "chars": 1227,
    "preview": "import argparse\n\nimport cv2\nimport numpy as np\nimport torch\n\nfrom backbones import get_model\n\n\n@torch.no_grad()\ndef infe"
  },
  {
    "path": "face_module/TransFace/losses.py",
    "chars": 3629,
    "preview": "import torch\nimport math\n\n\nclass CombinedMarginLoss(torch.nn.Module):\n    def __init__(self, \n                 s, \n     "
  },
  {
    "path": "face_module/TransFace/lr_scheduler.py",
    "chars": 1145,
    "preview": "from torch.optim.lr_scheduler import _LRScheduler\n\n\nclass PolyScheduler(_LRScheduler):\n    def __init__(self, optimizer,"
  },
  {
    "path": "face_module/TransFace/onnx_helper.py",
    "chars": 10422,
    "preview": "from __future__ import division\nimport datetime\nimport os\nimport os.path as osp\nimport glob\nimport numpy as np\nimport cv"
  },
  {
    "path": "face_module/TransFace/onnx_ijbc.py",
    "chars": 10531,
    "preview": "import argparse\nimport os\nimport pickle\nimport timeit\n\nimport cv2\nimport mxnet as mx\nimport numpy as np\nimport pandas as"
  },
  {
    "path": "face_module/TransFace/partial_fc_exp.py",
    "chars": 20475,
    "preview": "import collections\nfrom typing import Callable\n\nimport torch\nfrom torch import distributed\nfrom torch.nn.functional impo"
  },
  {
    "path": "face_module/TransFace/requirement.txt",
    "chars": 40,
    "preview": "tensorboard\neasydict\nmxnet\nonnx\nsklearn\n"
  },
  {
    "path": "face_module/TransFace/run.sh",
    "chars": 257,
    "preview": "\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python -m torch.distributed.launch \\\n--nproc_per_node=8 \\\n--nnodes=1 \\\n--node_rank"
  },
  {
    "path": "face_module/TransFace/torch2onnx.py",
    "chars": 2236,
    "preview": "import numpy as np\nimport onnx\nimport torch\n\n\ndef convert_onnx(net, path_module, output, opset=11, simplify=False):\n    "
  },
  {
    "path": "face_module/TransFace/train.py",
    "chars": 9553,
    "preview": "import os\nimport argparse\nimport logging\n\nimport numpy as np\nimport torch\nfrom torch import distributed\nfrom torch.utils"
  },
  {
    "path": "face_module/TransFace/utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "face_module/TransFace/utils/plot.py",
    "chars": 2176,
    "preview": "import os\nimport sys\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom menpo.visualize.viewma"
  },
  {
    "path": "face_module/TransFace/utils/utils_callbacks.py",
    "chars": 5092,
    "preview": "import logging\nimport os\nimport time\nfrom typing import List\n\nimport torch\n\nfrom eval import verification\nfrom utils.uti"
  },
  {
    "path": "face_module/TransFace/utils/utils_config.py",
    "chars": 571,
    "preview": "import importlib\nimport os.path as osp\n\n\ndef get_config(config_file):\n    assert config_file.startswith('configs/'), 'co"
  },
  {
    "path": "face_module/TransFace/utils/utils_distributed_sampler.py",
    "chars": 4264,
    "preview": "import math\nimport os\nimport random\n\nimport numpy as np\nimport torch\nimport torch.distributed as dist\nfrom torch.utils.d"
  },
  {
    "path": "face_module/TransFace/utils/utils_logging.py",
    "chars": 1110,
    "preview": "import logging\nimport os\nimport sys\n\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current val"
  },
  {
    "path": "facechain/constants.py",
    "chars": 15629,
    "preview": "from facechain.utils import project_dir\r\nneg_prompt = '(nsfw:2), paintings, sketches, (worst quality:2), (low quality:2)"
  },
  {
    "path": "facechain/inference_fact.py",
    "chars": 20040,
    "preview": "# Copyright (c) Alibaba, Inc. and its affiliates.\nimport os\nimport time\nimport sys\n\nimport cv2\nimport json\nimport numpy "
  },
  {
    "path": "facechain/inference_inpaint_fact.py",
    "chars": 36745,
    "preview": "# Copyright (c) Alibaba, Inc. and its affiliates.\nimport os\nimport sys\nimport time\n\nimport cv2\nimport json\nimport numpy "
  },
  {
    "path": "facechain/merge_lora.py",
    "chars": 6652,
    "preview": "# Copyright (c) Alibaba, Inc. and its affiliates.\nimport os\nimport re\nfrom collections import defaultdict\n\nimport torch\n"
  },
  {
    "path": "facechain/utils.py",
    "chars": 2291,
    "preview": "# Copyright (c) Alibaba, Inc. and its affiliates.\n\nimport time\nimport subprocess\nfrom modelscope import snapshot_downloa"
  },
  {
    "path": "install.py",
    "chars": 3746,
    "preview": "import launch\nimport os\n\n# TODO: add pip dependency if need extra module only on extension\n\nif not launch.is_installed(\""
  },
  {
    "path": "main.css",
    "chars": 9590,
    "preview": "/* 屏幕宽度大于等于500px的设备 */\n@media screen and (min-width: 500px) {\n  #chatbot, #chatbot_classic, #chatbot_classic textarea{\n "
  },
  {
    "path": "more_apps/Facechain-SuDe/README.md",
    "chars": 3268,
    "preview": "# FaceChain-SuDe: Building Derived Class to Inherit Category Attributes for One-shot Subject-Driven Generation\n![](./ass"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/autoencoder/autoencoder_kl_16x16x16.yaml",
    "chars": 1145,
    "preview": "model:\n  base_learning_rate: 4.5e-6\n  target: ldm.models.autoencoder.AutoencoderKL\n  params:\n    monitor: \"val/rec_loss\""
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/autoencoder/autoencoder_kl_32x32x4.yaml",
    "chars": 1140,
    "preview": "model:\n  base_learning_rate: 4.5e-6\n  target: ldm.models.autoencoder.AutoencoderKL\n  params:\n    monitor: \"val/rec_loss\""
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/autoencoder/autoencoder_kl_64x64x3.yaml",
    "chars": 1139,
    "preview": "model:\n  base_learning_rate: 4.5e-6\n  target: ldm.models.autoencoder.AutoencoderKL\n  params:\n    monitor: \"val/rec_loss\""
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/autoencoder/autoencoder_kl_8x8x64.yaml",
    "chars": 1148,
    "preview": "model:\n  base_learning_rate: 4.5e-6\n  target: ldm.models.autoencoder.AutoencoderKL\n  params:\n    monitor: \"val/rec_loss\""
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/celebahq-ldm-vq-4.yaml",
    "chars": 2028,
    "preview": "model:\n  base_learning_rate: 2.0e-06\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/cin-ldm-vq-f8.yaml",
    "chars": 2360,
    "preview": "model:\n  base_learning_rate: 1.0e-06\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/cin256-v2.yaml",
    "chars": 1553,
    "preview": "model:\n  base_learning_rate: 0.0001\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.00"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/ffhq-ldm-vq-4.yaml",
    "chars": 2020,
    "preview": "model:\n  base_learning_rate: 2.0e-06\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/lsun_bedrooms-ldm-vq-4.yaml",
    "chars": 2024,
    "preview": "model:\n  base_learning_rate: 2.0e-06\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/lsun_churches-ldm-kl-8.yaml",
    "chars": 2284,
    "preview": "model:\n  base_learning_rate: 5.0e-5   # set to target_lr by starting main.py with '--scale_lr False'\n  target: ldm.model"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/txt2img-1p4B-eval.yaml",
    "chars": 1614,
    "preview": "model:\n  base_learning_rate: 5.0e-05\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/txt2img-1p4B-eval_with_tokens.yaml",
    "chars": 1811,
    "preview": "model:\n  base_learning_rate: 5.0e-05\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/txt2img-1p4B-finetune.yaml",
    "chars": 2652,
    "preview": "model:\n  base_learning_rate: 5.0e-3\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.00"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/latent-diffusion/txt2img-1p4B-finetune_style.yaml",
    "chars": 2610,
    "preview": "model:\n  base_learning_rate: 5.0e-3\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.00"
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/stable-diffusion/v1-finetune_unfrozen.yaml",
    "chars": 2893,
    "preview": "model:\n  base_learning_rate: 1.0e-06\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    reg_weight: 2.0\n "
  },
  {
    "path": "more_apps/Facechain-SuDe/configs/stable-diffusion/v1-inference.yaml",
    "chars": 1851,
    "preview": "model:\n  base_learning_rate: 1.0e-04\n  target: ldm.models.diffusion.ddpm.LatentDiffusion\n  params:\n    linear_start: 0.0"
  },
  {
    "path": "more_apps/Facechain-SuDe/environment.yaml",
    "chars": 739,
    "preview": "name: ldm\nchannels:\n  - pytorch\n  - defaults\ndependencies:\n  - python=3.8.10\n  - pip=20.3\n  - cudatoolkit=11.3\n  - pytor"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/data/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/data/base.py",
    "chars": 693,
    "preview": "from abc import abstractmethod\nfrom torch.utils.data import Dataset, ConcatDataset, ChainDataset, IterableDataset\n\n\nclas"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/data/imagenet.py",
    "chars": 15497,
    "preview": "import os, yaml, pickle, shutil, tarfile, glob\nimport cv2\nimport albumentations\nimport PIL\nimport numpy as np\nimport tor"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/data/lsun.py",
    "chars": 3274,
    "preview": "import os\nimport numpy as np\nimport PIL\nfrom PIL import Image\nfrom torch.utils.data import Dataset\nfrom torchvision impo"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/data/personalized.py",
    "chars": 7447,
    "preview": "import os\nimport numpy as np\nimport PIL\nfrom PIL import Image\nfrom torch.utils.data import Dataset\nfrom torchvision impo"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/data/personalized_style.py",
    "chars": 4797,
    "preview": "import os\nimport numpy as np\nimport PIL\nfrom PIL import Image\nfrom torch.utils.data import Dataset\nfrom torchvision impo"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/lr_scheduler.py",
    "chars": 3882,
    "preview": "import numpy as np\n\n\nclass LambdaWarmUpCosineScheduler:\n    \"\"\"\n    note: use with a base_lr of 1.0\n    \"\"\"\n    def __in"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/models/autoencoder.py",
    "chars": 17619,
    "preview": "import torch\nimport pytorch_lightning as pl\nimport torch.nn.functional as F\nfrom contextlib import contextmanager\n\nfrom "
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/models/diffusion/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/models/diffusion/classifier.py",
    "chars": 10276,
    "preview": "import os\nimport torch\nimport pytorch_lightning as pl\nfrom omegaconf import OmegaConf\nfrom torch.nn import functional as"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/models/diffusion/ddim.py",
    "chars": 12861,
    "preview": "\"\"\"SAMPLING ONLY.\"\"\"\n\nimport torch\nimport numpy as np\nfrom tqdm import tqdm\nfrom functools import partial\n\nfrom ldm.modu"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/models/diffusion/ddpm.py",
    "chars": 80894,
    "preview": "\"\"\"\nwild mixture of\nhttps://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e316"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/models/diffusion/plms.py",
    "chars": 12450,
    "preview": "\"\"\"SAMPLING ONLY.\"\"\"\n\nimport torch\nimport numpy as np\nfrom tqdm import tqdm\nfrom functools import partial\n\nfrom ldm.modu"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/attention.py",
    "chars": 8740,
    "preview": "from inspect import isfunction\nimport math\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn, einsum\nfro"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/model.py",
    "chars": 33409,
    "preview": "# pytorch_diffusion + derived encoder decoder\nimport math\nimport torch\nimport torch.nn as nn\nimport numpy as np\nfrom ein"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/openaimodel.py",
    "chars": 35331,
    "preview": "from abc import abstractmethod\nfrom functools import partial\nimport math\nfrom typing import Iterable\nimport pdb\nimport t"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/diffusionmodules/util.py",
    "chars": 9633,
    "preview": "# adopted from\n# https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/gaussian_diffusion.py\n# and\n#"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/distributions/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/distributions/distributions.py",
    "chars": 2970,
    "preview": "import torch\nimport numpy as np\n\n\nclass AbstractDistribution:\n    def sample(self):\n        raise NotImplementedError()\n"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/ema.py",
    "chars": 2982,
    "preview": "import torch\nfrom torch import nn\n\n\nclass LitEma(nn.Module):\n    def __init__(self, model, decay=0.9999, use_num_upates="
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/embedding_manager.py",
    "chars": 6853,
    "preview": "import pdb\nimport torch\nfrom torch import nn\n\nfrom ldm.data.personalized import per_img_token_list\nfrom transformers imp"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/encoders/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/encoders/modules.py",
    "chars": 15109,
    "preview": "import torch\nimport torch.nn as nn\nfrom functools import partial\nimport clip\nfrom einops import rearrange, repeat\nfrom t"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/encoders/modules_bak.py",
    "chars": 18883,
    "preview": "import torch\nimport torch.nn as nn\nfrom functools import partial\nimport clip\nfrom einops import rearrange, repeat\nfrom t"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/image_degradation/__init__.py",
    "chars": 208,
    "preview": "from ldm.modules.image_degradation.bsrgan import degradation_bsrgan_variant as degradation_fn_bsr\nfrom ldm.modules.image"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/image_degradation/bsrgan.py",
    "chars": 25198,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\n# --------------------------------------------\n# Super-Resolution\n# ------------------------"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/image_degradation/bsrgan_light.py",
    "chars": 22238,
    "preview": "# -*- coding: utf-8 -*-\nimport numpy as np\nimport cv2\nimport torch\n\nfrom functools import partial\nimport random\nfrom sci"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/image_degradation/utils_image.py",
    "chars": 29022,
    "preview": "import os\nimport math\nimport random\nimport numpy as np\nimport torch\nimport cv2\nfrom torchvision.utils import make_grid\nf"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/losses/__init__.py",
    "chars": 68,
    "preview": "from ldm.modules.losses.contperceptual import LPIPSWithDiscriminator"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/losses/contperceptual.py",
    "chars": 5581,
    "preview": "import torch\nimport torch.nn as nn\n\nfrom taming.modules.losses.vqperceptual import *  # TODO: taming dependency yes/no?\n"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/losses/vqperceptual.py",
    "chars": 7941,
    "preview": "import torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom einops import repeat\n\nfrom taming.modules.discrim"
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/modules/x_transformer.py",
    "chars": 20369,
    "preview": "\"\"\"shout-out to https://github.com/lucidrains/x-transformers/tree/main/x_transformers\"\"\"\nimport torch\nfrom torch import "
  },
  {
    "path": "more_apps/Facechain-SuDe/ldm/util.py",
    "chars": 5877,
    "preview": "import importlib\n\nimport torch\nimport numpy as np\nfrom collections import abc\nfrom einops import rearrange\nfrom functool"
  },
  {
    "path": "more_apps/Facechain-SuDe/main.py",
    "chars": 32295,
    "preview": "import argparse, os, sys, datetime, glob, importlib, csv\nimport numpy as np\nimport time\nimport torch\n\nimport torchvision"
  },
  {
    "path": "more_apps/Facechain-SuDe/main.sh",
    "chars": 1097,
    "preview": "#!/bin/bash\n# # ------------------------example--------------------------\n\n# reg data:\nCUDA_VISIBLE_DEVICES=0 python scr"
  },
  {
    "path": "more_apps/Facechain-SuDe/merge_embeddings.py",
    "chars": 3706,
    "preview": "from ldm.modules.encoders.modules import FrozenCLIPEmbedder, BERTEmbedder\nfrom ldm.modules.embedding_manager import Embe"
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/download_first_stages.sh",
    "chars": 1324,
    "preview": "#!/bin/bash\nwget -O models/first_stage_models/kl-f4/model.zip https://ommer-lab.com/files/latent-diffusion/kl-f4.zip\nwge"
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/download_models.sh",
    "chars": 1681,
    "preview": "#!/bin/bash\nwget -O models/ldm/celeba256/celeba-256.zip https://ommer-lab.com/files/latent-diffusion/celeba.zip\nwget -O "
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/evaluate_model.py",
    "chars": 6923,
    "preview": "import argparse, os, sys, glob\nfrom pytorch_lightning import seed_everything\nsys.path.append(os.path.join(sys.path[0], '"
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/inpaint.py",
    "chars": 3644,
    "preview": "import argparse, os, sys, glob\nfrom omegaconf import OmegaConf\nfrom PIL import Image\nfrom tqdm import tqdm\nimport numpy "
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/latent_imagenet_diffusion.ipynb",
    "chars": 4172302,
    "preview": "{\n \"nbformat\": 4,\n \"nbformat_minor\": 0,\n \"metadata\": {\n  \"colab\": {\n   \"name\": \"latent-imagenet-diffusion.ipynb\",\n   \"pr"
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/sample_diffusion.py",
    "chars": 9606,
    "preview": "import argparse, os, sys, glob, datetime, yaml\nimport torch\nimport time\nimport numpy as np\nfrom tqdm import trange\n\nfrom"
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/stable_txt2img.py",
    "chars": 10336,
    "preview": "import argparse, os, sys, glob\nsys.path.append(os.path.join(sys.path[0], '..'))\nimport torch\nimport numpy as np\nfrom ome"
  },
  {
    "path": "more_apps/Facechain-SuDe/scripts/txt2img.py",
    "chars": 5660,
    "preview": "import argparse, os, sys, glob\nimport torch\nimport numpy as np\nfrom omegaconf import OmegaConf\nfrom PIL import Image\nfro"
  },
  {
    "path": "more_apps/Facechain-SuDe/setup.py",
    "chars": 233,
    "preview": "from setuptools import setup, find_packages\n\nsetup(\n    name='latent-diffusion',\n    version='0.0.1',\n    description=''"
  },
  {
    "path": "run_inference.py",
    "chars": 2427,
    "preview": "# Copyright (c) Alibaba, Inc. and its affiliates.\nimport os\nimport json\nfrom facechain.inference_fact import GenPortrait"
  },
  {
    "path": "run_inference_inpaint.py",
    "chars": 935,
    "preview": "import cv2\nimport os\nimport json\nfrom facechain.inference_inpaint_fact import GenPortrait_inpaint\n\nnum_faces = 1\nselecte"
  },
  {
    "path": "scripts/facechain_sdwebui.py",
    "chars": 1683,
    "preview": "import modules.scripts as scripts\nimport gradio as gr\nimport os\nfrom modules import script_callbacks\nfrom modules import"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Autumn_populus.json",
    "chars": 379,
    "preview": "{\n    \"name\": \"秋日胡杨风(Autumn populus euphratica style)\",\n    \"img\": \"./style_image/Autumn_populus.jpg\",\n    \"model_id\": \""
  },
  {
    "path": "styles/MajicmixRealistic_v6/Bleak_autumn.json",
    "chars": 370,
    "preview": "{\n    \"name\": \"萧瑟秋天风(Bleak autumn style)\",\n    \"img\": \"./style_image/Bleak_autumn.jpg\",\n    \"model_id\": \"PeiPeiY/style_l"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Cartoon.json",
    "chars": 362,
    "preview": "{\n    \"name\": \"漫画风(Cartoon)\",\n    \"img\": \"./style_image/Cartoon.jpg\",\n    \"model_id\": \"rewfueranro/cartoon_lora\",\n    \"r"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Cheongsam.json",
    "chars": 501,
    "preview": "{\n    \"name\": \"旗袍风(Cheongsam)\",\n    \"img\": \"./style_image/Cheongsam.jpg\",\n    \"model_id\": \"PaperCloud/zju19_minguo_style"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Chinese_New_Year.json",
    "chars": 448,
    "preview": "{\n    \"name\": \"中国新年风(Chinese New Year Style)\",\n    \"img\": \"./style_image/Chinese_New_Year.jpg\",\n    \"model_id\": \"houpeir"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Chinese_winter_hanfu.json",
    "chars": 472,
    "preview": "{\n    \"name\": \"冬季汉服(Chinese winter hanfu)\",\n    \"img\": \"./style_image/Chinese_winter_hanfu.jpg\",\n    \"model_id\": \"Yorick"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Christmas.json",
    "chars": 375,
    "preview": "{\n    \"name\": \"圣诞风(Christmas)\",\n    \"img\": \"./style_image/Christmas.jpg\",\n    \"model_id\": \"mowunian/christmas\",\n    \"rev"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Colorful_rainbow.json",
    "chars": 507,
    "preview": "{\n    \"name\": \"炫彩少女风(Colorful rainbow style)\",\n    \"img\": \"./style_image/Colorful_rainbow.jpg\",\n    \"model_id\": \"houpeir"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Cool_tones.json",
    "chars": 455,
    "preview": "{\n    \"name\": \"自然清冷风(Cool tones)\",\n    \"img\": \"./style_image/Cool_tones.jpg\",\n    \"model_id\": \"houpeiran/mymodel\",\n    \""
  },
  {
    "path": "styles/MajicmixRealistic_v6/Cowboy.json",
    "chars": 422,
    "preview": "{\n    \"name\": \"西部牛仔风(Cowboy style)\",\n    \"img\": \"./style_image/Cowboy.jpg\",\n    \"model_id\": \"houpeiran/mymodel\",\n    \"re"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Deer_girl.json",
    "chars": 480,
    "preview": "{\n    \"name\": \"林中鹿女风(Deer girl)\",\n    \"img\": \"./style_image/Deer_girl.jpg\",\n    \"model_id\": \"EnlZhao/deer_lora\",\n    \"re"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Disneyland.json",
    "chars": 449,
    "preview": "{\n    \"name\": \"主题乐园风(Disneyland)\",\n    \"img\": \"./style_image/Disneyland.jpg\",\n    \"model_id\": \"rtxxxx/zju_05\",\n    \"revi"
  },
  {
    "path": "styles/MajicmixRealistic_v6/DreamyOcean.json",
    "chars": 307,
    "preview": "{\n    \"name\": \"海洋风(Ocean)\",\n    \"img\": \"./style_image/DreamyOcean.jpg\",\n    \"model_id\": \"MushroomLyn/artist\",\n    \"revis"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Dunhuang.json",
    "chars": 538,
    "preview": "{\n    \"name\": \"敦煌风(Dunhuang)\",\n    \"img\": \"./style_image/Dunhuang.jpg\",\n    \"model_id\": \"PaperCloud/zju19_dunhuang_style"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Duobaan.json",
    "chars": 339,
    "preview": "{\n    \"name\": \"多巴胺风格(Colourful Style)\",\n    \"img\": \"./style_image/Duobaan.jpg\",\n    \"model_id\": \"Tekhne/dubaan\",\n    \"re"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Embroidery.json",
    "chars": 450,
    "preview": "{\n    \"name\": \"中华刺绣风(Embroidery)\",\n    \"img\": \"./style_image/Embroidery.jpg\",\n    \"model_id\": \"rtxxxx/zju_05\",\n    \"revi"
  },
  {
    "path": "styles/MajicmixRealistic_v6/European_fields.json",
    "chars": 460,
    "preview": "{\n    \"name\": \"欧式田野风(European fields)\",\n    \"img\": \"./style_image/European_fields.jpg\",\n    \"model_id\": \"iotang/lora_tes"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Fairy_style.json",
    "chars": 524,
    "preview": "{\n    \"name\": \"仙女风(Fairy style)\",\n    \"img\": \"./style_image/Fairy_style.jpg\",\n    \"model_id\": \"YorickHe/fairy_lora\",\n   "
  },
  {
    "path": "styles/MajicmixRealistic_v6/Fashion_glasses.json",
    "chars": 559,
    "preview": "{\n    \"name\": \"时尚墨镜风(Fashion glasses)\",\n    \"img\": \"./style_image/Fashion_glasses.jpg\",\n    \"model_id\": \"SoulNut/facecha"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Flame_red_style.json",
    "chars": 465,
    "preview": "{\n    \"name\": \"火红少女风(Flame Red Style)\",\n    \"img\": \"./style_image/Flame_red_style.jpg\",\n    \"model_id\": \"Hswich/wlop_off"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Flowers.json",
    "chars": 339,
    "preview": "{\n    \"name\": \"花园风(Flowers)\",\n    \"img\": \"./style_image/Flowers.jpg\",\n    \"model_id\": \"lljjcc/outdoor\",\n    \"revision\": "
  },
  {
    "path": "styles/MajicmixRealistic_v6/Gentleman.json",
    "chars": 333,
    "preview": "{\n    \"name\": \"绅士风(Gentleman style)\",\n    \"img\": \"./style_image/Gentleman.jpg\",\n    \"model_id\": \"Licht000/gentleman\",\n  "
  },
  {
    "path": "styles/MajicmixRealistic_v6/GuoFeng.json",
    "chars": 437,
    "preview": "{\n    \"name\": \"国风(GuoFeng Style)\",\n    \"img\": \"./style_image/GuoFeng.jpg\",\n    \"model_id\": \"Tekhne/GuoFengchill\",\n    \"r"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Hiphop.json",
    "chars": 431,
    "preview": "{\n    \"name\": \"嘻哈风(Hiphop style)\",\n    \"img\": \"./style_image/Hiphop.jpg\",\n    \"model_id\": \"Licht000/hiphop\",\n    \"revisi"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Hong_Kong_night_style.json",
    "chars": 586,
    "preview": "{\n    \"name\": \"夜景港风(Hong Kong night)\",\n    \"img\": \"./style_image/Hong_Kong_night_style.jpg\",\n    \"model_id\": \"YorickHe/p"
  },
  {
    "path": "styles/MajicmixRealistic_v6/India.json",
    "chars": 410,
    "preview": "{\n    \"name\": \"印度风(India)\",\n    \"img\": \"./style_image/India.jpg\",\n    \"model_id\": \"lljjcc/IndianSarres\",\n    \"revision\":"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Jacket_in_Snow_Mountain.json",
    "chars": 447,
    "preview": "{\n    \"name\": \"雪山羽绒服风(Jacket in Snow Mountain)\",\n    \"img\": \"./style_image/Jacket_in_Snow_Mountain.jpg\",\n    \"model_id\":"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Kimono.json",
    "chars": 425,
    "preview": "{\n    \"name\": \"日系和服风(Kimono Style)\",\n    \"img\": \"./style_image/Kimono.jpg\",\n    \"model_id\": \"ZackWang123/filmvelvia_lora"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Li.json",
    "chars": 625,
    "preview": "{\n    \"name\": \"哥特洛丽塔(Gothic Lolita)\",\n    \"img\": \"./style_image/Li.jpg\",\n    \"model_id\": \"Cleaner/lo_dress_gothic_style2"
  },
  {
    "path": "styles/MajicmixRealistic_v6/Lolita.json",
    "chars": 443,
    "preview": "{\n    \"name\": \"洛丽塔(Lolita)\",\n    \"img\": \"./style_image/Lolita.jpg\",\n    \"model_id\": \"Licht000/lolita\",\n    \"revision\": \""
  },
  {
    "path": "styles/MajicmixRealistic_v6/Luolita.json",
    "chars": 438,
    "preview": "{\n    \"name\": \"花环洛丽塔(Flora Lolita)\",\n    \"img\": \"./style_image/Luolita.jpg\",\n    \"model_id\": \"idlepiggy/zju_16FC\",\n    \""
  }
]

// ... and 49 more files (download for full content)

About this extraction

This page contains the full source code of the modelscope/facechain GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 249 files (5.2 MB), approximately 1.4M tokens, and a symbol index with 1328 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!