FaceChain FACT 换脸 Docker镜像实战
2025-11-19
深度学习
00

目录

原理
1. 核心生成阶段:FaceAdapter (FaceChain-FACT)
2. 增强阶段:Face Fusion (人脸融合)
FacePrjResampler
1. FacePrjResampler 是一个模型吗?
2. 人脸特征会变成 token 给 SD 1.5 模型吗?
步骤 1: 特征提取与转换
步骤 2: 拼接为 Prompt Embeddings
步骤 3: 在 Cross-Attention 中使用
都下载了什么模型
1. 核心基础模型(最大,约 8-10 GB)
2. FaceAdapter 模型(约 2-3 GB)
3. ControlNet 控制模型(约 3-5 GB)
4. 人脸处理模型(约 1.5-2 GB)
5. 风格 LoRA 模型(约 5-10 GB)

https://www.dong-blog.fun/post/360#Docker

之前没打镜像,后悔!搞了半天,记录下来。

这里有Dockerfile:

bash
展开代码
FROM registry.us-west-1.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1 RUN apt-get update && apt-get install -y libjemalloc-dev && rm -rf /var/lib/apt/lists/* RUN useradd -m -u 1000 user USER user ENV HOME=/home/user \ PATH=/home/user/.local/bin:$PATH WORKDIR $HOME RUN chmod 777 $HOME RUN mkdir $HOME/modelscope_cache ENV MODELSCOPE_CACHE=$HOME/modelscope_cache ENV GRADIO_SERVER_NAME=0.0.0.0 EXPOSE 7860 RUN echo 'cloning facechain:hf_space_fact' RUN git clone -b feat/hf_space_fact https://github.com/modelscope/facechain.git WORKDIR $HOME/facechain RUN pip install -r requirements.txt ENV LD_PRELOAD=/lib/x86_64-linux-gnu/libjemalloc.so ENV PYTHONPATH=. CMD ["python", "app.py"]

不以root运行。进去后还需要适配一些代码。

启动

bash
展开代码
docker run -it --net host --gpus all kevinchina/deeplearning:fact_face_swapev1 /bin/bash cd facechain $ GRADIO_SERVER_PORT=9872 python3 app.py

原理

1. 核心生成阶段:FaceAdapter (FaceChain-FACT)

这是 FaceChain 生成写真的核心,它不仅仅是简单的“换脸”,而是基于用户的人脸特征“生成”一张新的人像。

  • 特征提取 (Feature Extraction):

    • 代码位置: face_adapter/face_adapter_v1.py 中的 Face_Extracter_v1 类。
    • 预处理: 首先使用 face_detection (RetinaFace) 检测人脸,并进行对齐 (align) 和分割 (segmentation_pipeline),只保留人脸区域。
    • 提取器: 使用一个 Vision Transformer (Face_Transformer) 模型来提取人脸的特征嵌入 (Embeddings)。
    • 特征重采样: 提取的特征通过一个 Perceiver Attention 模块 (Face_Prj_Resampler) 进行处理。这个模块的作用是将人脸特征转换成 Stable Diffusion (SD) 模型可以理解的格式和维度 (768维)。
  • 特征注入与生成 (Injection & Generation):

    • 代码位置: face_adapter/face_adapter_v1.py 中的 FaceAdapter_v1 类。
    • Adapter 机制: FaceChain 不直接微调 SD 的庞大权重,而是通过“适配器 (Adapter)”模式。它替换了 SD UNet 中的 Cross-Attention 处理器 (FaceAttnProcessor)。
    • Cross-Attention: 在生成过程中,这些自定义的 Attention 处理器会将上一步提取的人脸特征作为“Key”和“Value”注入到网络中。
    • 结果: 这样,Stable Diffusion 在根据 Prompt(提示词)生成图像时,会强制“关注”用户的人脸特征,从而生成出长相与用户一致,但风格、动作由模型和 Prompt 控制的新图像。

2. 增强阶段:Face Fusion (人脸融合)

这是一个显式的“换脸”步骤,在 UI 中对应“是否使用人脸相似度增强”选项。

  • 原理:
    • 代码位置: facechain/inference_fact.py 中的 face_swap_fn 函数。
    • 输入: 拿第 1 步生成的图片(作为模板)和用户原始上传的照片(作为源)。
    • 模型: 使用 ModelScope 的 damo/cv_unet_face_fusion_torch 模型。这是一个专门的基于 UNet 的人脸融合模型。
    • 过程: 该模型会精准地识别生成图片中的人脸区域,并将用户原图的五官特征“搬移”并融合到生成图片上。
    • 目的: 弥补生成模型可能带来的细节丢失(如眼神、微表情),进一步提高人脸的相似度 (Identity Preservation)。

Face_Prj_Resampler

查看 Face_Prj_Resampler 的实现,以及它如何将人脸特征转换为 SD 1.5 可用的格式:

1. Face_Prj_Resampler 是一个模型吗?

是的,Face_Prj_Resampler 是一个神经网络模型(继承自 nn.Module)。

180:224:face_adapter/face_adapter_v1.py
展开代码
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)

它使用 Perceiver Attention 机制,将人脸特征压缩并转换为固定数量的 token。

2. 人脸特征会变成 token 给 SD 1.5 模型吗?

是的。流程如下:

步骤 1: 特征提取与转换

  • Face_Transformer 提取人脸特征(512 维)
  • Face_Prj_Resampler 将其转换为 16 个 token,每个 token 768 维(与 SD 1.5 的 embedding 维度一致)
241:251:face_adapter/face_adapter_v1.py
展开代码
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

步骤 2: 拼接为 Prompt Embeddings

人脸 token 会被拼接到文本 prompt 的 embeddings 后面:

417:425:face_adapter/face_adapter_v1.py
展开代码
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)

步骤 3: 在 Cross-Attention 中使用

FaceAttnProcessor 中,这些 token 会被分离出来,并通过 self-attention 和 cross-attention 影响生成过程:

324:333:face_adapter/face_attention_processor_v1.py
展开代码
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,:]

都下载了什么模型

查找代码中所有模型下载位置,整理下载的模型列表:

运行 FaceChain 后,会下载约 40+ GB 的模型,主要包括:

1. 核心基础模型(最大,约 8-10 GB)

  • MAILAND/majicmixRealistic_v6 - 写真风格 SD 1.5 模型
  • ly261666/cv_portrait_model - 写实风格 SD 1.5 模型

2. FaceAdapter 模型(约 2-3 GB)

  • yucheng1996/FaceChain-FACT - 包含人脸识别和适配器权重

3. ControlNet 控制模型(约 3-5 GB)

  • damo/face_chain_control_model - OpenPose 姿态控制
  • ly261666/cv_wanx_style_model - Canny 边缘控制

4. 人脸处理模型(约 1.5-2 GB)

  • 人脸检测(2个)
  • 人体/人脸分割
  • 人脸融合(Face Swap)
  • 人脸质量评估
  • 人脸属性识别(年龄、性别)
  • 皮肤修复

5. 风格 LoRA 模型(约 5-10 GB)

  • 50+ 个预设风格 LoRA,包括:
    • 各种服装风格(汉服、和服、婚纱等)
    • 艺术风格(油画、卡通、科幻等)
    • 场景风格(秋日、雨天、水下等)
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!