{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"%%writefile ayarlar.py\nHF_TOKEN = \"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\"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile egitim.py\n\n\nimport os\nimport gc\nimport time\nimport math\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nimport torchvision.utils as vutils\nimport torchvision.transforms.functional as TF\nfrom torchvision.io import encode_jpeg, decode_jpeg\nimport random\nimport io\nfrom PIL import Image, ImageFile, ImageFilter\nimport torch.distributed as dist\nimport torch.multiprocessing as mp\nfrom torch.nn.parallel import DistributedDataParallel as DDP\nfrom diffusers import AutoencoderKL\nimport bitsandbytes as bnb\nimport numpy as np\nfrom PIL import ImageDraw\nfrom ayarlar import HF_TOKEN\n\nImageFile.LOAD_TRUNCATED_IMAGES = True\n\n\n\n\n\n\n\ndef rastgele_duzenleme_maskesi(width, height, task_id):\n    \"\"\"\n    task_id:\n        1 = inpainting\n        2 = outpainting\n\n    Dönen maske:\n        [1, H, W], float32\n        1 = üretilecek/doldurulacak alan\n        0 = korunacak alan\n    \"\"\"\n\n    def tensor_yap(mask_pil):\n        arr = np.array(mask_pil, dtype=np.float32, copy=True) / 255.0\n        return torch.from_numpy(arr).unsqueeze(0)\n\n    for _ in range(64):\n\n        if task_id == 2:\n\n\n\n            mask_pil = Image.new(\"L\", (width, height), 255)\n            draw = ImageDraw.Draw(mask_pil)\n\n            kenar_sayisi = random.choices(\n                [1, 2, 3, 4],\n                weights=[0.35, 0.35, 0.20, 0.10],\n                k=1,\n            )[0]\n\n            kenarlar = random.sample(\n                [\"left\", \"right\", \"top\", \"bottom\"],\n                kenar_sayisi,\n            )\n\n            alt_oran = 0.15 if kenar_sayisi == 1 else 0.10\n            ust_oran = 0.60 if kenar_sayisi == 1 else 0.40\n\n            left = (\n                int(width * random.uniform(alt_oran, ust_oran))\n                if \"left\" in kenarlar else 0\n            )\n            right = (\n                int(width * random.uniform(alt_oran, ust_oran))\n                if \"right\" in kenarlar else 0\n            )\n            top = (\n                int(height * random.uniform(alt_oran, ust_oran))\n                if \"top\" in kenarlar else 0\n            )\n            bottom = (\n                int(height * random.uniform(alt_oran, ust_oran))\n                if \"bottom\" in kenarlar else 0\n            )\n\n            draw.rectangle(\n                [\n                    left,\n                    top,\n                    width - right - 1,\n                    height - bottom - 1,\n                ],\n                fill=0,\n            )\n\n            min_oran, max_oran = 0.15, 0.75\n\n        else:\n\n\n            mask_pil = Image.new(\"L\", (width, height), 0)\n            draw = ImageDraw.Draw(mask_pil)\n\n            parca_sayisi = random.choices(\n                [1, 2, 3, 4],\n                weights=[0.45, 0.30, 0.15, 0.10],\n                k=1,\n            )[0]\n\n            for _ in range(parca_sayisi):\n                sekil = random.choice(\n                    [\"rectangle\", \"ellipse\", \"polygon\", \"brush\"]\n                )\n\n                cx = random.uniform(0.05, 0.95) * width\n                cy = random.uniform(0.05, 0.95) * height\n\n                rw = random.uniform(0.08, 0.45) * width\n                rh = random.uniform(0.08, 0.45) * height\n\n                bbox = [\n                    int(cx - rw / 2),\n                    int(cy - rh / 2),\n                    int(cx + rw / 2),\n                    int(cy + rh / 2),\n                ]\n\n                if sekil == \"rectangle\":\n                    draw.rectangle(bbox, fill=255)\n\n                elif sekil == \"ellipse\":\n                    draw.ellipse(bbox, fill=255)\n\n                elif sekil == \"polygon\":\n\n                    nokta_sayisi = random.randint(5, 10)\n                    acilar = sorted(\n                        random.uniform(0, 2 * math.pi)\n                        for _ in range(nokta_sayisi)\n                    )\n\n                    noktalar = []\n                    for aci in acilar:\n                        yaricap = random.uniform(0.55, 1.0)\n                        x = cx + math.cos(aci) * rw * yaricap\n                        y = cy + math.sin(aci) * rh * yaricap\n                        noktalar.append((int(x), int(y)))\n\n                    draw.polygon(noktalar, fill=255)\n\n                else:\n\n                    kalinlik = max(\n                        4,\n                        int(\n                            min(width, height)\n                            * random.uniform(0.025, 0.13)\n                        ),\n                    )\n\n                    x, y = cx, cy\n                    noktalar = [(int(x), int(y))]\n\n                    for _ in range(random.randint(3, 9)):\n                        aci = random.uniform(0, 2 * math.pi)\n                        uzunluk = (\n                            min(width, height)\n                            * random.uniform(0.04, 0.22)\n                        )\n\n                        x = min(\n                            width - 1,\n                            max(0, x + math.cos(aci) * uzunluk),\n                        )\n                        y = min(\n                            height - 1,\n                            max(0, y + math.sin(aci) * uzunluk),\n                        )\n                        noktalar.append((int(x), int(y)))\n\n                    draw.line(noktalar, fill=255, width=kalinlik)\n\n\n                    r = kalinlik / 2\n                    for x, y in noktalar:\n                        draw.ellipse(\n                            [int(x-r), int(y-r), int(x+r), int(y+r)],\n                            fill=255,\n                        )\n\n            min_oran, max_oran = 0.02, 0.60\n\n        mask = tensor_yap(mask_pil)\n        kapali_oran = mask.mean().item()\n\n\n        if min_oran <= kapali_oran <= max_oran:\n            return mask\n\n\n    mask = torch.zeros(1, height, width)\n\n    if task_id == 2:\n        mask[:, :, :width // 3] = 1.0\n    else:\n        mask[\n            :,\n            height // 4:3 * height // 4,\n            width // 4:3 * width // 4,\n        ] = 1.0\n\n    return mask\n\n\n\n\n\n\nclass SuperResDataset(Dataset):\n    def __init__(self, folder_infos, rank=0, cache_name=\"dataset_cache.pt\", split=\"train\", val_ratio=0.01):\n        self.hr_crop = transforms.Compose([\n            transforms.RandomCrop(512, pad_if_needed=True),\n            transforms.RandomHorizontalFlip()\n        ])\n\n        self.task_probs = (0.50, 0.25, 0.25)\n\n        self.to_tensor = transforms.Compose([\n            transforms.ToTensor(),\n            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n        ])\n\n        if os.path.exists(cache_name) and os.path.getsize(cache_name) > 0:\n            basarili = False\n            while not basarili:\n                try:\n                    self.image_paths = torch.load(cache_name, weights_only=False)\n                    basarili = True\n                except (EOFError, RuntimeError):\n                    time.sleep(1)\n        else:\n            if rank != 0:\n                while not os.path.exists(cache_name):\n                    time.sleep(1)\n                basarili = False\n                while not basarili:\n                    try:\n                        if os.path.getsize(cache_name) > 0:\n                            self.image_paths = torch.load(cache_name, weights_only=False)\n                            basarili = True\n                        else:\n                            time.sleep(1)\n                    except (EOFError, RuntimeError):\n                        time.sleep(1)\n            else:\n                self.image_paths = []\n                gecerli_uzantilar = ('.png', '.jpg', '.jpeg', '.PNG', '.JPG', '.JPEG')\n\n                for folder_path, multiplier in folder_infos:\n                    if folder_path and os.path.exists(folder_path):\n                        paths = []\n                        for root, dirs, files in os.walk(folder_path):\n                            for f in files:\n                                if f.endswith(gecerli_uzantilar):\n                                    paths.append(os.path.join(root, f))\n\n                        paths.sort()\n                        toplam_adet = len(paths)\n\n                        if toplam_adet > 0:\n                            val_sayisi = max(1, int(toplam_adet * val_ratio))\n                            train_sayisi = toplam_adet - val_sayisi\n\n                            if split == \"train\":\n                                secilen_paths = paths[:train_sayisi]\n                            else:\n                                secilen_paths = paths[-val_sayisi:]\n\n                            if multiplier == 1:\n                                self.image_paths.extend(secilen_paths)\n                            else:\n                                self.image_paths.extend(secilen_paths * multiplier)\n\n                temp_cache = cache_name + \".tmp\"\n                torch.save(self.image_paths, temp_cache)\n                os.replace(temp_cache, cache_name)\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        if len(self.image_paths) == 0:\n            raise RuntimeError(\"Dataset bos.\")\n\n\n        for attempt in range(16):\n            path = self.image_paths[\n                (idx + attempt) % len(self.image_paths)\n            ]\n\n            try:\n                with Image.open(path) as opened:\n                    img = opened.convert(\"RGB\")\n                break\n            except (OSError, ValueError):\n                continue\n        else:\n            raise RuntimeError(\n                f\"Ardisik 16 dosya okunamadi. Baslangic index: {idx}\"\n            )\n\n        hr_pil = self.hr_crop(img)\n        hr_tensor = self.to_tensor(hr_pil)\n\n        task_id = random.choices(\n            [0, 1, 2],\n            weights=self.task_probs,\n            k=1,\n        )[0]\n\n        if task_id == 0:\n\n\n\n\n            lr_pil = hr_pil.copy()\n\n            scale_factor = random.uniform(2.0, 8.0)\n            target_size = max(1, int(512 / scale_factor))\n\n            resample_mod = random.choice([\n                Image.Resampling.BICUBIC,\n                Image.Resampling.BILINEAR,\n                Image.Resampling.NEAREST,\n            ])\n\n            lr_pil = lr_pil.resize(\n                (target_size, target_size),\n                resample=resample_mod,\n            )\n\n            if random.random() < 0.6:\n                sigma = random.uniform(0.5, 3.0)\n                lr_pil = lr_pil.filter(\n                    ImageFilter.GaussianBlur(radius=sigma)\n                )\n\n            lr_pil = lr_pil.resize(\n                (512, 512),\n                resample=resample_mod,\n            )\n\n            if random.random() < 0.2:\n                jpeg_quality = random.randint(30, 60)\n\n                with io.BytesIO() as buffer:\n                    lr_pil.save(\n                        buffer,\n                        format=\"JPEG\",\n                        quality=jpeg_quality,\n                    )\n                    buffer.seek(0)\n                    with Image.open(buffer) as compressed:\n                        lr_pil = compressed.convert(\"RGB\")\n\n            condition_tensor = self.to_tensor(lr_pil)\n\n            if random.random() < 0.3:\n                noise_level = random.uniform(0.01, 0.1)\n                condition_tensor = (\n                    condition_tensor\n                    + torch.randn_like(condition_tensor) * noise_level\n                ).clamp(-1.0, 1.0)\n\n\n            mask = torch.ones(\n                1,\n                hr_tensor.shape[-2],\n                hr_tensor.shape[-1],\n                dtype=torch.float32,\n            )\n\n        else:\n\n\n\n\n            mask = rastgele_duzenleme_maskesi(\n                width=hr_tensor.shape[-1],\n                height=hr_tensor.shape[-2],\n                task_id=task_id,\n            )\n\n            condition_tensor = hr_tensor * (1.0 - mask)\n\n        return hr_tensor, condition_tensor, mask, task_id\n\n\n\nclass DiffusionZamanlayici:\n    def __init__(self, adim_sayisi=1000, device='cpu'):\n        self.adim_sayisi = adim_sayisi\n        self.device = device\n        self.beta = torch.linspace(1e-4, 0.02, adim_sayisi, dtype=torch.float32).to(device)\n        self.alpha = 1.0 - self.beta\n        self.alpha_sapka = torch.cumprod(self.alpha, dim=0)\n\n    def gurultu_ekle(self, x_0, t, gurultu):\n        sqrt_alpha_sapka = torch.sqrt(self.alpha_sapka[t])[:, None, None, None]\n        sqrt_bir_eksi_alpha_sapka = torch.sqrt(1.0 - self.alpha_sapka[t])[:, None, None, None]\n        return sqrt_alpha_sapka * x_0 + sqrt_bir_eksi_alpha_sapka * gurultu\n\nclass SinusoidalPositionEmbeddings(nn.Module):\n    def __init__(self, dim):\n        super().__init__()\n        self.dim = dim\n    def forward(self, time):\n        device = time.device\n        half_dim = self.dim // 2\n        embeddings = math.log(10000) / (half_dim - 1)\n        embeddings = torch.exp(torch.arange(half_dim, device=device) * -embeddings)\n        embeddings = time[:, None].float() * embeddings[None, :]\n        embeddings = torch.cat((embeddings.sin(), embeddings.cos()), dim=-1)\n        return embeddings\n\nclass FP32GroupNorm(nn.GroupNorm):\n    def forward(self, x):\n        y = super().forward(x.float())\n        return y.to(dtype=x.dtype)\n\nclass AttentionBlock(nn.Module):\n    def __init__(self, dim, head_dim=64):\n        super().__init__()\n\n        if head_dim <= 0 or dim % head_dim != 0:\n            raise ValueError(\"dim, pozitif head_dim degerine tam bolunmeli.\")\n\n        self.num_heads = dim // head_dim\n        self.head_dim = head_dim\n\n        self.norm = FP32GroupNorm(8, dim, eps=1e-4)\n        self.qkv = nn.Conv2d(dim, dim * 3, 1)\n        self.proj = nn.Conv2d(dim, dim, 1)\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n\n        qkv = self.qkv(self.norm(x))\n        qkv = qkv.reshape(\n            B, 3, self.num_heads, self.head_dim, H * W\n        )\n\n        q, k, v = qkv.unbind(dim=1)\n\n        q = q.transpose(-2, -1).contiguous()\n        k = k.transpose(-2, -1).contiguous()\n        v = v.transpose(-2, -1).contiguous()\n\n        out = F.scaled_dot_product_attention(\n            q, k, v,\n            dropout_p=0.0,\n            is_causal=False,\n        )\n\n        out = out.transpose(-2, -1).contiguous().reshape(B, C, H, W)\n\n        return x + self.proj(out)\n\nclass ResNetBlock(nn.Module):\n    def __init__(self, in_c, out_c, time_emb_dim):\n        super().__init__()\n        self.time_mlp = nn.Linear(time_emb_dim, out_c)\n        self.conv1 = nn.Conv2d(in_c, out_c, 3, padding=1)\n        self.conv2 = nn.Conv2d(out_c, out_c, 3, padding=1)\n        self.bn1 = FP32GroupNorm(8, in_c, eps=1e-4)\n        self.bn2 = FP32GroupNorm(8, out_c, eps=1e-4)\n        self.relu = nn.SiLU()\n        self.shortcut = nn.Conv2d(in_c, out_c, 1) if in_c != out_c else nn.Identity()\n\n    def forward(self, x, t_emb):\n        h = self.relu(self.bn1(x))\n        h = self.conv1(h)\n        time_info = self.time_mlp(t_emb)[:, :, None, None]\n        h = h + time_info\n        h = self.relu(self.bn2(h))\n        h = self.conv2(h)\n        return h + self.shortcut(x)\n\nclass ConditionalUNet(nn.Module):\n    def __init__(self):\n        super().__init__()\n        time_dim = 512\n        self.time_mlp = nn.Sequential(\n            SinusoidalPositionEmbeddings(time_dim),\n            nn.Linear(time_dim, time_dim),\n            nn.SiLU()\n        )\n        self.init_conv = nn.Conv2d(36, 128, 3, padding=1)\n        self.down1_1 = ResNetBlock(128, 128, time_dim)\n        self.down1_2 = ResNetBlock(128, 256, time_dim)\n        self.pool1 = nn.MaxPool2d(2)\n        self.down2_1 = ResNetBlock(256, 256, time_dim)\n        self.down2_2 = ResNetBlock(256, 512, time_dim)\n        self.attn2 = AttentionBlock(512)\n        self.pool2 = nn.MaxPool2d(2)\n        self.down3_1 = ResNetBlock(512, 512, time_dim)\n        self.down3_2 = ResNetBlock(512, 768, time_dim)\n        self.attn3 = AttentionBlock(768)\n        self.pool3 = nn.MaxPool2d(2)\n        self.mid1 = ResNetBlock(768, 768, time_dim)\n        self.mid_attn = AttentionBlock(768)\n        self.mid2 = ResNetBlock(768, 768, time_dim)\n        self.up1 = nn.ConvTranspose2d(768, 768, 2, 2)\n        self.up_res1_1 = ResNetBlock(1536, 512, time_dim)\n        self.up_res1_2 = ResNetBlock(512, 512, time_dim)\n        self.up_attn1 = AttentionBlock(512)\n        self.up2 = nn.ConvTranspose2d(512, 512, 2, 2)\n        self.up_res2_1 = ResNetBlock(1024, 256, time_dim)\n        self.up_res2_2 = ResNetBlock(256, 256, time_dim)\n        self.up_attn2 = AttentionBlock(256)\n        self.up3 = nn.ConvTranspose2d(256, 256, 2, 2)\n        self.up_res3_1 = ResNetBlock(512, 128, time_dim)\n        self.up_res3_2 = ResNetBlock(128, 128, time_dim)\n        self.final_conv = nn.Sequential(\n            FP32GroupNorm(8, 128, eps=1e-4),\n            nn.SiLU(),\n            nn.Conv2d(128, 16, 3, padding=1)\n        )\n        nn.init.zeros_(self.final_conv[-1].weight)\n        nn.init.zeros_(self.final_conv[-1].bias)\n\n    def forward(\n        self,\n        x_noisy,\n        t,\n        condition_lr,\n        edit_mask,\n        task_ids,\n    ):\n        t_emb = self.time_mlp(t)\n\n        task_map = F.one_hot(\n            task_ids.long(),\n            num_classes=3,\n        ).to(dtype=x_noisy.dtype)\n\n        task_map = task_map[:, :, None, None].expand(\n            -1,\n            -1,\n            x_noisy.shape[-2],\n            x_noisy.shape[-1],\n        )\n\n        x = torch.cat(\n            [\n                x_noisy,\n                condition_lr.to(dtype=x_noisy.dtype),\n                edit_mask.to(dtype=x_noisy.dtype),\n                task_map,\n            ],\n            dim=1,\n        )\n\n        x = self.init_conv(x)\n\n\n        d1 = self.down1_1(x, t_emb)\n        d1 = self.down1_2(d1, t_emb)\n        d2 = self.down2_1(self.pool1(d1), t_emb)\n        d2 = self.down2_2(d2, t_emb)\n        d2 = self.attn2(d2)\n        d3 = self.down3_1(self.pool2(d2), t_emb)\n        d3 = self.down3_2(d3, t_emb)\n        d3 = self.attn3(d3)\n        mid = self.pool3(d3)\n        mid = self.mid1(mid, t_emb)\n        mid = self.mid_attn(mid)\n        mid = self.mid2(mid, t_emb)\n        u1 = self.up1(mid)\n        u1 = torch.cat([u1, d3], dim=1)\n        u1 = self.up_res1_1(u1, t_emb)\n        u1 = self.up_res1_2(u1, t_emb)\n        u1 = self.up_attn1(u1)\n        u2 = self.up2(u1)\n        u2 = torch.cat([u2, d2], dim=1)\n        u2 = self.up_res2_1(u2, t_emb)\n        u2 = self.up_res2_2(u2, t_emb)\n        u2 = self.up_attn2(u2)\n        u3 = self.up3(u2)\n        u3 = torch.cat([u3, d1], dim=1)\n        u3 = self.up_res3_1(u3, t_emb)\n        u3 = self.up_res3_2(u3, t_emb)\n        return self.final_conv(u3)\n\n\n@torch.no_grad()\ndef latentleri_hazirla(\n    vae,\n    hr_imgs,\n    condition_imgs,\n    pixel_masks,\n    task_ids,\n    latent_scale,\n    latent_shift,\n    lr_use_mode,\n):\n    hr_latents = (\n        vae.encode(hr_imgs).latent_dist.sample() - latent_shift\n    ) * latent_scale\n\n    posterior = vae.encode(condition_imgs).latent_dist\n\n\n    condition_latents = posterior.mode()\n\n\n\n    if not lr_use_mode:\n        sampled = posterior.sample()\n        sr_selector = (task_ids == 0)[:, None, None, None]\n\n        condition_latents = torch.where(\n            sr_selector,\n            sampled,\n            condition_latents,\n        )\n\n    condition_latents = (\n        condition_latents - latent_shift\n    ) * latent_scale\n\n\n    latent_masks = F.adaptive_max_pool2d(\n        pixel_masks,\n        output_size=hr_latents.shape[-2:],\n    )\n\n    return hr_latents, condition_latents, latent_masks\n\n\ndef maskeli_v_loss(prediction, target, latent_masks):\n    loss_map = F.huber_loss(\n        prediction,\n        target,\n        reduction=\"none\",\n        delta=1.0,\n    ).mean(dim=1, keepdim=True)\n\n\n\n\n\n    weights = latent_masks + 0.1 * (1.0 - latent_masks)\n\n    per_sample = (\n        (loss_map * weights).sum(dim=(1, 2, 3))\n        / weights.sum(dim=(1, 2, 3)).clamp_min(1e-8)\n    )\n\n\n    return per_sample.mean()\n\n\nclass EMA:\n    def __init__(self, model, decay=0.9999):\n        import copy\n        self.target_decay = decay\n        self.step = 0\n        self.ema_model = copy.deepcopy(model)\n        self.ema_model.eval()\n        for param in self.ema_model.parameters():\n            param.requires_grad = False\n\n    @torch.no_grad()\n    def update(self, current_model):\n\n        current_decay = min(self.target_decay, (1 + self.step) / (10 + self.step))\n\n        for ema_param, model_param in zip(self.ema_model.parameters(), current_model.parameters()):\n            ema_param.data.mul_(current_decay).add_(model_param.data, alpha=1 - current_decay)\n\n        self.step += 1\n\nclass ResumableDistributedSampler(torch.utils.data.distributed.DistributedSampler):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_index = 0\n\n    def set_start_step(self, step, batch_size):\n        if step < 0 or batch_size <= 0:\n            raise ValueError(\"step negatif olamaz ve batch_size pozitif olmali.\")\n\n        self.start_index = step * batch_size\n\n    def __iter__(self):\n        from itertools import islice\n\n        return islice(super().__iter__(), self.start_index, None)\n\n    def __len__(self):\n        return max(0, super().__len__() - self.start_index)\n\n@torch.no_grad()\ndef cok_gorevli_ornek_uret(\n    model,\n    vae,\n    difuzyon,\n    condition_imgs,\n    condition_latents,\n    pixel_masks,\n    latent_masks,\n    task_ids,\n    latent_scale,\n    latent_shift,\n    steps=30,\n    cfg=1.0,\n    eta=0.0,\n):\n    if not 2 <= steps <= difuzyon.adim_sayisi:\n        raise ValueError(\n            \"Ornekleme adimi 2 ile difuzyon.adim_sayisi arasinda olmali.\"\n        )\n\n\n\n    x = torch.randn_like(condition_latents)\n    batch_size = x.shape[0]\n\n    zamanlar = (\n        torch.linspace(\n            0,\n            math.sqrt(difuzyon.adim_sayisi - 1),\n            steps,\n            device=x.device,\n        )\n        .square()\n        .round()\n        .long()\n        .flip(0)\n        .unique_consecutive()\n        .tolist()\n    )\n\n    for index, t_cur in enumerate(zamanlar):\n        t_batch = torch.full(\n            (batch_size,),\n            t_cur,\n            device=x.device,\n            dtype=torch.long,\n        )\n\n        v_cond = model(\n            x,\n            t_batch,\n            condition_latents,\n            latent_masks,\n            task_ids,\n        )\n\n        if cfg != 1.0:\n\n\n            v_uncond = model(\n                x,\n                t_batch,\n                torch.zeros_like(condition_latents),\n                latent_masks,\n                task_ids,\n            )\n\n            v_pred = v_uncond + cfg * (v_cond - v_uncond)\n        else:\n            v_pred = v_cond\n\n        alpha = difuzyon.alpha_sapka[t_cur]\n\n        if index + 1 < len(zamanlar):\n            alpha_prev = difuzyon.alpha_sapka[\n                zamanlar[index + 1]\n            ]\n        else:\n            alpha_prev = torch.ones_like(alpha)\n\n\n        x0 = (\n            alpha.sqrt() * x\n            - (1.0 - alpha).sqrt() * v_pred\n        )\n\n        eps = (\n            (1.0 - alpha).sqrt() * x\n            + alpha.sqrt() * v_pred\n        )\n\n        sigma = eta * torch.sqrt(\n            (\n                (1.0 - alpha_prev)\n                / (1.0 - alpha)\n                * (1.0 - alpha / alpha_prev)\n            ).clamp_min(0.0)\n        )\n\n        direction = (\n            1.0 - alpha_prev - sigma.square()\n        ).clamp_min(0.0).sqrt()\n\n        x = alpha_prev.sqrt() * x0 + direction * eps\n\n        if eta > 0 and index + 1 < len(zamanlar):\n            x = x + sigma * torch.randn_like(x)\n\n    generated = vae.decode(\n        x / latent_scale + latent_shift\n    ).sample.clamp(-1.0, 1.0)\n\n    generated = generated.to(dtype=condition_imgs.dtype)\n\n\n\n\n\n\n\n    result = torch.where(\n        pixel_masks.bool(),\n        generated,\n        condition_imgs,\n    )\n\n    return result\n\n\n@torch.no_grad()\ndef cok_gorevli_validation(\n    model,\n    vae,\n    val_loader,\n    difuzyon,\n    device,\n    latent_scale,\n    latent_shift,\n    lr_use_mode,\n    epoch,\n):\n    model.eval()\n\n    toplam_loss = 0.0\n    toplam_ornek = 0\n\n    gorev_adlari = [\"SR\", \"inpainting\", \"outpainting\"]\n\n    for val_step, batch in enumerate(val_loader):\n        if val_step >= 10:\n            break\n\n        hr, condition, pixel_masks, task_ids = batch\n\n        hr = hr.to(device, non_blocking=True)\n        condition = condition.to(device, non_blocking=True)\n        pixel_masks = pixel_masks.to(device, non_blocking=True)\n        task_ids = task_ids.to(device, non_blocking=True)\n\n        hr_z, condition_z, latent_masks = latentleri_hazirla(\n            vae=vae,\n            hr_imgs=hr,\n            condition_imgs=condition,\n            pixel_masks=pixel_masks,\n            task_ids=task_ids,\n            latent_scale=latent_scale,\n            latent_shift=latent_shift,\n            lr_use_mode=lr_use_mode,\n        )\n\n        batch_size = hr.shape[0]\n\n        t = torch.randint(\n            0,\n            difuzyon.adim_sayisi,\n            (batch_size,),\n            device=device,\n            dtype=torch.long,\n        )\n\n        noise = torch.randn_like(hr_z)\n        noisy = difuzyon.gurultu_ekle(hr_z, t, noise)\n\n        prediction = model(\n            noisy,\n            t,\n            condition_z,\n            latent_masks,\n            task_ids,\n        )\n\n        alpha = difuzyon.alpha_sapka[t][:, None, None, None]\n\n        target = (\n            alpha.sqrt() * noise\n            - (1.0 - alpha).sqrt() * hr_z\n        )\n\n        loss = maskeli_v_loss(\n            prediction,\n            target,\n            latent_masks,\n        )\n\n        toplam_loss += loss.item() * batch_size\n        toplam_ornek += batch_size\n\n\n        if val_step < 2:\n            count = min(4, batch_size)\n\n            generated = cok_gorevli_ornek_uret(\n                model=model,\n                vae=vae,\n                difuzyon=difuzyon,\n                condition_imgs=condition[:count],\n                condition_latents=condition_z[:count],\n                pixel_masks=pixel_masks[:count],\n                latent_masks=latent_masks[:count],\n                task_ids=task_ids[:count],\n                latent_scale=latent_scale,\n                latent_shift=latent_shift,\n                steps=30,\n                cfg=1.0,\n                eta=0.0,\n            )\n\n\n\n\n            mask_visual = (\n                pixel_masks[:count].expand(-1, 3, -1, -1)\n                * 2.0\n                - 1.0\n            )\n\n\n\n\n\n\n            grid = torch.cat(\n                [\n                    condition[:count],\n                    mask_visual,\n                    generated,\n                    hr[:count],\n                ],\n                dim=0,\n            )\n\n            dosya_adi = (\n                f\"ornek_epoch_{epoch}_multitask_{val_step}.png\"\n            )\n\n            vutils.save_image(\n                grid,\n                dosya_adi,\n                nrow=count,\n                normalize=True,\n                value_range=(-1, 1),\n            )\n\n            secilen_gorevler = [\n                gorev_adlari[i]\n                for i in task_ids[:count].tolist()\n            ]\n\n            print(\n                f\"[VAL] {dosya_adi} | \"\n                f\"Sutunlardaki gorevler: {secilen_gorevler}\"\n            )\n\n    if toplam_ornek == 0:\n        raise RuntimeError(\"Validation dataset bos.\")\n\n    return toplam_loss / toplam_ornek\n\n\ndef train_worker(rank, world_size):\n    torch.backends.cudnn.benchmark = True\n    torch.backends.cuda.matmul.allow_tf32 = True\n    torch.backends.cudnn.allow_tf32 = True\n\n    os.environ['MASTER_ADDR'] = '127.0.0.1'\n    os.environ['MASTER_PORT'] = '12355'\n    os.environ['NCCL_P2P_DISABLE'] = '1'\n    os.environ['NCCL_IB_DISABLE'] = '1'\n\n    dist.init_process_group(\"nccl\", rank=rank, world_size=world_size)\n    device = torch.device(f\"cuda:{rank}\")\n    torch.cuda.set_device(device)\n\n    oyun_yolu = '/kaggle/input/competitions/super-resolution-in-video-games/train/hr'\n    lsdir_yolu = '/kaggle/input/datasets/bpwqsdd/lsdir-45474736'\n    textocr_yolu = '/kaggle/input/datasets/robikscube/textocr-text-extraction-from-images-dataset/train_val_images/train_images'\n    ui_yolu = '/kaggle/input/datasets/daudaudinang/ui-elements-detection-dataset/train/images'\n    div2k_yolu = '/kaggle/input/datasets/joe1995/div2k-dataset/DIV2K_train_HR/DIV2K_train_HR'\n\n    folder_infos = []\n    if lsdir_yolu and os.path.exists(lsdir_yolu):\n        folder_infos.append((lsdir_yolu, 1))\n    if textocr_yolu and os.path.exists(textocr_yolu):\n        folder_infos.append((textocr_yolu, 1))\n    if ui_yolu and os.path.exists(ui_yolu):\n        folder_infos.append((ui_yolu, 1))\n    if oyun_yolu and os.path.exists(oyun_yolu):\n        folder_infos.append((oyun_yolu, 1))\n    if div2k_yolu and os.path.exists(div2k_yolu):\n        folder_infos.append((div2k_yolu, 2))\n\n    train_dataset = SuperResDataset(folder_infos, rank=rank, cache_name=\"train_cache.pt\", split=\"train\", val_ratio=0.01)\n    val_dataset = SuperResDataset(folder_infos, rank=rank, cache_name=\"val_cache.pt\", split=\"val\", val_ratio=0.01)\n\n    train_sampler = ResumableDistributedSampler(train_dataset, num_replicas=world_size, rank=rank, shuffle=True)\n\n    batch_size = 64\n    lr = 0.0001\n\n    train_loader = DataLoader(train_dataset, batch_size=batch_size, sampler=train_sampler, num_workers=2, drop_last=True, pin_memory=True, persistent_workers=True, prefetch_factor=2)\n\n    epoch_adim_sayisi = len(train_loader)\n\n    if epoch_adim_sayisi == 0:\n        raise RuntimeError(\n            \"Train loader bos. Dataset boyutunu, GPU sayisini ve batch_size degerini kontrol edin.\"\n        )\n\n    if rank == 0:\n        val_loader = DataLoader(val_dataset, batch_size=8, shuffle=True, num_workers=2, drop_last=False, pin_memory=True, persistent_workers=True)\n    else:\n        val_loader = None\n\n    model = ConditionalUNet().to(device)\n\n\n    baslangic_epoch = 1\n    baslangic_adim = 0\n    epochs = 5000\n    checkpoint_path = 'super_res_model_light.pth'\n\n    checkpoint = None\n    opt_state = None\n    chk_lr = None\n    latent_config = None\n\n    if os.path.exists(checkpoint_path):\n        checkpoint = torch.load(checkpoint_path, map_location='cpu')\n\n        latent_config = checkpoint[\"latent_config\"]\n\n        model.load_state_dict(checkpoint[\"model_state_dict\"])\n\n        del checkpoint[\"model_state_dict\"]\n        gc.collect()\n\n        if checkpoint[\"step\"] != \"END\":\n            baslangic_epoch = checkpoint[\"epoch\"]\n            baslangic_adim = checkpoint[\"step\"] + 1\n        else:\n            baslangic_epoch = checkpoint[\"epoch\"] + 1\n            baslangic_adim = 0\n\n        opt_state = checkpoint[\"optimizer_state_dict\"]\n        chk_lr = checkpoint[\"lr\"]\n\n    if baslangic_adim >= epoch_adim_sayisi:\n        baslangic_epoch += baslangic_adim // epoch_adim_sayisi\n        baslangic_adim %= epoch_adim_sayisi\n\n    ema = EMA(model, decay=0.9999) if rank == 0 else None\n    if checkpoint is not None:\n        if rank == 0:\n            ema.ema_model.load_state_dict(checkpoint[\"ema_state_dict\"])\n            ema.step = int(checkpoint[\"ema_step\"])\n\n            print(\n                f\"[BILGI] EMA agirliklari yuklendi. EMA guncelleme sayisi: {ema.step}\"\n            )\n\n        del checkpoint\n        gc.collect()\n    elif rank == 0:\n        print(\"[BILGI] Yeni egitim basladi, EMA sifirdan olusturuldu.\")\n\n    model = DDP(model, device_ids=[rank], static_graph=True)\n\n    if rank == 0:\n        print(\"[SISTEM] torch.compile etkinlestiriliyor...\")\n    model = torch.compile(model)\n    if rank == 0:\n        print(\n            \"[SISTEM] Compile sarmalayicisi hazir. Derleme ilk forward/backward calismalarinda gerceklesecek; ilk adimlar yavas olabilir.\"\n        )\n\n    optimizer = bnb.optim.AdamW8bit(model.parameters(), lr=lr, eps=1e-5)\n\n    if opt_state is not None:\n        optimizer.load_state_dict(opt_state)\n\n        lr = chk_lr\n        for param_group in optimizer.param_groups:\n            param_group['lr'] = lr\n\n        if rank == 0:\n            print(f\"[BILGI] Checkpoint yuklendi. Epoch {baslangic_epoch}, Adim {baslangic_adim}'den devam ediliyor.\")\n\n        del opt_state\n        gc.collect()\n\n    difuzyon = DiffusionZamanlayici(adim_sayisi=1000, device=device)\n\n    if rank == 0:\n        temp_vae = AutoencoderKL.from_pretrained(\n            \"black-forest-labs/FLUX.1-schnell\",\n            subfolder=\"vae\",\n            token=HF_TOKEN,\n        )\n        del temp_vae\n\n    dist.barrier()\n\n    vae = AutoencoderKL.from_pretrained(\n        \"black-forest-labs/FLUX.1-schnell\",\n        subfolder=\"vae\",\n        token=HF_TOKEN,\n    ).to(device)\n\n    vae.eval()\n    vae.enable_slicing()\n    for param in vae.parameters():\n        param.requires_grad = False\n\n    if latent_config is None:\n        latent_config = {\n            'scaling_factor': float(vae.config.scaling_factor),\n            'shift_factor': float(\n                getattr(vae.config, 'shift_factor', None) or 0.0\n            ),\n            'lr_posterior': 'mode',\n        }\n\n    latent_scale = float(latent_config['scaling_factor'])\n    latent_shift = float(latent_config['shift_factor'])\n\n    if latent_scale <= 0:\n        raise ValueError(\"VAE scaling_factor pozitif olmali.\")\n\n    if latent_config['lr_posterior'] not in ('sample', 'mode'):\n        raise ValueError(\"lr_posterior yalnizca sample veya mode olabilir.\")\n\n    lr_use_mode = latent_config['lr_posterior'] == 'mode'\n\n    if rank == 0:\n        print(\n            f\"[BILGI] VAE latent ayarlari: scale={latent_scale}, \"\n            f\"shift={latent_shift}, LR posterior={latent_config['lr_posterior']}\"\n        )\n\n    torch.cuda.empty_cache()\n\n    if rank == 0:\n        if not os.path.exists(\"egitim_metrikleri.csv\"):\n            with open(\"egitim_metrikleri.csv\", \"w\", encoding=\"utf-8\") as f:\n                f.write(\"Epoch,Adim,LearningRate,TrainLoss,ValLoss,AdimSuresi\\n\")\n        log_file = open(\"egitim_loglari.txt\", \"a\", encoding=\"utf-8\")\n        csv_file = open(\"egitim_metrikleri.csv\", \"a\", encoding=\"utf-8\")\n\n    for epoch in range(baslangic_epoch, epochs + 1):\n        start_step = baslangic_adim if epoch == baslangic_epoch else 0\n\n        train_sampler.set_epoch(epoch)\n        train_sampler.set_start_step(start_step, batch_size)\n\n        model.train()\n\n        epoch_loss = 0.0\n        adim_sayisi = 0\n        log_loss_toplami = 0.0\n        log_adim_sayisi = 0\n\n        for step, (\n            hr_imgs,\n            lr_imgs,\n            edit_masks,\n            task_ids,\n        ) in enumerate(train_loader, start=start_step):\n\n            global_step = (epoch - 1) * epoch_adim_sayisi + step\n\n            if global_step < 1000:\n                lr = 0.0001 * (global_step / 1000.0)\n            elif global_step < 101000:\n                progress = (global_step - 1000) / 100000.0\n                lr = 0.00001 + 0.5 * (0.0001 - 0.00001) * (1.0 + math.cos(math.pi * progress))\n            else:\n                lr = 0.00001\n\n            for param_group in optimizer.param_groups:\n                param_group['lr'] = lr\n\n            adim_baslangic = time.time()\n\n            hr_imgs = hr_imgs.to(device, non_blocking=True)\n            lr_imgs = lr_imgs.to(device, non_blocking=True)\n            edit_masks = edit_masks.to(device, non_blocking=True)\n            task_ids = task_ids.to(device, non_blocking=True)\n\n            b_size = hr_imgs.shape[0]\n\n            with torch.no_grad():\n                hr_latents, lr_latents, latent_masks = latentleri_hazirla(\n                    vae=vae,\n                    hr_imgs=hr_imgs,\n                    condition_imgs=lr_imgs,\n                    pixel_masks=edit_masks,\n                    task_ids=task_ids,\n                    latent_scale=latent_scale,\n                    latent_shift=latent_shift,\n                    lr_use_mode=lr_use_mode,\n                )\n\n\n\n                drop_mask = (\n                    torch.rand(b_size, 1, 1, 1, device=device) < 0.1\n                )\n                lr_latents = lr_latents.masked_fill(drop_mask, 0.0)\n\n            t = torch.randint(0, difuzyon.adim_sayisi, (b_size,), device=device).long()\n            gercek_gurultu = torch.randn_like(hr_latents)\n\n            optimizer.zero_grad(set_to_none=True)\n            x_noisy = difuzyon.gurultu_ekle(hr_latents, t, gercek_gurultu)\n\n            tahmin_edilen_v = model(\n                x_noisy,\n                t,\n                lr_latents,\n                latent_masks,\n                task_ids,\n            )\n\n            alpha_t = difuzyon.alpha_sapka[t].to(device)\n\n            sqrt_alpha_sapka = torch.sqrt(alpha_t)[:, None, None, None]\n            sqrt_bir_eksi_alpha_sapka = torch.sqrt(1.0 - alpha_t)[:, None, None, None]\n            v_hedef = (sqrt_alpha_sapka * gercek_gurultu) - (sqrt_bir_eksi_alpha_sapka * hr_latents)\n\n            loss_v = maskeli_v_loss(\n                tahmin_edilen_v,\n                v_hedef,\n                latent_masks,\n            )\n\n            loss = loss_v\n\n            loss.backward()\n            torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n            optimizer.step()\n            if rank == 0:\n                ema.update(model.module)\n\n            epoch_loss += loss.item()\n            adim_sayisi += 1\n            log_loss_toplami += loss.item()\n            log_adim_sayisi += 1\n\n            if rank == 0 and step % 10 == 0:\n                ortalama_log_loss = log_loss_toplami / log_adim_sayisi\n                adim_suresi = time.time() - adim_baslangic\n                print(f\"Epoch: {epoch} | Adim: {step}/{epoch_adim_sayisi} | Loss: {ortalama_log_loss:.5f} | LR: {lr:.8f} | Sure: {adim_suresi:.3f}s\")\n                log_file.write(f\"Epoch: {epoch} | Adim: {step}/{epoch_adim_sayisi} | Loss: {ortalama_log_loss:.5f} | LR: {lr:.8f}\\n\")\n                csv_file.write(f\"{epoch},{step},{lr},{ortalama_log_loss:.6f},0.0,{adim_suresi:.3f}\\n\")\n                log_file.flush()\n                csv_file.flush()\n                log_loss_toplami = 0.0\n                log_adim_sayisi = 0\n\n            if rank == 0 and step > 0 and step % 100 == 0:\n                gc.collect()\n                torch.cuda.empty_cache()\n                temp_path = checkpoint_path + \".tmp\"\n                model_state = {k: v.cpu() for k, v in model.module.state_dict().items()}\n                ema_state = {k: v.cpu() for k, v in ema.ema_model.state_dict().items()}\n                torch.save({\n                    'epoch': epoch,\n                    'step': step,\n                    'model_state_dict': model_state,\n                    'ema_state_dict': ema_state,\n                    'ema_step': ema.step,\n                    'latent_config': latent_config,\n                    'task_config': {\n                        'names': ['sr', 'inpainting', 'outpainting'],\n                        'mask_one_means': 'generate',\n                        'unet_input_channels': 36,\n                        'masked_condition_posterior': 'mode',\n                    },\n                    'optimizer_state_dict': optimizer.state_dict(),\n                    'lr': lr,\n                }, temp_path)\n                os.replace(temp_path, checkpoint_path)\n                print(f\"[BILGI] Adim {step}: Model ara kaydi olusturuldu.\")\n                del model_state, ema_state\n                gc.collect()\n\n        if adim_sayisi == 0:\n            raise RuntimeError(\n                f\"Epoch {epoch} icinde hic egitim adimi calismadi. \"\n                \"Sampler ve resume konumunu kontrol edin.\"\n            )\n\n        if rank == 0:\n            ortalama_loss = epoch_loss / adim_sayisi\n\n            print(\n                f\"--- Epoch {epoch} Tamamlandi | \"\n                f\"Ortalama Loss: {ortalama_loss:.5f} ---\"\n            )\n\n            print(\n                \"[BILGI] Validation basliyor. \"\n                \"Hata hesabi ve ornek gorseller EMA modeli ile uretilecek.\"\n            )\n\n\n            del hr_imgs, lr_imgs, edit_masks, task_ids\n            del hr_latents, lr_latents, latent_masks\n            del gercek_gurultu, x_noisy, tahmin_edilen_v\n            del v_hedef, loss, loss_v\n\n            gc.collect()\n            torch.cuda.empty_cache()\n\n            ortalama_val_loss = cok_gorevli_validation(\n                model=ema.ema_model,\n                vae=vae,\n                val_loader=val_loader,\n                difuzyon=difuzyon,\n                device=device,\n                latent_scale=latent_scale,\n                latent_shift=latent_shift,\n                lr_use_mode=lr_use_mode,\n                epoch=epoch,\n            )\n\n            print(\n                f\"Validation Loss: {ortalama_val_loss:.5f}\"\n            )\n\n            gc.collect()\n            torch.cuda.empty_cache()\n\n            temp_path = checkpoint_path + \".tmp\"\n\n            model_state = {\n                k: v.cpu()\n                for k, v in model.module.state_dict().items()\n            }\n\n            ema_state = {\n                k: v.cpu()\n                for k, v in ema.ema_model.state_dict().items()\n            }\n\n            torch.save({\n                'epoch': epoch,\n                'step': 'END',\n                'model_state_dict': model_state,\n                'ema_state_dict': ema_state,\n                'ema_step': ema.step,\n                'latent_config': latent_config,\n                'task_config': {\n                    'names': ['sr', 'inpainting', 'outpainting'],\n                    'mask_one_means': 'generate',\n                    'unet_input_channels': 36,\n                    'masked_condition_posterior': 'mode',\n                },\n                'optimizer_state_dict': optimizer.state_dict(),\n                'lr': lr,\n            }, temp_path)\n\n            os.replace(temp_path, checkpoint_path)\n\n            del model_state, ema_state\n            gc.collect()\n\n            csv_file.write(\n                f\"{epoch},END,{lr},{ortalama_loss:.6f},\"\n                f\"{ortalama_val_loss:.6f},0.0\\n\"\n            )\n            csv_file.flush()\n\n        dist.barrier()\n        torch.cuda.empty_cache()\n\n    if rank == 0:\n        log_file.close()\n        csv_file.close()\n    dist.destroy_process_group()\n\nif __name__ == \"__main__\":\n    import sys\n\n\n    if 'ipykernel' in sys.modules:\n        print(\"⚠️ UYARI: Jupyter Notebook algılandı!\")\n        print(\"Çoklu GPU (DDP) eğitiminin Kaggle'da çalışabilmesi için bu kodu bir dosyaya kaydetmelisiniz.\")\n        print(\"-\" * 50)\n        print(\"ADIM 1: Lütfen bu hücrenin EN ÜSTÜNE (ilk satıra) şu komutu ekleyin ve hücreyi çalıştırın:\\n\")\n        print(\"%%writefile egitim.py\\n\")\n        print(\"ADIM 2: Dosya oluştuktan sonra, YENİ BİR HÜCRE açıp şu komutla eğitimi başlatın:\\n\")\n        print(\"!python egitim.py\")\n        print(\"-\" * 50)\n    else:\n        world_size = torch.cuda.device_count()\n        if world_size < 1:\n            print(\"HATA: Sisteminizde GPU bulunamadi!\")\n        else:\n            print(f\"🚀 {world_size} adet GPU tespit edildi. DDP baslatiliyor...\")\n            mp.spawn(train_worker, args=(world_size,), nprocs=world_size, join=True)\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#!cp /kaggle/input/datasets/attaukk/yukkse2/super_res_model_light.pth ./","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install diffusers accelerate\n!pip install bitsandbytes","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!cp \"/kaggle/input/notebooks/attaukk/son-buyyuk/super_res_model_light.pth\" \"./\"\n!ls -lh /kaggle/working/super_res_model_light.pth","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import subprocess\nimport os\nimport time\nimport re\n\n# 1. Eksik modülü otomatik olarak yükle\nprint(\"RangeHTTPServer modülü yükleniyor...\")\nos.system(\"pip -q install RangeHTTPServer\")\n\n# 2. Önce 8000 portunu (eski sunucuyu) zorla kapat\nos.system(\"fuser -k 8000/tcp\")\ntime.sleep(1) # Kapanması için kısa bir süre bekle\n\n# 3. Eğer cloudflared dosyası yoksa indir ve yetki ver\nif not os.path.exists('./cloudflared'):\n    print(\"Cloudflared bulunamadı, indiriliyor...\")\n    os.system(\"wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -O cloudflared\")\n    os.system(\"chmod +x cloudflared\")\n    print(\"Cloudflared indirme tamamlandı.\")\n\n# 4. Arka planda parçalı indirme sunucusunu başlat\nprint(\"Sunucu ve tünel başlatılıyor...\")\nsubprocess.Popen([\"python3\", \"-m\", \"RangeHTTPServer\", \"8000\"], cwd=\"/kaggle/working\")\n\n# 5. Tüneli başlat ve çıktıları görmek için bir dosyaya yazdır\nlog_file = open(\"tunnel_log.txt\", \"w\")\nsubprocess.Popen([\"./cloudflared\", \"tunnel\", \"--url\", \"http://localhost:8000\"], stdout=log_file, stderr=log_file)\n\n# 6. LİNKİ LOGLARA YAZDIRMA KISMI (EKLENEN BÖLÜM)\nprint(\"Cloudflare bağlantısı kuruluyor, lütfen 10 saniye bekleyin...\")\ntime.sleep(10) # Linkin üretilmesi ve dosyaya yazılması için zaman tanıyoruz\n\nprint(\"=\"*50)\ntry:\n    with open(\"tunnel_log.txt\", \"r\") as f:\n        log_icerik = f.read()\n        \n        # Regex (düzenli ifade) ile logların içinden .trycloudflare.com uzantılı linki buluyoruz\n        linkler = re.findall(r\"https://[-a-zA-Z0-9]+\\.trycloudflare\\.com\", log_icerik)\n        \n        if linkler:\n            print(\"🚀 İŞTE BAĞLANTI LİNKİNİZ:\")\n            print(f\">>>  {linkler[0]}  <<<\")\n        else:\n            print(\"Link henüz oluşmamış veya bir hata var. Log dosyasının içeriği:\")\n            print(log_icerik)\nexcept FileNotFoundError:\n    print(\"HATA: tunnel_log.txt dosyası bulunamadı!\")\nprint(\"=\"*50)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python egitim.py","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}