{"id":14543,"date":"2026-07-29T15:09:12","date_gmt":"2026-07-29T14:09:12","guid":{"rendered":"https:\/\/www.blopig.com\/blog\/?p=14543"},"modified":"2026-07-29T16:11:28","modified_gmt":"2026-07-29T15:11:28","slug":"diffusion-models-cant-give-you-a-likelihood-so-how-do-we-score-inverse-folded-sequences","status":"publish","type":"post","link":"https:\/\/www.blopig.com\/blog\/2026\/07\/diffusion-models-cant-give-you-a-likelihood-so-how-do-we-score-inverse-folded-sequences\/","title":{"rendered":"Diffusion Models Can&#8217;t Give You a Likelihood&#8230; So How Do We Score Inverse-Folded Sequences?"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I&#8217;ve been working with inverse folding models for sequence design for a while now, and one question kept coming up. How would you score a sequence&#8217;s likelihood under these models? It turns out the answer depends heavily on whether the model is autoregressive or diffusion-based. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Autoregressive models, like GPT-style language models, make this straightforward. You can calculate the probability of a sequence directly, by breaking it into one prediction per position and multiplying them together. Diffusion models define a probability distribution over outputs too, but getting the likelihood of a particular output means accounting for many unobserved intermediate states, and that turns out to be much harder. This is why diffusion models typically rely on the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Evidence_lower_bound\" data-type=\"link\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Evidence_lower_bound\">Evidence Lower Bound, or ELBO,<\/a> a computable estimate, rather than the exact likelihood itself.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2026\/07\/image-2.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"593\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2026\/07\/image-2-edited.png?resize=625%2C593&#038;ssl=1\" alt=\"\" class=\"wp-image-14569\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2026\/07\/image-2-edited.png?w=811&amp;ssl=1 811w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2026\/07\/image-2-edited.png?resize=300%2C285&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2026\/07\/image-2-edited.png?resize=768%2C729&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2026\/07\/image-2-edited.png?resize=624%2C592&amp;ssl=1 624w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The easy case: autoregressive models<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An autoregressive model breaks the probability of a sequence into a product of conditional probabilities:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>n<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><munderover><mo>\u220f<\/mo><mrow><mi>i<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><mi>n<\/mi><\/munderover><\/mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mrow><mo lspace=\"0em\" rspace=\"0em\">&lt;<\/mo><mi>i<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">p(x_{1:n}) = \\prod_{i=1}^{n} p(x_i \\mid x_{&lt;i})<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Each term asks: given everything that came before position <em>i<\/em>, what probability does the model assign to the observed value <em>x<sub>i<\/sub><\/em>?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Taking logarithms turns the product into a sum:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>n<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><munderover><mo>\u2211<\/mo><mrow><mi>i<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><mi>n<\/mi><\/munderover><\/mrow><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mrow><mo lspace=\"0em\" rspace=\"0em\">&lt;<\/mo><mi>i<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\log p(x_{1:n})\n=\n\\sum_{i=1}^{n}\n\\log p(x_i \\mid x_{&lt;i}).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">To score a sequence, we read off the probability assigned to the observed token at each position and add the log-probabilities. Once the decoding order is fixed, the likelihood is directly available.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One caviat is Inverse folding models like ProteinMPNN could use different residue-decoding orders. A sequence score calculated using one order is exact for that particular order. Averaging over every possible decoding order would require an additional sum over those orders.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The harder case: diffusion models<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A standard diffusion model introduces a sequence of noisy states:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_0,x_1,\\ldots,x_T.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Here, <em>x<sub>0<\/sub><\/em> is the clean data point, <em>x<sub>1<\/sub><\/em> is a slightly noisy version of <em>x<sub>0<\/sub><\/em>, <em>x<sub>T<\/sub><\/em> is approximately pure noise, and <em>T<\/em> is the total number of diffusion steps. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Generation runs backwards, beginning with noise at xT and gradually producing cleaner states.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At each step, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo>\u223c<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_{t-1}\n\\sim\np_\\theta(x_{t-1} \\mid x_t).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The symbol ~ means &#8220;is sampled from&#8221;, while the vertical bar means &#8220;given&#8221;. Therefore, this expression means: Given the current noisy state <em>x<sub>t<\/sub><\/em>, the model produces a probability distribution for the next, slightly cleaner state <em>x<sub>t-1<\/sub><\/em>, and samples from it. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The symbol \u03b8 represents the learned parameters of the neural network. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A Three-step example <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the model uses only three diffusion steps: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_0,x_1,x_2,x_3.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Genration might follow the path <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mn>1.2<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.8<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.4<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.1.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">1.2\n\\longrightarrow\n0.8\n\\longrightarrow\n0.4\n\\longrightarrow\n0.1.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo>=<\/mo><mn>1.2<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">x_3=1.2\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">is the starting noise, while<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo>=<\/mo><mn>0.1<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">x_0=0.1\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">is the final clean output. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The model generates the path using<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo>\u223c<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">x_2\\sim p_\\theta(x_2\\mid x_3),\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">followed by <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo>\u223c<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">x_1\\sim p_\\theta(x_1\\mid x_2),\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">and finally<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo>\u223c<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_0\\sim p_\\theta(x_0\\mid x_1).\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The notation <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">x_{0:T}\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">is shorthand for the complete collection of states<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_0,x_1,\\ldots,x_T.\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For <em>T<\/em> = 3, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mn>3<\/mn><\/mrow><\/msub><mo>=<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_{0:3}\n=\n(x_0,x_1,x_2,x_3).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The probability density of one comeplete path is <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mn>3<\/mn><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mspace width=\"0.1667em\"><\/mspace><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mspace width=\"0.1667em\"><\/mspace><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mspace width=\"0.1667em\"><\/mspace><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_{0:3})\n=\np(x_3)\\,\np_\\theta(x_2\\mid x_3)\\,\np_\\theta(x_1\\mid x_2)\\,\np_\\theta(x_0\\mid x_1).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the density values for this path are <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.2<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">p(x_3)=0.2,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.5<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_2\\mid x_3)=0.5,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.4<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_1\\mid x_2)=0.4,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">and <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.6.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0\\mid x_1)=0.6.\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The density of this particular path is then<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mn>0.2<\/mn><mo>\u00d7<\/mo><mn>0.5<\/mn><mo>\u00d7<\/mo><mn>0.4<\/mn><mo>\u00d7<\/mo><mn>0.6<\/mn><mo>=<\/mo><mn>0.024.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">0.2\\times 0.5\\times 0.4\\times 0.6\n=\n0.024.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For <em>T<\/em> steps, this is written as <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mrow><munderover><mo movablelimits=\"false\">\u220f<\/mo><mrow><mi>t<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><mi>T<\/mi><\/munderover><\/mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_{0:T})\n=\np(x_T)\n\\prod_{t=1}^{T}\np_\\theta(x_{t-1}\\mid x_t).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The product symbol means that we multiply together the density of every denoising transition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why the Likelihood Is Difficult<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The calculation above gives the density of one particular path.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, the same final output <em>x<sub>0<\/sub><\/em> could be reached through many different intermediate states. For example, several paths might end at <em>x<sub>0<\/sub><\/em> = 0.1: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mn>1.2<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.8<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.4<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.1<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">1.2\\longrightarrow0.8\\longrightarrow0.4\\longrightarrow0.1,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mo>\u2212<\/mo><mn>0.5<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.6<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.3<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.1<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">-0.5\\longrightarrow0.6\\longrightarrow0.3\\longrightarrow0.1,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">or <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mn>0.9<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.2<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.15<\/mn><mo stretchy=\"false\">\u27f6<\/mo><mn>0.1.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">0.9\\longrightarrow0.2\\longrightarrow0.15\\longrightarrow0.1.\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">When we are given only <em>x<\/em><sub>0<\/sub>, we do not know which intermediate path was taken. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The states<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_1,\\ldots,x_T\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">are called latent variables. They are part of the model, but they are not observed. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To calculate the density of <em>x<sub>0<\/sub><\/em>, we must combine the contributions of all possible latent paths: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mo movablelimits=\"false\">\u222b<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mspace width=\"0.1667em\"><\/mspace><mi>d<\/mi><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo>\u22ef<\/mo><mi>d<\/mi><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0)\n=\n\\int\np_\\theta(x_{0:T})\n\\,dx_1\\cdots dx_T.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For a discrete model, this would be a sum rather than an integral. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The difficulty is not evaluating one denoising step such as <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_{t-1}\\mid x_t).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"> The model can evaluate that quantity when <em>x<sub>t<\/sub><\/em> and <em>x<\/em><sub><em>t-1<\/em> <\/sub>are known. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The difficulty is combining the contributions of every possible value of <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_1,\\ldots,x_T.\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For a standard diffusion model, this marginalisation is generally intractable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The Forward Noising Process <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To make the problem manageable, diffusion models define a fixed forward process. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The forward process begins with a knonw clean data point and gradually adds noise: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo stretchy=\"false\">\u27f6<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo stretchy=\"false\">\u27f6<\/mo><mo>\u22ef<\/mo><mo stretchy=\"false\">\u27f6<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_0\n\\longrightarrow\nx_1\n\\longrightarrow\n\\cdots\n\\longrightarrow\nx_T.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Its distribution is written as<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><munderover><mo movablelimits=\"false\">\u220f<\/mo><mrow><mi>t<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><mi>T<\/mi><\/munderover><\/mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">q(x_{1:T}\\mid x_0)\n=\n\\prod_{t=1}^{T}\nq(x_t\\mid x_{t-1}).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The two distributions have different roles: <em>q<\/em> is the fixed forward process that adds noise; <em>p<sub>\u03b8<\/sub><\/em> is the learned reverse process that removes noise. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In a standard Gaussian diffusion model, a noisy state can be sampled directly from <em>x<sub>0<\/sub><\/em>: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo>=<\/mo><msqrt><msub><mover><mi>\u03b1<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">\u203e<\/mo><\/mover><mi>t<\/mi><\/msub><\/msqrt><mspace width=\"0.1667em\"><\/mspace><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo>+<\/mo><msqrt><mrow><mn>1<\/mn><mo>\u2212<\/mo><msub><mover><mi>\u03b1<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">\u203e<\/mo><\/mover><mi>t<\/mi><\/msub><\/mrow><\/msqrt><mspace width=\"0.1667em\"><\/mspace><mi>\u03f5<\/mi><mo separator=\"true\">,<\/mo><mspace width=\"2em\"><\/mspace><mi>\u03f5<\/mi><mo>\u223c<\/mo><mi class=\"mathcal\">\ud835\udca9<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>0<\/mn><mo separator=\"true\">,<\/mo><mi>I<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_t\n=\n\\sqrt{\\bar{\\alpha}_t}\\,x_0\n+\n\\sqrt{1-\\bar{\\alpha}_t}\\,\\epsilon,\n\\qquad\n\\epsilon\\sim\\mathcal{N}(0,I).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Here, <em>x<sub>0<\/sub><\/em> is the clean data point; \u03f5 is random Gaussian noise; \u03b1<sub>t <\/sub>control how much of the original data remains; and 1- \u03b1<sub>t<\/sub> controls how much noise is added. So the equation says take some part of the clean data, add some amount of random Gaussian noise, and you get the noisy sample at timestep<em> t<\/em>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a simple example, suppose <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo>=<\/mo><mn>10<\/mn><mo separator=\"true\">,<\/mo><mspace width=\"2em\"><\/mspace><msub><mover><mi>\u03b1<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">\u203e<\/mo><\/mover><mi>t<\/mi><\/msub><mo>=<\/mo><mn>0.64<\/mn><mo separator=\"true\">,<\/mo><mspace width=\"2em\"><\/mspace><mi>\u03f5<\/mi><mo>=<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>0.5.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">x_0=10,\n\\qquad\n\\bar{\\alpha}_t=0.64,\n\\qquad\n\\epsilon=-0.5.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Then <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo>=<\/mo><msqrt><mn>0.64<\/mn><\/msqrt><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>10<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>+<\/mo><msqrt><mrow><mn>1<\/mn><mo>\u2212<\/mo><mn>0.64<\/mn><\/mrow><\/msqrt><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>0.5<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_t\n=\n\\sqrt{0.64}(10)\n+\n\\sqrt{1-0.64}(-0.5).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Since <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msqrt><mn>0.64<\/mn><\/msqrt><mo>=<\/mo><mn>0.8<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\sqrt{0.64}=0.8\n\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">and <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msqrt><mn>0.36<\/mn><\/msqrt><mo>=<\/mo><mn>0.6<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">\\sqrt{0.36}=0.6,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">we obtain <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo>=<\/mo><mn>0.8<\/mn><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>10<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>+<\/mo><mn>0.6<\/mn><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>0.5<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>7.7.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">x_t\n=\n0.8(10)+0.6(-0.5)\n=\n7.7.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The forward process has therefore turned the clean values 10 into a noisy values 7.7 <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This process does not make the exact likelihood easy to calculate. Instead, it gives an easy way to sample plausible noisy paths starting from a known <em>x<sub>0<\/sub><\/em>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is what allows us to contruct the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Evidence_lower_bound\" data-type=\"link\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Evidence_lower_bound\">ELBO<\/a>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The ELBO<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/Evidence_lower_bound\" data-type=\"link\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Evidence_lower_bound\">The ELBO (Evidence Lower Bound)<\/a>, provides a computable lower bound on the true log-likelihood. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To understand it, I use a simple discrete example with only two possible hidden paths, path A and path B. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose the model assigns the joint probabilities: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mtext>A<\/mtext><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.06<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0,\\text{A})=0.06<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">and <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mtext>B<\/mtext><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.04.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0,\\text{B})=0.04.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The true probability of <em>x<sub>0<\/sub><\/em> is obtained by adding the probability of every path: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.06<\/mn><mo>+<\/mo><mn>0.04<\/mn><mo>=<\/mo><mn>0.10.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0)\n=\n0.06+0.04\n=\n0.10.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The true log-likelihood is then<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><mi>log<\/mi><mo>\u2061<\/mo><\/mrow><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>0.10<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2248<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>2.303.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\log p_\\theta(x_0)\n=\n\\log(0.10)\n\\approx\n-2.303.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, adding both paths is easy. In a real diffusion model, there are too many possible trajectories to combine directly. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of considering every path, the ELBO uses the tractable forward distribution<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">q(x_{1:T}\\mid x_0).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the two-path example, suppose the forward process assigns equal probability to both paths: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>A<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.5<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">q(\\text{A}\\mid x_0)=0.5<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">and <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>B<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.5.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">q(\\text{B}\\mid x_0)=0.5.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">the ELBO is <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><munder><mo movablelimits=\"false\">\u2211<\/mo><mtext>paths<\/mtext><\/munder><\/mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>path<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mrow><mspace width=\"0.1667em\"><\/mspace><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><mfrac><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mtext>path<\/mtext><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>path<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/mfrac><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\operatorname{ELBO}(x_0)\n=\n\\sum_{\\text{paths}}\nq(\\text{path}\\mid x_0)\n\\log\n\\frac{\np_\\theta(x_0,\\text{path})\n}{\nq(\\text{path}\\mid x_0)\n}.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Here, path means the whole hidden noisy trajectory<em> x1 ,&#8230;, x<sub>T<\/sub><\/em>. Then <em>q (path <\/em>|<em> x<sub>0<\/sub>)<\/em> is the forward noising process, given the clean data <em>x<sub>0<\/sub><\/em>. p<sub>\u03b8<\/sub> (<em>x<sub>0<\/sub><\/em>, path) is the models joint probability of the clean output and that path, and the whole thing is an avegare over paths of that log ratio.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Essentially, ELBO is how good the model is on average over noisy paths that start from <em>x<sub>0<\/sub><\/em>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For Path A, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mfrac><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mtext>A<\/mtext><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>A<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/mfrac><mo>=<\/mo><mfrac><mn>0.06<\/mn><mn>0.5<\/mn><\/mfrac><mo>=<\/mo><mn>0.12.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\frac{\np_\\theta(x_0,\\text{A})\n}{\nq(\\text{A}\\mid x_0)\n}\n=\n\\frac{0.06}{0.5}\n=\n0.12.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For path B, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mfrac><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mtext>B<\/mtext><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>B<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/mfrac><mo>=<\/mo><mfrac><mn>0.04<\/mn><mn>0.5<\/mn><\/mfrac><mo>=<\/mo><mn>0.08.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\frac{\np_\\theta(x_0,\\text{B})\n}{\nq(\\text{B}\\mid x_0)\n}\n=\n\\frac{0.04}{0.5}\n=\n0.08.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The ELBO is therefore <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0.5<\/mn><mrow><mspace width=\"0.1667em\"><\/mspace><mi>log<\/mi><mo>\u2061<\/mo><\/mrow><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>0.12<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>+<\/mo><mn>0.5<\/mn><mrow><mspace width=\"0.1667em\"><\/mspace><mi>log<\/mi><mo>\u2061<\/mo><\/mrow><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>0.08<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\operatorname{ELBO}(x_0)\n=\n0.5\\log(0.12)\n+\n0.5\\log(0.08).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Numerically, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2248<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>2.323.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\operatorname{ELBO}(x_0)\n\\approx\n-2.323.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The true log-likelihood was <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2248<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>2.303.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\log p_\\theta(x_0)\n\\approx\n-2.303.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Therfore, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mo>\u2212<\/mo><mn>2.323<\/mn><mo>\u2264<\/mo><mo form=\"prefix\" stretchy=\"false\">\u2212<\/mo><mn>2.303.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">-2.323\n\\leq\n-2.303.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The ELBO is slightly smaller than the true log-likelihood, which is why it is called a a lower bound. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why divide by <em>q<\/em>?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The forward distribuition determines how often each path is sampled. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dividing by <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>path<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">q(\\text{path}\\mid x_0)<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">corrects for that sampling probability. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The ratio <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mfrac><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mtext>path<\/mtext><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>path<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/mfrac><annotation encoding=\"application\/x-tex\">\\frac{\np_\\theta(x_0,\\text{path})\n}{\nq(\\text{path}\\mid x_0)\n}<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">compares how much probability the generative model gives the path with how often the forward process samples it. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The connection to KL divergence<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The KL divergence measures the difference between two full probability distributions over hideen paths.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">the exact relationship between the true log-likelihood and the ELBO is<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math><semantics><mrow><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>+<\/mo><msub><mi>D<\/mi><mrow><mtext><\/mtext><mi>KL<\/mi><\/mrow><\/msub><mrow><mo fence=\"true\" form=\"prefix\">(<\/mo><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2225<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo fence=\"true\" form=\"postfix\">)<\/mo><\/mrow><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\log p_\\theta(x_0) = \\operatorname{ELBO}(x_0) + D_{\\mathrm{KL}} \\left( q(x_{1:T}\\mid x_0) \\parallel p_\\theta(x_{1:T}\\mid x_0) \\right).<\/annotation><\/semantics><\/math> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the two-path example, the models true posterioir probability of path A is <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>A<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mn>0.06<\/mn><mn>0.10<\/mn><\/mfrac><mo>=<\/mo><mn>0.6.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(\\text{A}\\mid x_0)\n=\n\\frac{0.06}{0.10}\n=\n0.6.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>B<\/mtext><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mn>0.04<\/mn><mn>0.10<\/mn><\/mfrac><mo>=<\/mo><mn>0.4.<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(\\text{B}\\mid x_0)\n=\n\\frac{0.04}{0.10}\n=\n0.4.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The models true posterior over paths is therefore <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>0.6,0.4<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">(0.6,0.4).\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The forward distribution was <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mn>0.5,0.5<\/mn><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">(0.5,0.5).\n<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Thes distributions are close, but not identical, so the mismatch prodcues a positive KL divergence, making the ELBO slightly smaller than the true log-likelihood. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because KL divergenece cannot be negative, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>D<\/mi><mrow><mtext><\/mtext><mi>KL<\/mi><\/mrow><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mi>q<\/mi><mo>\u2225<\/mo><mi>p<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2265<\/mo><mn>0<\/mn><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">D_{\\mathrm{KL}}(q\\parallel p)\\geq 0,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">we always have <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2264<\/mo><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\operatorname{ELBO}(x_0)\n\\leq\n\\log p_\\theta(x_0).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">If the forward distributions matched the model&#8217;s true posterior exactly, then <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>D<\/mi><mrow><mtext><\/mtext><mi>KL<\/mi><\/mrow><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mi>q<\/mi><mo>\u2225<\/mo><mi>p<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mn>0<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">D_{\\mathrm{KL}}(q\\parallel p)=0<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Applications to Inverse Folding diffusion models<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inverse folding is the task of predicting a sequence that folds into a target structure. Rather than modelling an unconditional distribution over sequences, an inverse folding model conditions everything on fixed structure <em>S<\/em>: <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0 \\mid S).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The structure is held constant throughout, both the forward noising process and the reverse denoising process are conditioned on it. The forward noising process and the reverse denoising process are conditioned on it. The forward process becomes <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><munderover><mo movablelimits=\"false\">\u220f<\/mo><mrow><mi>t<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><mi>T<\/mi><\/munderover><\/mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo separator=\"true\">,<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">q(x_{1:T}\\mid x_0, S)\n=\n\\prod_{t=1}^{T}\nq(x_t\\mid x_{t-1}, S),<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">  and the reverse process becomes <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo>\u223c<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mi>t<\/mi><mo>\u2212<\/mo><mn>1<\/mn><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo separator=\"true\">,<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_{t-1}\n\\sim\np_\\theta(x_{t-1}\\mid x_t, S).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Everything derived in the previous section is carried over unchnaged once <em>S<\/em> is added as a conditioning variable throughout. In particular, the exact decomposition still holds. <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>+<\/mo><msub><mi>D<\/mi><mrow><mtext><\/mtext><mi>KL<\/mi><\/mrow><\/msub><mrow><mo fence=\"true\" form=\"prefix\">(<\/mo><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2225<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo separator=\"true\">,<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo fence=\"true\" form=\"postfix\">)<\/mo><\/mrow><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\log p_\\theta(x_0 \\mid S)\n=\n\\operatorname{ELBO}(x_0 \\mid S)\n+\nD_{\\mathrm{KL}}\n\\left(\nq(x_{1:T}\\mid x_0, S)\n\\parallel\np_\\theta(x_{1:T}\\mid x_0, S)\n\\right).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scoring\/<strong>Ranking<\/strong> a Candidate sequence<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The main use of this scoring, rather than generating. Given a candidate sequence <em>x<sub>0<\/sub><\/em> and a fixed strucure <em>S<\/em>, the question is not what sequence should the model produce, but how plausible does the model consider this specific sequence, given this specific structure. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because the exact log-likelihood is intractible for the same reasons discussed above, the ELBO is used instead. In practice this is computed by taking the known sequence <em>x<sub>0<\/sub><\/em>, corrupting it to a range of noise levels <em>t<\/em>, and evaluating how well the model reconstructs the true sequence identity at each position, conditioned on <em>S<\/em>. Summing these reconstruction terms across timesteps, following the same construction as before, prodcues ELBO (<em>x<\/em><sub><em>0<\/em> <\/sub>| <em>S<\/em>). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because the ELBO is a lower bound rather the exact values, it is less informative than its use as a ranking signal. Two candidate sequences <em>x<\/em><sub>0<\/sub><sup>(1)<\/sup> and x<sub>0<\/sub><sup>(2)<\/sup> for the same structure <em>S<\/em> can be comaped using <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msubsup><mi>x<\/mi><mn>0<\/mn><mrow><mo form=\"prefix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">(<\/mo><mn>1<\/mn><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/msubsup><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mspace width=\"1em\"><\/mspace><mtext>versus<\/mtext><mspace width=\"1em\"><\/mspace><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msubsup><mi>x<\/mi><mn>0<\/mn><mrow><mo form=\"prefix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">(<\/mo><mn>2<\/mn><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/msubsup><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><mi>S<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\operatorname{ELBO}(x_0^{(1)} \\mid S)\n\\quad\\text{versus}\\quad\n\\operatorname{ELBO}(x_0^{(2)} \\mid S).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In practice this can be used to rank candidate sequences or mutations by their structural plausibility under a fixed backbone, since no tractable exact alternative exists.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A note on discrete sequences<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Gaussian forward process intorduced earlier, with <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mi>t<\/mi><\/msub><mo>=<\/mo><msqrt><msub><mover><mi>\u03b1<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">\u203e<\/mo><\/mover><mi>t<\/mi><\/msub><\/msqrt><mspace width=\"0.1667em\"><\/mspace><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo>+<\/mo><msqrt><mrow><mn>1<\/mn><mo>\u2212<\/mo><msub><mover><mi>\u03b1<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">\u203e<\/mo><\/mover><mi>t<\/mi><\/msub><\/mrow><\/msqrt><mspace width=\"0.1667em\"><\/mspace><mi>\u03f5<\/mi><mo separator=\"true\">,<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">x_t\n=\n\\sqrt{\\bar{\\alpha}_t}\\,x_0\n+\n\\sqrt{1-\\bar{\\alpha}_t}\\,\\epsilon,<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">applied to continuous data, Amino acid sequences are categorical rather than continuous, so a discrete diffusion model instead defines a forward process that corrupts a categorical identity directly, for example by replacing a residue with a randomly drawn amino acid with some probability that increases with <em>t<\/em>, rather than adding Gaussian noise to a continuous embedding . <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The overall logic of the ELBO is unaffected by this distinction. The reverse process remains intractable, and the forward process remains tractable to sample from directly, regardless of whether the underlying noise model is Gaussian or categorical. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Conclusion<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For an autoregressive model, the likelihood is directly calculated:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mi>x<\/mi><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mrow><munderover><mo>\u220f<\/mo><mrow><mi>i<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><mi>n<\/mi><\/munderover><\/mrow><mi>p<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mrow><mo lspace=\"0em\" rspace=\"0em\">&lt;<\/mo><mi>i<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p(x)\n=\n\\prod_{i=1}^{n}\np(x_i \\mid x_{&lt;i}).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">For a standard diffusion model, the likelihood requires integrating over intermediate states:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mo movablelimits=\"false\">\u222b<\/mo><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mspace width=\"0.1667em\"><\/mspace><mi>d<\/mi><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo>\u22ef<\/mo><mi>d<\/mi><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">p_\\theta(x_0)\n=\n\\int\np_\\theta(x_{0:T})\n\\,dx_1\\cdots dx_T.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">That integral is the central difficulty. The ELBO avoids calculating it directly. It uses the tractable forward noising process to produce a lower bound on the true log-likelihood.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In a real diffusion model, the hidden variable is the complete noisy trajectory<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>T<\/mi><\/msub><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">x_1,x_2,\\ldots,x_T.<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The ELBO is written as<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>ELBO<\/mi><mo>\u2061<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><msub><mi>\ud835\udd3c<\/mi><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/msub><mrow><mo fence=\"true\" form=\"prefix\">[<\/mo><mrow><mi>log<\/mi><mo>\u2061<\/mo><mspace width=\"0.1667em\"><\/mspace><\/mrow><mfrac><mrow><msub><mi>p<\/mi><mi>\u03b8<\/mi><\/msub><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>0<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><mrow><mi>q<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mrow><mn>1<\/mn><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>T<\/mi><\/mrow><\/msub><mo lspace=\"0.22em\" rspace=\"0.22em\" stretchy=\"false\">|<\/mo><msub><mi>x<\/mi><mn>0<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/mfrac><mo fence=\"true\" form=\"postfix\">]<\/mo><\/mrow><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\operatorname{ELBO}(x_0)\n=\n\\mathbb{E}_{q(x_{1:T}\\mid x_0)}\n\\left[\n\\log\n\\frac{\np_\\theta(x_{0:T})\n}{\nq(x_{1:T}\\mid x_0)\n}\n\\right].<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The main idea is that the exact likelihood requires combining every possible hidden trajectory. The ELBO instead uses trajectories from an easy forward process to calculate a guaranteed lower bound on the log-likelihood. This is why likelihood evaluation is immediate for autoregressive models, while diffusion models often require a variational bound or another specialised estimation method.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been working with inverse folding models for sequence design for a while now, and one question kept coming up. How would you score a sequence&#8217;s likelihood under these models? It turns out the answer depends heavily on whether the model is autoregressive or diffusion-based. Autoregressive models, like GPT-style language models, make this straightforward. You [&hellip;]<\/p>\n","protected":false},"author":131,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","wikipediapreview_detectlinks":true,"_monsterinsights_skip_tracking":false,"ngg_post_thumbnail":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[633,920,189],"tags":[],"ppma_author":[817],"class_list":["post-14543","post","type-post","status-publish","format-standard","hentry","category-ai","category-diffusion","category-machine-learning"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"authors":[{"term_id":817,"user_id":131,"is_guest":0,"slug":"king","display_name":"King Ifashe","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/47fee3b332544ca46a19ab03b6c5b8c35e9a4dbf1247beb5f9b773ed20efcad7?s=96&d=mm&r=g","author_category":"","user_url":"","last_name":"Ifashe","first_name":"King","job_title":"","description":""}],"_links":{"self":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/14543","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/users\/131"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/comments?post=14543"}],"version-history":[{"count":5,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/14543\/revisions"}],"predecessor-version":[{"id":14582,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/14543\/revisions\/14582"}],"wp:attachment":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/media?parent=14543"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/categories?post=14543"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/tags?post=14543"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=14543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}