{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"jupytext":{"cell_metadata_filter":"-all","main_language":"python","notebook_metadata_filter":"-all"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":99552,"databundleVersionId":13851420,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":13297012,"sourceType":"datasetVersion","datasetId":8427782},{"sourceId":13297046,"sourceType":"datasetVersion","datasetId":8427808},{"sourceId":13301864,"sourceType":"datasetVersion","datasetId":8428066},{"sourceId":13306362,"sourceType":"datasetVersion","datasetId":8432933},{"sourceId":13312360,"sourceType":"datasetVersion","datasetId":8438912},{"sourceId":13314823,"sourceType":"datasetVersion","datasetId":8435658},{"sourceId":13316992,"sourceType":"datasetVersion","datasetId":8442048},{"sourceId":13325273,"sourceType":"datasetVersion","datasetId":8447826},{"sourceId":13329534,"sourceType":"datasetVersion","datasetId":8450859},{"sourceId":13339052,"sourceType":"datasetVersion","datasetId":8458417},{"sourceId":13342964,"sourceType":"datasetVersion","datasetId":8461223},{"sourceId":13354958,"sourceType":"datasetVersion","datasetId":8470506},{"sourceId":13355659,"sourceType":"datasetVersion","datasetId":8471059},{"sourceId":13370416,"sourceType":"datasetVersion","datasetId":8482207},{"sourceId":13373006,"sourceType":"datasetVersion","datasetId":8484230}],"dockerImageVersionId":31089,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport sys\n\nsys.path.insert(0, '/kaggle/input/timm-1-0-20/timm-1.0.20/')\n\nimport copy\nimport shutil\nfrom collections import defaultdict, Counter\nimport gc\nimport time\n\nimport numpy as np\nimport pandas as pd\nimport polars as pl\nfrom tqdm import tqdm\nfrom glob import glob\n\nimport cv2\nfrom PIL import Image\nimport pydicom\nimport matplotlib.pyplot as plt\n\nimport torch\nfrom torch import nn\nimport timm\n\nimport kaggle_evaluation.rsna_inference_server","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:15:36.874233Z","iopub.execute_input":"2025-10-13T17:15:36.874815Z","iopub.status.idle":"2025-10-13T17:15:51.100263Z","shell.execute_reply.started":"2025-10-13T17:15:36.874787Z","shell.execute_reply":"2025-10-13T17:15:51.09973Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CFG:\n    class crop_config:\n        model_name = \"vit_small_plus_patch16_dinov3.lvd1689m\"\n        N = 48\n        NC = 3\n        image_size = [128, 128]\n\n    class bin_config:\n        model_name = \"maxvit_tiny_tf_384.in1k\"\n        image_size = [384, 384]\n        batch_size = 32","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:15:54.176616Z","iopub.execute_input":"2025-10-13T17:15:54.177271Z","iopub.status.idle":"2025-10-13T17:15:54.181609Z","shell.execute_reply.started":"2025-10-13T17:15:54.177247Z","shell.execute_reply":"2025-10-13T17:15:54.180971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def read_volume(files):\n    dcms = [pydicom.dcmread(file) for file in files]\n    \n    shapes = [(d.Rows, d.Columns) for d in dcms]\n    most_common_shape = Counter(shapes).most_common(1)[0][0]\n    \n    valid_data = []\n    for d, file in zip(dcms, files):\n        if (d.Rows, d.Columns) == most_common_shape:\n            valid_data.append([d, file])\n    \n    if len(valid_data)>1:\n        valid_data.sort(key=lambda x: float(x[0].ImagePositionPatient[2]))\n    \n    #volume = np.stack([dcm.pixel_array for dcm in valid_dcms])\n    \n    #t = time.time()\n    volume = np.stack([dcm[0].pixel_array.astype(np.int32) for dcm in valid_data])\n    \n    if volume.shape[0]==1:\n        volume = volume[0]\n\n    return volume","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:15:55.440098Z","iopub.execute_input":"2025-10-13T17:15:55.440798Z","iopub.status.idle":"2025-10-13T17:15:55.446561Z","shell.execute_reply.started":"2025-10-13T17:15:55.440772Z","shell.execute_reply":"2025-10-13T17:15:55.445749Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Model_crop(nn.Module):\n    def __init__(self, config, pretrained=False):\n        super(Model_crop, self).__init__()\n        \n        self.encoder = timm.create_model(config.model_name, pretrained=pretrained, in_chans=config.NC, global_pool='', num_classes=0)\n        feats = self.encoder.num_features\n        \n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        \n        self.head = nn.Linear(feats*config.N//config.NC, 4)\n        \n    def forward(self, inp):\n        inp = torch.nan_to_num(inp, 0, 0, 0)\n        \n        bs, n, c, h, w = inp.shape\n        \n        inp = inp.reshape(bs*n, c, h, w)\n        features = self.encoder(inp)\n        \n        features = features.mean(1)\n        \n        features = features.reshape(bs, n, -1)\n        features = features.flatten(1,2)\n        \n        logits = self.head(features)\n        \n        logits = logits.sigmoid()\n        \n        logits = torch.nan_to_num(logits, 0, 0, 0)\n        \n        return logits, None\n\nmodel_crop = Model_crop(CFG.crop_config, pretrained=False)\nst = torch.load('/kaggle/input/try5-vit-small-plus-patch16-dinov3-lvd1689m-v7/0_best.pth', map_location=f\"cpu\")\nmodel_crop.eval()\nmodel_crop.cuda()\nmodel_crop.load_state_dict(st, strict=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:15:57.408016Z","iopub.execute_input":"2025-10-13T17:15:57.408286Z","iopub.status.idle":"2025-10-13T17:15:59.139132Z","shell.execute_reply.started":"2025-10-13T17:15:57.408265Z","shell.execute_reply":"2025-10-13T17:15:59.138513Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Model_bin(nn.Module):\n    def __init__(self, config, pretrained=False):\n        super(Model_bin, self).__init__()\n        \n        try:\n            self.encoder = timm.create_model(config.model_name, pretrained=pretrained, in_chans=3, \n                                             img_size=config.image_size, global_pool='avg', num_classes=0)\n        except:\n            self.encoder = timm.create_model(config.model_name, pretrained=pretrained, in_chans=3, \n                                             global_pool='', num_classes=0)\n        \n        feats = self.encoder.num_features\n        \n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        \n        self.head = nn.Linear(feats, 14)\n        \n    def forward(self, inp):\n        inp = torch.nan_to_num(inp, 0, 0, 0)\n        \n        features = self.encoder(inp)\n        \n        if len(features.shape)==3:\n            features = features.mean(1)\n        \n        if len(features.shape)>3:\n            features = self.avgpool(features).flatten(1, 3)\n        \n        logits = self.head(features)\n        \n        logits = torch.nan_to_num(logits, 0, 0, 0)\n        \n        return logits, None\n\npaths = [\n    \"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/0_best.pth\",\n    #\"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/1_best.pth\",\n    #\"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/2_best.pth\",\n    #\"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/3_best.pth\",\n\n    #\"/kaggle/input//maxvit-small-tf-384-in1k-v1/0_best.pth\",\n    #\"/kaggle/input//maxvit-small-tf-384-in1k-v1/1_best.pth\",\n    \"/kaggle/input//maxvit-small-tf-384-in1k-v1/2_best.pth\",\n    #\"/kaggle/input//maxvit-small-tf-384-in1k-v1/3_best.pth\",\n\n    #\"/kaggle/input/maxvit-small-tf-224-in1k-v2/1123_best.pth\",\n    \n    \"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/0_best.pth\",\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/1_best.pth\",\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/2_best.pth\",\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/3_best.pth\",\n\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v4/123_best.pth\",\n    \n    #\"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/0_best.pth\",\n    #\"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/1_best.pth\",\n    \"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/2_best.pth\",\n    #\"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/3_best.pth\",\n]\n\nmodels_bin0 = []\nfor path in paths:\n\n    if 'maxvit-tiny' in path:\n        CFG.bin_config.model_name = \"maxvit_tiny_tf_384.in1k\"\n\n    if 'maxvit-small-tf-384' in path:\n        CFG.bin_config.model_name = \"maxvit_small_tf_384.in1k\"\n\n    if 'maxvit-small-tf-224' in path:\n        CFG.bin_config.model_name = \"maxvit_small_tf_224.in1k\"\n    \n    if 'coat-lite-medium' in path:\n        CFG.bin_config.model_name = \"coat_lite_medium_384.in1k\"\n        \n    model_bin = Model_bin(CFG.bin_config, pretrained=False)\n    \n    st = torch.load(path, map_location=f\"cpu\")\n    print(model_bin.load_state_dict(st, strict=False))\n\n    model_bin.eval()\n    model_bin.cuda()\n    \n    #if torch.cuda.device_count() > 1:\n        #model_bin = nn.DataParallel(model_bin, device_ids=[0,1,])\n\n    #model_bin = torch.compile(model_bin)\n    \n    models_bin0.append(copy.deepcopy(model_bin))\n\npaths = [\n    #\"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/0_best.pth\",\n    \"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/1_best.pth\",\n    #\"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/2_best.pth\",\n    #\"/kaggle/input//maxvit-tiny-tf-384-in1k-v1/3_best.pth\",\n\n    #\"/kaggle/input//maxvit-small-tf-384-in1k-v1/0_best.pth\",\n    #\"/kaggle/input//maxvit-small-tf-384-in1k-v1/1_best.pth\",\n    #\"/kaggle/input//maxvit-small-tf-384-in1k-v1/2_best.pth\",\n    \"/kaggle/input//maxvit-small-tf-384-in1k-v1/3_best.pth\",\n\n    #\"/kaggle/input/maxvit-small-tf-224-in1k-v2/11231123_best.pth\",\n    \n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/0_best.pth\",\n    \"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/1_best.pth\",\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/2_best.pth\",\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v3/3_best.pth\",\n\n    #\"/kaggle/input//try8-coat-lite-medium-384-in1k-v4/123123_best.pth\",\n    \n    #\"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/0_best.pth\",\n    #\"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/1_best.pth\",\n    #\"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/2_best.pth\",\n    \"/kaggle/input/try7-coat-lite-medium-384-in1k-v13/3_best.pth\",\n]\n\nmodels_bin1 = []\nfor path in paths:\n\n    if 'maxvit-tiny' in path:\n        CFG.bin_config.model_name = \"maxvit_tiny_tf_384.in1k\"\n\n    if 'maxvit-small-tf-384' in path:\n        CFG.bin_config.model_name = \"maxvit_small_tf_384.in1k\"\n\n    if 'maxvit-small-tf-224' in path:\n        CFG.bin_config.model_name = \"maxvit_small_tf_224.in1k\"\n    \n    if 'coat-lite-medium' in path:\n        CFG.bin_config.model_name = \"coat_lite_medium_384.in1k\"\n        \n    model_bin = Model_bin(CFG.bin_config, pretrained=False)\n    \n    st = torch.load(path, map_location=f\"cpu\")\n    print(model_bin.load_state_dict(st, strict=False))\n\n    model_bin.eval()\n    model_bin.to('cuda:1')\n    \n    #if torch.cuda.device_count() > 1:\n        #model_bin = nn.DataParallel(model_bin, device_ids=[0,1,])\n\n    #model_bin = torch.compile(model_bin)\n    \n    models_bin1.append(copy.deepcopy(model_bin))\n\nprint(len(models_bin0), len(models_bin1))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:20:06.055639Z","iopub.execute_input":"2025-10-13T17:20:06.055953Z","iopub.status.idle":"2025-10-13T17:20:16.237203Z","shell.execute_reply.started":"2025-10-13T17:20:06.055932Z","shell.execute_reply":"2025-10-13T17:20:16.236342Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def crop_preprocessing(volume, config):\n    \n    volume = volume[np.linspace(0, len(volume)-1, config.N).astype(np.int16)]\n    \n    volume = volume.reshape(config.N//config.NC, config.NC, volume.shape[1], volume.shape[2])\n        \n    volume = torch.as_tensor((volume - volume.min()) / (volume.max() - volume.min())).half()\n    \n    volume = nn.functional.interpolate(volume, config.image_size, mode='bilinear')\n    \n    return volume\n\ndef crop_predict(volume, config):\n    \n    volume = crop_preprocessing(volume, config)\n    volume = volume.unsqueeze(0)\n    \n    #config.volume = volume\n\n    with torch.no_grad():\n\n        volume = volume.cuda()\n        \n        with torch.amp.autocast(device_type='cuda:0', enabled=True):\n            logits, logits_mask = model_crop(volume)\n        outputs = logits.float().detach().cpu().numpy()\n    \n    return outputs[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:20:16.238319Z","iopub.execute_input":"2025-10-13T17:20:16.238563Z","iopub.status.idle":"2025-10-13T17:20:16.244318Z","shell.execute_reply.started":"2025-10-13T17:20:16.238515Z","shell.execute_reply":"2025-10-13T17:20:16.243777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def bin_preprocessing(volume, config):\n    volume = torch.as_tensor(volume).to(torch.float32)\n\n    D = volume.shape[0]\n\n    volume_last = torch.stack([volume[i-2] if i-2>-1 else volume[i] for i in range(D)])\n    volume_next = torch.stack([volume[i+2] if i+2<D else volume[i] for i in range(D)])\n    #volume_next = volume_last #Bug in training, to be corrected further in training\n    \n    volume = torch.stack([volume_last, volume, volume_next], 1)\n\n    d = volume.shape[0]\n    vmin = volume.view(d, -1).min(dim=1).values.view(d, 1, 1, 1)\n    vmax = volume.view(d, -1).max(dim=1).values.view(d, 1, 1, 1)\n    volume = ((volume - vmin) / (vmax - vmin + 1e-8)).half()\n    \n    volume = nn.functional.interpolate(volume, config.image_size, mode='bilinear')\n    \n    return volume\n\ndef bin_predict(volume, config):\n    \n    volume = bin_preprocessing(volume, config)\n    \n    with torch.no_grad():\n        OUTPUTS = []\n        for model in models_bin:\n            \n            outputs = []\n            for i in range(0, volume.shape[0], config.batch_size):\n                start_idx = i\n                end_idx = min(i + config.batch_size, volume.shape[0])\n                batch_images = volume[start_idx:end_idx]\n\n                batch_images = batch_images.cuda().float()\n\n                #print(batch_images.shape, batch_images.dtype, batch_images.mean())\n\n                with torch.cuda.amp.autocast(enabled=True):\n                #with torch.amp.autocast(device_type='cuda', enabled=True):\n                    logits, logits_mask = model(batch_images)\n                    \n                outs = logits.float().sigmoid().detach().cpu().numpy()\n\n                outputs.extend(outs)\n                \n            outputs = np.stack(outputs)\n\n            OUTPUTS.append(outputs)\n        \n        OUTPUTS = np.stack(OUTPUTS).mean(0)\n    \n    return OUTPUTS","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:20:16.245057Z","iopub.execute_input":"2025-10-13T17:20:16.245291Z","iopub.status.idle":"2025-10-13T17:20:16.262407Z","shell.execute_reply.started":"2025-10-13T17:20:16.245269Z","shell.execute_reply":"2025-10-13T17:20:16.26179Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import threading\n\ndef bin_prediction_loop(models, config, gpu, volume, name, results):\n    with torch.no_grad():\n        OUTPUTS = []\n        for model in models:\n            \n            outputs = []\n            for i in range(0, volume.shape[0], config.batch_size):\n                start_idx = i\n                end_idx = min(i + config.batch_size, volume.shape[0])\n                batch_images = volume[start_idx:end_idx]\n\n                batch_images = batch_images.to(f'cuda:{gpu}').float()\n\n                #print(batch_images.shape, batch_images.dtype, batch_images.mean())\n\n                with torch.cuda.amp.autocast(enabled=True):\n                #with torch.amp.autocast(device_type='cuda', enabled=True):\n                    logits, logits_mask = model(batch_images)\n                    \n                outs = logits.float().sigmoid().detach().cpu().numpy()\n\n                outputs.extend(outs)\n                \n            outputs = np.stack(outputs)\n\n            OUTPUTS.append(outputs)\n        \n        OUTPUTS = np.stack(OUTPUTS)\n    \n    results[name] = OUTPUTS\n    return results\n\ndef bin_predict_2gpu(volume, config, models0, models1):\n\n    results = {}\n    volume = bin_preprocessing(volume, config)\n\n    thread_a = threading.Thread(target=bin_prediction_loop, args=(models0, config, 0, volume, 'outputs0', results))\n    thread_b = threading.Thread(target=bin_prediction_loop, args=(models1, config, 1, volume, 'outputs1', results))\n\n    thread_a.start()\n    thread_b.start()\n\n    thread_a.join()\n    thread_b.join()\n\n    prediction = np.concatenate([results['outputs0'], results['outputs1']])\n\n    weights = [0.1, 0.1, 0.15, 0.15,\n               0.1, 0.1, 0.15, 0.15]\n\n    prediction = np.stack([x*w for x, w in zip(prediction, weights)]).sum(0)\n    #prediction = (prediction.mean(0) + prediction.max(0)) / 2\n    \n    return prediction","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:20:16.263819Z","iopub.execute_input":"2025-10-13T17:20:16.264047Z","iopub.status.idle":"2025-10-13T17:20:16.277661Z","shell.execute_reply.started":"2025-10-13T17:20:16.264034Z","shell.execute_reply":"2025-10-13T17:20:16.276986Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ID_COL = 'SeriesInstanceUID'\n\nLABEL_COLS = [\n    'Left Infraclinoid Internal Carotid Artery',\n    'Right Infraclinoid Internal Carotid Artery',\n    'Left Supraclinoid Internal Carotid Artery',\n    'Right Supraclinoid Internal Carotid Artery',\n    'Left Middle Cerebral Artery',\n    'Right Middle Cerebral Artery',\n    'Anterior Communicating Artery',\n    'Left Anterior Cerebral Artery',\n    'Right Anterior Cerebral Artery',\n    'Left Posterior Communicating Artery',\n    'Right Posterior Communicating Artery',\n    'Basilar Tip',\n    'Other Posterior Circulation',\n    'Aneurysm Present',\n]\n\n\ndef predict(series_path: str) -> pl.DataFrame | pd.DataFrame:\n    \n    #series_path = \"/kaggle/input/rsna-intracranial-aneurysm-detection/series/1.2.826.0.1.3680043.8.498.10004044428023505108375152878107656647\"\n    #series_path = \"/kaggle/input/rsna-intracranial-aneurysm-detection/series/1.2.826.0.1.3680043.8.498.10134365079002163886508836892471866754\"\n\n    #if 1:\n    try:\n    \n        series_id = os.path.basename(series_path)\n        #print(series_id)\n        \n        all_filepaths = []\n        for root, _, files in os.walk(series_path):\n            for file in files:\n                if file.endswith('.dcm'):\n                    all_filepaths.append(os.path.join(root, file))\n        all_filepaths.sort()\n\n        volume = read_volume(all_filepaths)\n        #print(volume.shape)\n        \n        x1, x2, y1, y2 = crop_predict(volume, CFG.crop_config)\n        #print(x1, x2, y1, y2)\n        \n        height, width = volume.shape[-2:]\n        volume = volume[:, int(y1*height*0.9):int(y2*height*1.1), int(x1*width*0.9):int(x2*width*1.1)]\n        \n        CFG.volume = volume\n        \n        #predictions = bin_predict(volume, CFG.bin_config)\n        predictions = bin_predict_2gpu(volume, CFG.bin_config, models_bin0, models_bin1)\n        \n        final_pred = predictions.max(0)\n        \n        final_pred = final_pred[1:].tolist() + [final_pred[0]]\n        \n        #print(final_pred)\n        \n        # ... do some machine learning magic ...\n        predictions = pl.DataFrame(\n            data=[[series_id] + final_pred ],\n            schema=[ID_COL, *LABEL_COLS],\n            orient='row',\n        )\n        # ----------------------------------------------------------------------\n    \n        if isinstance(predictions, pl.DataFrame):\n            assert predictions.columns == [ID_COL, *LABEL_COLS]\n        elif isinstance(predictions, pd.DataFrame):\n            assert (predictions.columns == [ID_COL, *LABEL_COLS]).all()\n        else:\n            raise TypeError('The predict function must return a DataFrame')\n\n        #if np.random.random() < 0.5:\n            #print(error_here)\n        \n        return predictions.drop(ID_COL)\n\n    #'''\n    except:\n        conservative_preds = [0.1] * len(LABEL_COLS)\n        predictions = pl.DataFrame(\n            data=[conservative_preds],\n            schema=LABEL_COLS,\n            orient='row'\n        )\n        return predictions\n    \n    finally:\n    #'''\n    #if 1:\n        # ----------------------------- IMPORTANT ------------------------------\n        # You MUST have the following code in your `predict` function\n        # to prevent \"out of disk space\" errors. This is a temporary workaround\n        # as we implement improvements to our evaluation system.\n        shared_dir = '/kaggle/shared'\n        shutil.rmtree(shared_dir, ignore_errors=True)\n        os.makedirs(shared_dir, exist_ok=True)\n        \n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n        gc.collect()\n        # ----------------------------------------------------------------------\n\nshutil.rmtree('/kaggle/shared', ignore_errors=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:20:16.278383Z","iopub.execute_input":"2025-10-13T17:20:16.278648Z","iopub.status.idle":"2025-10-13T17:20:16.294906Z","shell.execute_reply.started":"2025-10-13T17:20:16.278626Z","shell.execute_reply":"2025-10-13T17:20:16.294206Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inference_server = kaggle_evaluation.rsna_inference_server.RSNAInferenceServer(predict)\n\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    t = time.time()\n    inference_server.run_local_gateway()\n    print(f\"Time to run: {time.time() - t}\")\n    display(pl.read_parquet('/kaggle/working/submission.parquet'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-13T17:20:16.295562Z","iopub.execute_input":"2025-10-13T17:20:16.295735Z","iopub.status.idle":"2025-10-13T17:21:31.644932Z","shell.execute_reply.started":"2025-10-13T17:20:16.295721Z","shell.execute_reply":"2025-10-13T17:21:31.644322Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission_df = pl.read_parquet('/kaggle/working/submission.parquet')\ndisplay(submission_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-12T17:51:20.889032Z","iopub.execute_input":"2025-10-12T17:51:20.889309Z","iopub.status.idle":"2025-10-12T17:51:20.895954Z","shell.execute_reply.started":"2025-10-12T17:51:20.889289Z","shell.execute_reply":"2025-10-12T17:51:20.895223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}