{ "cells": [ { "cell_type": "code", "execution_count": 10, "id": "c15deb04-94a0-4073-a174-adcd22af10b8", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "The config attributes {'block_out_channels': [128, 128, 256, 512, 512], 'force_upcast': False} were passed to AsymmetricAutoencoderKL, but are not expected and will be ignored. Please verify your config.json configuration file.\n", "The config attributes {'block_out_channels': [128, 128, 256, 512, 512], 'force_upcast': False} were passed to AsymmetricAutoencoderKL, but are not expected and will be ignored. Please verify your config.json configuration file.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "✅ Создана новая модель: \n", "\n", "--- Перенос весов ---\n", "✅ Готово. Модель сохранена в vae9\n" ] } ], "source": [ "from diffusers.models import AsymmetricAutoencoderKL\n", "import torch\n", "from tqdm import tqdm\n", "\n", "# ---- Конфиг новой модели ----\n", "config = {\n", " \"_class_name\": \"AsymmetricAutoencoderKL\",\n", " \"act_fn\": \"silu\",\n", " \"in_channels\": 3,\n", " \"out_channels\": 3,\n", " \"scaling_factor\": 1.0,\n", " \"norm_num_groups\": 32,\n", " \"down_block_out_channels\": [128, 256, 512, 512],\n", " \"down_block_types\": [\n", " \"DownEncoderBlock2D\",\n", " \"DownEncoderBlock2D\",\n", " \"DownEncoderBlock2D\",\n", " \"DownEncoderBlock2D\",\n", " ],\n", " \"latent_channels\": 16,\n", " \"up_block_out_channels\": [128,128, 256, 512, 512],\n", " \"up_block_types\": [\n", " \"UpDecoderBlock2D\",\n", " \"UpDecoderBlock2D\",\n", " \"UpDecoderBlock2D\",\n", " \"UpDecoderBlock2D\",\n", " \"UpDecoderBlock2D\",\n", " ],\n", "}\n", "\n", "# ---- Создание пустой асимметричной модели ----\n", "vae = AsymmetricAutoencoderKL(\n", " act_fn=config[\"act_fn\"],\n", " down_block_out_channels=config[\"down_block_out_channels\"],\n", " down_block_types=config[\"down_block_types\"],\n", " latent_channels=config[\"latent_channels\"],\n", " up_block_out_channels=config[\"up_block_out_channels\"],\n", " up_block_types=config[\"up_block_types\"],\n", " in_channels=config[\"in_channels\"],\n", " out_channels=config[\"out_channels\"],\n", " scaling_factor=config[\"scaling_factor\"],\n", " norm_num_groups=config[\"norm_num_groups\"],\n", " layers_per_down_block=2,\n", " layers_per_up_block=3,\n", " sample_size=256\n", ")\n", "\n", "vae.save_pretrained(\"asymmetric_vae_empty\")\n", "print(\"✅ Создана новая модель:\", type(vae))\n", "\n", "def transfer_weights(old_path, new_path, save_path=\"vae_final\", device=\"cuda\", dtype=torch.float32):\n", " old_vae = AsymmetricAutoencoderKL.from_pretrained(old_path).to(device, dtype=dtype)\n", " new_vae = AsymmetricAutoencoderKL.from_pretrained(new_path).to(device, dtype=dtype)\n", "\n", " old_sd = old_vae.state_dict()\n", " new_sd = new_vae.state_dict()\n", "\n", " print(\"\\n--- Перенос весов ---\")\n", " \n", " # 1. Переносим всё, что совпадает по именам и формам (Энкодер, конволоции и т.д.)\n", " # Это покроет Encoder полностью, так как там down_blocks не менялись\n", " for k, v in old_sd.items():\n", " if k in new_sd and v.shape == new_sd[k].shape:\n", " new_sd[k] = v.clone()\n", "\n", " # 2. Переносим блоки декодера (Up-blocks)\n", " # Старый: [0, 1, 2, 3, 4] -> Новой: [0, 1, 2, 3]\n", " # Нам нужно перенести глубокие слои (0, 1, 2), а последний 3-й взять из 4-го старого\n", " \n", " # Сопоставление индексов: старый блок -> новый блок\n", " # Мы берем 0->0, 1->1, 2->2 и 4->3 (пропуская лишний блок 128->128)\n", " mapping = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4} \n", " \n", " for old_idx, new_idx in mapping.items():\n", " old_prefix = f\"decoder.up_blocks.{old_idx}.\"\n", " new_prefix = f\"decoder.up_blocks.{new_idx}.\"\n", " \n", " for k, v in old_sd.items():\n", " if k.startswith(old_prefix):\n", " new_key = k.replace(old_prefix, new_prefix)\n", " if new_key in new_sd and v.shape == new_sd[new_key].shape:\n", " new_sd[new_key] = v.clone()\n", " else:\n", " print(f\"⚠️ Пропущен слой или не совпал размер: {new_key}\")\n", "\n", " # Загрузка\n", " new_vae.load_state_dict(new_sd, strict=False)\n", " new_vae.save_pretrained(save_path)\n", " print(f\"✅ Готово. Модель сохранена в {save_path}\")\n", "\n", "# Запуск\n", "transfer_weights(\"vae8\", \"asymmetric_vae_empty\", save_path=\"vae9\")\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "59fcafb9-6d89-49b4-8362-b4891f591687", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }