家用扩散模型 (2.1):Variational Score Distillation
动机
假设我们训(下)好(载)了一个pretrained diffuser \(\boldsymbol{\epsilon}_\psi(\boldsymbol{x}_t, t, c)\)(也可以认为是score function,之前已经介绍过了这两者是一样的),能帮我们轻松的计算\(p(\boldsymbol{x}_0|c)\)。
其实一点也不轻松,即使是之前介绍的DPM Solver 2m++,也要10~20 steps(
现在我们想要解决如下问题:对生成函数\(x=g(z;\theta, c)\),条件c和隐分布z,优化g的参数\(\theta \in \Theta\)使得x在pretrained diffuser的分布内(常见的应用比如,我们想要学一个nerf让它渲染的图片x看起来真实——我们今天要介绍的论文相当程度上围绕这个主题展开)。
这时候,一个自然而然的想法是——既然我们已经有了pretrained diffuser,那如果我们直接做denoising score matching呢?也就是说,先把生成的图片加噪声
然后最小化DSM Loss。这意味着极值处的\(\nabla_\theta\)是0:
根据链式法则,
- 后半段是我们自己设计控制的小模型,我们可以用backprop轻松算出梯度。
- 但前半段是在一个极其巨大的pretrained diffuser上求Jacobian,且不论这玩意计算起来有多昂贵,光是数值稳定性就是一大难题
所以直接最小化DSM Loss非常困难。那怎么办呢?我们需要Score Distillation。
Variational Score Distillation [2,3]
我们用一个新Diffuser,\(\boldsymbol{\epsilon}_\phi(\boldsymbol{x}_t, t, c)\),来预测g生成样本的概率q的分数\(-\sigma_t\nabla_{\boldsymbol{x}}\log q_t(\boldsymbol{x}_t, t, c)\)。
我们的优化目标是(推导过程见下文)
这里\(\boldsymbol{\epsilon}_{\psi}\)来自预训练的大模型。
这个函数就是可以计算的了。实现上我们交替优化\(\phi\)和\(\theta\):
- 优化\(\phi\)的时候使用DSM Loss(也就是\(\phi\)对\(\boldsymbol{\epsilon}\)——但计算这个DSM Loss的时候因为x是从g采样来的,实际上还是用了generator),从而让\(\boldsymbol{\epsilon}_\phi(\boldsymbol{x}_t, t, c)\)逼近我们想要的真值\(-\sigma_t\nabla_{\boldsymbol{x}}\log q_t(\boldsymbol{x}_t, t, c)\)。
- 优化\(\theta\)的时候算VSD Loss,让生成分布和真实分布靠拢。
当我们sample的时候,只要先采样一个z,然后用g生成一个x,这意味着我们一步就能完成inference,再也不需要走昂贵的diffusion sampling了(
至于为什么叫Variational Score Distillation,那是因为还有一个不variational的Score Distillation Sampling[1],请见下文。
题外话:Variational Score Distillation(VSD)是[2]中的名字。[3]中有一个非常接近的term,叫Integral Kullback-Leibler divergence(IKL),仔细对比一下就会发现[2]和[3]只差了个只和t有关的系数,可以简单的塞进weight里。这是CMU的Zhengyang Geng大佬发现的。[2]和[3]的发布日期其实也相当接近,可以说是比较机缘巧合。
推导思路
详见[3]的A.2和[2]的C.4。
我们记隐分布为\(z\sim q(z)\),生成的分布为\(x=g(z; \theta)\sim q_\theta(x)\),而真实数据的分布是\(x\sim p(x)\)(这里省略了c和t,但是不本质)
我们显然想要生成分布和真实分布尽量接近,一个自然的想法就是令两者的KL为0:
而
所以
到这里已经长出了VSD的主要形状(注意\(\nabla_x \log p(x)\)和\(\boldsymbol{\epsilon}\)差了个负号),剩下来的权重部分就只和t有关了。
Score Distillation Sampling [1]
SDS的优化目标是
这里\(\boldsymbol{\epsilon}_{\psi}\)来自预训练的大模型。
考虑VSD这个问题。给定条件c和先验z,事实上我们可以有很多个\(\theta\),使得\(g(z;\theta, c)\)符合要求。因此我们需要的其实是一个variational的\(\theta\)分布——但SDS其实是\(\theta \sim \delta(\theta-\theta^*)\),此时有\(q_\theta \sim \mathcal{N}(\boldsymbol{x}_t|\alpha_t g(z; \theta^*, c), \sigma_t^2 \boldsymbol{I})\),于是\(-\sigma_t \nabla_x\log q_\theta(x) = \boldsymbol{\epsilon}\)。
因此,SDS可以视为VSD在不Variational时的特殊情况,它的效果更差也自然是可以理解的了。
SDS本身的动机其实是从\(\nabla_\theta\mathcal{L}_{\text{DSM}}\)中扔掉难以计算的巨大Jacobian项,事后才想着从KL方面圆回来(见[1]的appendix),而且推导过程十分相像,实际上和[2][3]只差一层窗户纸,只能说[1]没有直接进到VSD真是机缘巧合(
但话又说回来,实际上大家都负担不起train一个新diffuser,所以还是SDS用的多...
VSD和GAN的关系
见[3]的A.4
VSD的这个交替优化是不是让你想到了什么呢?没错,这玩意看着像GAN!甚至GAN的著名trick之一就是往data里掺gaussian noise。
最传统的GAN的discriminator output \(h(\cdot)\)是一个sigmoid,然后出来的结果做Binary Cross Entropy。使用同样的参数符号,可以想象\(\theta\)是generator的参数,而\(\phi\)是discriminator的参数(方便类比),我们有:
它在h把所有假样本判成0而真样本判成1的时候取得极小值0。
它在h把所有假样本判成1的时候取得极小值0。
和VSD类比一下:
- D loss的目标是让\(h_\phi(x)\)逼近\(\frac{p(x)}{q_\theta(x)+p(x)}\)。
这是因为如果简单列个算式,D loss的极值处有
- G loss的目标本身很难处理(因为这个log概率和很难处理),但我们既然已经知道了\(h_\phi(x)\)的真实目标,可以偷偷的换一个目标一致的loss:
于是G loss的极值处有(把\(h_\phi(x)\)换成其理想值\(\frac{p(x)}{q_\theta(x)+p(x)}\))
这样就长得和VSD(的不加noise, t==0的版本)异曲同工(甚至可以说是一模一样)了。
所以其实有点好奇,如果用\(\mathcal{L}_G^{KL}\)代替\(\mathcal{L}_G\),train GAN会变得更稳定吗?
可惜生产中大家人均WGAN-GP,早就没有人用传统GAN了...
参考资料
[1] DreamFusion: Text-to-3D using 2D Diffusion
[2] ProlificDreamer: High-Fidelity and Diverse Text-to-3D Generation with Variational Score Distillation
[3] Diff-Instruct: A Universal Approach for Transferring Knowledge From Pre-trained Diffusion Models