{"record":{"id":"e4719032baf63952","repo":"lllyasviel/ControlNet","slug":"encoder-posterior-of-type-type-encoder-posterior","errorCode":null,"errorMessage":"encoder_posterior of type '{type(encoder_posterior)}' not yet implemented","messagePattern":"encoder_posterior of type '(.+?)' not yet implemented","errorType":"validation","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"ldm/models/diffusion/ddpm.py","lineNumber":661,"sourceCode":"    def _get_denoise_row_from_list(self, samples, desc='', force_no_decoder_quantization=False):\n        denoise_row = []\n        for zd in tqdm(samples, desc=desc):\n            denoise_row.append(self.decode_first_stage(zd.to(self.device),\n                                                       force_not_quantize=force_no_decoder_quantization))\n        n_imgs_per_row = len(denoise_row)\n        denoise_row = torch.stack(denoise_row)  # n_log_step, n_row, C, H, W\n        denoise_grid = rearrange(denoise_row, 'n b c h w -> b n c h w')\n        denoise_grid = rearrange(denoise_grid, 'b n c h w -> (b n) c h w')\n        denoise_grid = make_grid(denoise_grid, nrow=n_imgs_per_row)\n        return denoise_grid\n\n    def get_first_stage_encoding(self, encoder_posterior):\n        if isinstance(encoder_posterior, DiagonalGaussianDistribution):\n            z = encoder_posterior.sample()\n        elif isinstance(encoder_posterior, torch.Tensor):\n            z = encoder_posterior\n        else:\n            raise NotImplementedError(f\"encoder_posterior of type '{type(encoder_posterior)}' not yet implemented\")\n        return self.scale_factor * z\n\n    def get_learned_conditioning(self, c):\n        if self.cond_stage_forward is None:\n            if hasattr(self.cond_stage_model, 'encode') and callable(self.cond_stage_model.encode):\n                c = self.cond_stage_model.encode(c)\n                if isinstance(c, DiagonalGaussianDistribution):\n                    c = c.mode()\n            else:\n                c = self.cond_stage_model(c)\n        else:\n            assert hasattr(self.cond_stage_model, self.cond_stage_forward)\n            c = getattr(self.cond_stage_model, self.cond_stage_forward)(c)\n        return c\n\n    def meshgrid(self, h, w):\n        y = torch.arange(0, h).view(h, 1, 1).repeat(1, w, 1)\n        x = torch.arange(0, w).view(1, w, 1).repeat(h, 1, 1)","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/lllyasviel/ControlNet/blob/ed85cd1e25a5ed592f7d8178495b4483de0331bf/ldm/models/diffusion/ddpm.py#L643-L679","documentation":"get_first_stage_encoding accepts either a DiagonalGaussianDistribution (VAE posterior, sampled to a latent) or a plain torch.Tensor latent. Anything else — e.g. a numpy array, list, or a different distribution object — raises NotImplementedError before applying scale_factor.","triggerScenarios":"Calling on_train_batch_start/get_input where the VAE encode step returned a non-tensor/non-DiagonalGaussianDistribution object: a numpy latent, a tuple of (mean, logvar), or None from a custom first_stage_model.","commonSituations":"Swapping in a custom VAE whose encode returns a different type; preprocessing pipelines that precompute latents to numpy .npy files; monkey-patches that bypass the standard encode path.","solutions":["Ensure the first-stage encoder returns DiagonalGaussianDistribution (use ldm.modules.distributions.DiagonalGaussianDistribution) or a torch tensor","Convert precomputed latents to torch tensors: torch.from_numpy(latent).to(device)","Check any custom encode override returns one of the two supported types"],"exampleFix":"# before\nz = np.load('latent.npy')\n# after\nz = torch.from_numpy(np.load('latent.npy')).to(device, torch.float32)","handlingStrategy":"type-guard","validationCode":"from ldm.modules.distributions import DiagonalGaussianDistribution\nassert isinstance(encoder_posterior, (DiagonalGaussianDistribution, torch.Tensor)), type(encoder_posterior)","typeGuard":"import torch\nfrom ldm.modules.distributions import DiagonalGaussianDistribution\n\ndef is_valid_posterior(p) -> bool:\n    return isinstance(p, (DiagonalGaussianDistribution, torch.Tensor))","tryCatchPattern":"try:\n    z = model.get_first_stage_encoding(post)\nexcept NotImplementedError:\n    z = model.scale_factor * torch.as_tensor(post, dtype=torch.float32, device=model.device)","preventionTips":["Keep precomputed latents as torch tensors, convert .npy at load time","Custom VAE encode overrides should return DiagonalGaussianDistribution"],"tags":["diffusion","vae","latent","type-error"],"backgroundTag":"unsupported-type","analyzedSha":"ed85cd1e25a5ed592f7d8178495b4483de0331bf","analyzedAt":"2026-08-27T12:58:54.167Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}