{
  "id": 581094,
  "title": "16th place solution - SDXL-Flash + Siglip/AES Reranking + Proxy VQA",
  "content": "<p>First of all, we would like to thank the hosts for their continued effort to improve the metric to ensure that the top solutions aligns with the objectives of the competition!</p>\n<p>Team members:</p>\n<ul>\n<li><a href=\"https://www.kaggle.com/yeoyunsianggeremie\" target=\"_blank\">@yeoyunsianggeremie</a> - solution development and experimentation</li>\n<li><a href=\"https://www.kaggle.com/xyzdivergence\" target=\"_blank\">@xyzdivergence</a> - solution development and experimentation</li>\n<li><a href=\"https://www.kaggle.com/evgeniimaslov2\" target=\"_blank\">@evgeniimaslov2</a> - dataset generation</li>\n</ul>\n<p>Code: <a href=\"https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms\" target=\"_blank\">https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms</a></p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5256933%2F5d143ee1a6e3da4d04cd99c52a51a880%2FScreenshot%202025-06-06%20200646.jpg?generation=1749211619603421&amp;alt=media\" alt=\"\"></p>\n<p>In summary, we allocated 36 seconds for SVG generation and aesthetic scores computation, and the remaining 27 seconds for candidate selection.</p>\n<h1><strong>Image Generation</strong></h1>\n<p>We tried lots of open-sourced SD models (such as Sana, SD 3.5) etc and stuck with <strong>SDXL-Flash</strong> as it was the fastest model which could generate \"nice-looking\" images that met our expectations.</p>\n<p>Using the default settings (1024x1024), SDXL-Flash took 8 seconds to generate an image. However, we improved the speed by up till <strong>80%</strong> by generating images with lower resolution. For 512x512, we were able to generate 18 candidate images within 30 seconds, without compromising much quality. It was validated locally that 512x512 or 640x640 gave the best tradeoff between the speed and accuracy. On the LB, 704x704 did pretty well too but we didn’t select it due to the low validation score.</p>\n<p>Additionally, we used the prompt <code>f'Cartoon style of \"{description}\".'</code> as we noticed that the cover page of the DOODL paper showed an image that appeared to have a cartoon style after aesthetic optimization. When examining the SVG outputs, it was found that there is less quality loss in the conversion process, compared to a normal image.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5256933%2Fa8b2ac2422555b96ea8c5c3b6c9beaf0%2FIMG_8871.jpeg?generation=1748425985094002&amp;alt=media\" alt=\"\"></p>\n<h1><strong>Bitmap to SVG</strong></h1>\n<p>The bitmap_to_svg_layered technique shared publicly took around 4.5 seconds to run per image, and has significant information loss when compressed to 10k bytes.</p>\n<p>When doing function profiling, we noticed that cv2's KMeans was the main culprit. Therefore, we sped it up using NVIDIA's cuML KMeans on GPU, with that, each image was converted to SVG in ~0.3 seconds (<strong>15x speedup</strong>).</p>\n<p>Additionally to squeeze in more elements into 10k bytes, we embedded the following techniques. </p>\n<ul>\n<li>Rounded all coordinates to the nearest integer</li>\n<li>Turned all <code>&lt;polygon&gt;</code> into <code>&lt;path&gt;</code></li>\n<li>Applied colour grouping (embed all paths of the same color within a <code>&lt;g&gt;</code> tag)</li>\n<li>Remove information bytes (in the OCR decoy function)</li>\n<li>Used <a href=\"https://pypi.org/project/scour/\" target=\"_blank\">scour</a> to further trim the size of the final SVG</li>\n</ul>\n<p>This allowed us to fit in 60 -&gt; 168 elements (on average) for an improvement of <strong>280%</strong> without any quality loss compared to the publicly shared function</p>\n<p>The OCR decoy by <a href=\"https://www.kaggle.com/richolson\" target=\"_blank\">@richolson</a> was used to mitigate hallucinations. We did not make any changes since a failure rate of 1/150 is deemed acceptable</p>\n<h1><strong>Candidate Selection</strong></h1>\n<p>To quicken the aesthetic computation locally, we sped up apply_median_filter using cv2 and apply_fft_low_pass in ImageProcessor using NVIDIA CuPy (0.5 -&gt; 0.3 s/image)</p>\n<pre><code> (metric.ImageProcessor):\n\n     ():\n        ().__init__(image, seed)\n\n     ():\n        \n        \n        img_array = np.asarray(.image)\n        \n         size %  == :\n            size += \n        filtered = cv2.medianBlur(img_array, ksize=size)\n        .image = Image.fromarray(filtered)\n         \n\n     ():\n        x = cp.asarray(.image, dtype=cp.float32)      \n        f = cp.fft.fftshift(cp.fft.fft2(x, axes=(,)), axes=(,))\n\n        rows, cols = x.shape[:]\n        crow, ccol = rows // , cols // \n        r = ((crow, ccol) * cutoff_frequency)\n\n        y, xg = cp.ogrid[:rows, :cols]\n        mask = ((y - crow) **  + (xg - ccol) ** ) &lt;= r * r\n        f *= mask[..., ]                              \n\n        img_back = cp.fft.ifft2(cp.fft.ifftshift(f, axes=(,)), axes=(,)).real\n        img_back = cp.clip(img_back, , ).astype(cp.uint8).get()\n        .image = Image.fromarray(img_back)\n         \n</code></pre>\n<p>We estimated the VQA score by asking one question: <code>'Does &lt;image&gt; portray \"{}\"? Answer yes or no.'</code></p>\n<p>Given that</p>\n<table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Time Taken/image</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Aesthetic Score</td>\n<td>0.3s</td>\n</tr>\n<tr>\n<td>VQA + OCR Score</td>\n<td>3s</td>\n</tr>\n</tbody>\n</table>\n<p>Instead of estimating VQA of all images, we employed a reranker approach to estimate which images are more likely to get a higher score on competition metric, which allowed us to generate more candidate SVGs within the time limit. </p>\n<ul>\n<li>We first generated N images (N depends on the image resolution), converted them into SVGs and computed the aesthetic score of all N images, with a time limit of 36 seconds.</li>\n<li>Since aesthetic alone doesn’t tell us how relevant the image is to the prompt, we used the <a href=\"https://huggingface.co/google/siglip-so400m-patch14-384\" target=\"_blank\">siglip</a> model to compute the alignment score between the SVG and the prompt - multiplying them to get a rerank score. This improved the result significantly for 384x384 and 512x512, but not so much for 640x640</li>\n<li>The SVGs were ranked in descending order of the rerank score and VQA/OCR was attempted until the time exceeded 63 seconds (on average, it can run 7 such evaluations). </li>\n<li>The SVG with the highest proxy fidelity score was chosen.</li>\n</ul>\n<h1>Notes</h1>\n<ul>\n<li>We tested our pipeline on our validation set of 500 examples (dataset to be shared later), and found it to be relatively stable on both CV and LB, with scores around 0.705-0.715 on public and 0.700-0.705 on private. The CV was correlating well up till 0.7 LB scores. </li>\n<li>However, there was one submission that stood out (0.717 private, gold zone) and it was just a small change from our selected submission 😢 - the validation and public LB scores was not able to explain that (probably lucky OCR?). EDIT: it probably is a fluke, the resubmission got 0.709</li>\n<li>We did not try vtracer or any other methods to refine the SVG, probably would have done it if there was a few more days.</li>\n<li>We did not try to fine tune any stable diffusion model.</li>\n</ul>\n<h1>Failed Ideas</h1>\n<ul>\n<li>An additional deduplication step using similarity matching</li>\n<li>Training LLM to generate real-time questions during inference</li>\n<li>Adding backgrounds to images with the hope of improving aesthetic score</li>\n<li>Using more complicated reranking techniques without estimating VQA score. Our best public/private score without estimating VQA/OCR is 0.701/0.698 (with 25 candidate images at 512x512 resolution)</li>\n<li>Using 3b PaliGemma model to estimate VQA and OCR</li>\n</ul>",
  "comments": [
    {
      "id": 3217099,
      "author_name": "Geremie Yeo",
      "author_url": "",
      "post_date": "2025-06-04T14:28:28.390000",
      "content": "<h2>Update</h2>\n<p>Our solution has been deployed and is accessible via this URL: <a href=\"https://geremieyeo--text-to-svg-generator-run.modal.run//\" target=\"_blank\">https://geremieyeo--text-to-svg-generator-run.modal.run//</a></p>\n<p>Code: <a href=\"https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms\" target=\"_blank\">https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms</a></p>\n<h2>Note</h2>\n<p>The application uses a 15-minute idle timeout. If no requests are made within 15 minutes, the container automatically shuts down to save resources. When you visit the URL after a period of inactivity, expect approximately 1 minute of waiting time for the container to restart and load.</p>\n<p>The rendering of the bitmap and SVG on the UI takes about 25 seconds after clicking \"Generate SVG\"</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 3214328,
      "author_name": "BeaKaggle",
      "author_url": "",
      "post_date": "2025-05-31T09:34:02.483000",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/yeoyunsianggeremie\" target=\"_blank\">@yeoyunsianggeremie</a> Thank you for sharing. N,ce work.  I was looking at your notebook <a href=\"https://www.kaggle.com/code/yeoyunsianggeremie/fork-of-16th-place-solution-sd-reranker-prox\" target=\"_blank\">https://www.kaggle.com/code/yeoyunsianggeremie/fork-of-16th-place-solution-sd-reranker-prox</a>    Question: can you make the PRIVATE inputs at your notebook public, so that we can try?  Thanks</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3214821,
          "author_name": "Geremie Yeo",
          "author_url": "",
          "post_date": "2025-06-01T06:08:55.203000",
          "content": "<p>done 😀<br>\nfeel free to use the original notebook <a href=\"https://www.kaggle.com/code/yeoyunsianggeremie/16th-place-solution-sd-reranker-proxy-vqa\" target=\"_blank\">here</a> if the forked one has issues </p>",
          "votes": 0,
          "replies": []
        }
      ]
    }
  ],
  "comment_count": 3,
  "messages": [
    {
      "id": 3211317,
      "postDate": "2025-05-28T09:51:02.050Z",
      "content": "<p>First of all, we would like to thank the hosts for their continued effort to improve the metric to ensure that the top solutions aligns with the objectives of the competition!</p>\n<p>Team members:</p>\n<ul>\n<li><a href=\"https://www.kaggle.com/yeoyunsianggeremie\" target=\"_blank\">@yeoyunsianggeremie</a> - solution development and experimentation</li>\n<li><a href=\"https://www.kaggle.com/xyzdivergence\" target=\"_blank\">@xyzdivergence</a> - solution development and experimentation</li>\n<li><a href=\"https://www.kaggle.com/evgeniimaslov2\" target=\"_blank\">@evgeniimaslov2</a> - dataset generation</li>\n</ul>\n<p>Code: <a href=\"https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms\" target=\"_blank\">https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms</a></p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5256933%2F5d143ee1a6e3da4d04cd99c52a51a880%2FScreenshot%202025-06-06%20200646.jpg?generation=1749211619603421&amp;alt=media\" alt=\"\"></p>\n<p>In summary, we allocated 36 seconds for SVG generation and aesthetic scores computation, and the remaining 27 seconds for candidate selection.</p>\n<h1><strong>Image Generation</strong></h1>\n<p>We tried lots of open-sourced SD models (such as Sana, SD 3.5) etc and stuck with <strong>SDXL-Flash</strong> as it was the fastest model which could generate \"nice-looking\" images that met our expectations.</p>\n<p>Using the default settings (1024x1024), SDXL-Flash took 8 seconds to generate an image. However, we improved the speed by up till <strong>80%</strong> by generating images with lower resolution. For 512x512, we were able to generate 18 candidate images within 30 seconds, without compromising much quality. It was validated locally that 512x512 or 640x640 gave the best tradeoff between the speed and accuracy. On the LB, 704x704 did pretty well too but we didn’t select it due to the low validation score.</p>\n<p>Additionally, we used the prompt <code>f'Cartoon style of \"{description}\".'</code> as we noticed that the cover page of the DOODL paper showed an image that appeared to have a cartoon style after aesthetic optimization. When examining the SVG outputs, it was found that there is less quality loss in the conversion process, compared to a normal image.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5256933%2Fa8b2ac2422555b96ea8c5c3b6c9beaf0%2FIMG_8871.jpeg?generation=1748425985094002&amp;alt=media\" alt=\"\"></p>\n<h1><strong>Bitmap to SVG</strong></h1>\n<p>The bitmap_to_svg_layered technique shared publicly took around 4.5 seconds to run per image, and has significant information loss when compressed to 10k bytes.</p>\n<p>When doing function profiling, we noticed that cv2's KMeans was the main culprit. Therefore, we sped it up using NVIDIA's cuML KMeans on GPU, with that, each image was converted to SVG in ~0.3 seconds (<strong>15x speedup</strong>).</p>\n<p>Additionally to squeeze in more elements into 10k bytes, we embedded the following techniques. </p>\n<ul>\n<li>Rounded all coordinates to the nearest integer</li>\n<li>Turned all <code>&lt;polygon&gt;</code> into <code>&lt;path&gt;</code></li>\n<li>Applied colour grouping (embed all paths of the same color within a <code>&lt;g&gt;</code> tag)</li>\n<li>Remove information bytes (in the OCR decoy function)</li>\n<li>Used <a href=\"https://pypi.org/project/scour/\" target=\"_blank\">scour</a> to further trim the size of the final SVG</li>\n</ul>\n<p>This allowed us to fit in 60 -&gt; 168 elements (on average) for an improvement of <strong>280%</strong> without any quality loss compared to the publicly shared function</p>\n<p>The OCR decoy by <a href=\"https://www.kaggle.com/richolson\" target=\"_blank\">@richolson</a> was used to mitigate hallucinations. We did not make any changes since a failure rate of 1/150 is deemed acceptable</p>\n<h1><strong>Candidate Selection</strong></h1>\n<p>To quicken the aesthetic computation locally, we sped up apply_median_filter using cv2 and apply_fft_low_pass in ImageProcessor using NVIDIA CuPy (0.5 -&gt; 0.3 s/image)</p>\n<pre><code> (metric.ImageProcessor):\n\n     ():\n        ().__init__(image, seed)\n\n     ():\n        \n        \n        img_array = np.asarray(.image)\n        \n         size %  == :\n            size += \n        filtered = cv2.medianBlur(img_array, ksize=size)\n        .image = Image.fromarray(filtered)\n         \n\n     ():\n        x = cp.asarray(.image, dtype=cp.float32)      \n        f = cp.fft.fftshift(cp.fft.fft2(x, axes=(,)), axes=(,))\n\n        rows, cols = x.shape[:]\n        crow, ccol = rows // , cols // \n        r = ((crow, ccol) * cutoff_frequency)\n\n        y, xg = cp.ogrid[:rows, :cols]\n        mask = ((y - crow) **  + (xg - ccol) ** ) &lt;= r * r\n        f *= mask[..., ]                              \n\n        img_back = cp.fft.ifft2(cp.fft.ifftshift(f, axes=(,)), axes=(,)).real\n        img_back = cp.clip(img_back, , ).astype(cp.uint8).get()\n        .image = Image.fromarray(img_back)\n         \n</code></pre>\n<p>We estimated the VQA score by asking one question: <code>'Does &lt;image&gt; portray \"{}\"? Answer yes or no.'</code></p>\n<p>Given that</p>\n<table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Time Taken/image</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Aesthetic Score</td>\n<td>0.3s</td>\n</tr>\n<tr>\n<td>VQA + OCR Score</td>\n<td>3s</td>\n</tr>\n</tbody>\n</table>\n<p>Instead of estimating VQA of all images, we employed a reranker approach to estimate which images are more likely to get a higher score on competition metric, which allowed us to generate more candidate SVGs within the time limit. </p>\n<ul>\n<li>We first generated N images (N depends on the image resolution), converted them into SVGs and computed the aesthetic score of all N images, with a time limit of 36 seconds.</li>\n<li>Since aesthetic alone doesn’t tell us how relevant the image is to the prompt, we used the <a href=\"https://huggingface.co/google/siglip-so400m-patch14-384\" target=\"_blank\">siglip</a> model to compute the alignment score between the SVG and the prompt - multiplying them to get a rerank score. This improved the result significantly for 384x384 and 512x512, but not so much for 640x640</li>\n<li>The SVGs were ranked in descending order of the rerank score and VQA/OCR was attempted until the time exceeded 63 seconds (on average, it can run 7 such evaluations). </li>\n<li>The SVG with the highest proxy fidelity score was chosen.</li>\n</ul>\n<h1>Notes</h1>\n<ul>\n<li>We tested our pipeline on our validation set of 500 examples (dataset to be shared later), and found it to be relatively stable on both CV and LB, with scores around 0.705-0.715 on public and 0.700-0.705 on private. The CV was correlating well up till 0.7 LB scores. </li>\n<li>However, there was one submission that stood out (0.717 private, gold zone) and it was just a small change from our selected submission 😢 - the validation and public LB scores was not able to explain that (probably lucky OCR?). EDIT: it probably is a fluke, the resubmission got 0.709</li>\n<li>We did not try vtracer or any other methods to refine the SVG, probably would have done it if there was a few more days.</li>\n<li>We did not try to fine tune any stable diffusion model.</li>\n</ul>\n<h1>Failed Ideas</h1>\n<ul>\n<li>An additional deduplication step using similarity matching</li>\n<li>Training LLM to generate real-time questions during inference</li>\n<li>Adding backgrounds to images with the hope of improving aesthetic score</li>\n<li>Using more complicated reranking techniques without estimating VQA score. Our best public/private score without estimating VQA/OCR is 0.701/0.698 (with 25 candidate images at 512x512 resolution)</li>\n<li>Using 3b PaliGemma model to estimate VQA and OCR</li>\n</ul>",
      "rawMarkdown": "First of all, we would like to thank the hosts for their continued effort to improve the metric to ensure that the top solutions aligns with the objectives of the competition!\n\nTeam members:\n- @yeoyunsianggeremie - solution development and experimentation\n- @xyzdivergence - solution development and experimentation\n- @evgeniimaslov2 - dataset generation\n\nCode: https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5256933%2F5d143ee1a6e3da4d04cd99c52a51a880%2FScreenshot%202025-06-06%20200646.jpg?generation=1749211619603421&alt=media)\n\nIn summary, we allocated 36 seconds for SVG generation and aesthetic scores computation, and the remaining 27 seconds for candidate selection.\n\n**Image Generation**\n===========\nWe tried lots of open-sourced SD models (such as Sana, SD 3.5) etc and stuck with **SDXL-Flash** as it was the fastest model which could generate \"nice-looking\" images that met our expectations.\n\nUsing the default settings (1024x1024), SDXL-Flash took 8 seconds to generate an image. However, we improved the speed by up till **80%** by generating images with lower resolution. For 512x512, we were able to generate 18 candidate images within 30 seconds, without compromising much quality. It was validated locally that 512x512 or 640x640 gave the best tradeoff between the speed and accuracy. On the LB, 704x704 did pretty well too but we didn’t select it due to the low validation score.\n\nAdditionally, we used the prompt ```f'Cartoon style of \"{description}\".'``` as we noticed that the cover page of the DOODL paper showed an image that appeared to have a cartoon style after aesthetic optimization. When examining the SVG outputs, it was found that there is less quality loss in the conversion process, compared to a normal image.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F5256933%2Fa8b2ac2422555b96ea8c5c3b6c9beaf0%2FIMG_8871.jpeg?generation=1748425985094002&alt=media)\n\n**Bitmap to SVG**\n==========\nThe bitmap_to_svg_layered technique shared publicly took around 4.5 seconds to run per image, and has significant information loss when compressed to 10k bytes.\n\nWhen doing function profiling, we noticed that cv2's KMeans was the main culprit. Therefore, we sped it up using NVIDIA's cuML KMeans on GPU, with that, each image was converted to SVG in ~0.3 seconds (**15x speedup**).\n\nAdditionally to squeeze in more elements into 10k bytes, we embedded the following techniques. \n- Rounded all coordinates to the nearest integer\n- Turned all ```<polygon>``` into ```<path>```\n- Applied colour grouping (embed all paths of the same color within a ```<g>``` tag)\n- Remove information bytes (in the OCR decoy function)\n- Used [scour](https://pypi.org/project/scour/) to further trim the size of the final SVG\n\nThis allowed us to fit in 60 -> 168 elements (on average) for an improvement of **280%** without any quality loss compared to the publicly shared function\n\nThe OCR decoy by @richolson was used to mitigate hallucinations. We did not make any changes since a failure rate of 1/150 is deemed acceptable\n\n**Candidate Selection**\n==================\nTo quicken the aesthetic computation locally, we sped up apply_median_filter using cv2 and apply_fft_low_pass in ImageProcessor using NVIDIA CuPy (0.5 -> 0.3 s/image)\n\n```py\nclass FasterImageProcessor(metric.ImageProcessor):\n\n    def __init__(self, image: Image.Image, seed=None):\n        super().__init__(image, seed)\n\n    def apply_median_filter(self, size=9):\n        \"\"\"Fast median filter using OpenCV (≈10-20× PIL speed).\"\"\"\n        # Pillow → NumPy (BGR order is okay; cv2 works on uint8 directly)\n        img_array = np.asarray(self.image)\n        # OpenCV expects odd kernel sizes ≥3\n        if size % 2 == 0:\n            size += 1\n        filtered = cv2.medianBlur(img_array, ksize=size)\n        self.image = Image.fromarray(filtered)\n        return self\n\n    def apply_fft_low_pass(self, cutoff_frequency=0.5, device=0):\n        x = cp.asarray(self.image, dtype=cp.float32)      # H×W×3\n        f = cp.fft.fftshift(cp.fft.fft2(x, axes=(0,1)), axes=(0,1))\n    \n        rows, cols = x.shape[:2]\n        crow, ccol = rows // 2, cols // 2\n        r = int(min(crow, ccol) * cutoff_frequency)\n    \n        y, xg = cp.ogrid[:rows, :cols]\n        mask = ((y - crow) ** 2 + (xg - ccol) ** 2) <= r * r\n        f *= mask[..., None]                              # broadcast over channels\n    \n        img_back = cp.fft.ifft2(cp.fft.ifftshift(f, axes=(0,1)), axes=(0,1)).real\n        img_back = cp.clip(img_back, 0, 255).astype(cp.uint8).get()\n        self.image = Image.fromarray(img_back)\n        return self\n```\n\nWe estimated the VQA score by asking one question: ``` 'Does <image> portray \"{}\"? Answer yes or no.' ```\n\nGiven that\n| Method | Time Taken/image |\n| --- | --- |\n| Aesthetic Score | 0.3s |\n| VQA + OCR Score| 3s |\n\nInstead of estimating VQA of all images, we employed a reranker approach to estimate which images are more likely to get a higher score on competition metric, which allowed us to generate more candidate SVGs within the time limit. \n\n- We first generated N images (N depends on the image resolution), converted them into SVGs and computed the aesthetic score of all N images, with a time limit of 36 seconds.\n- Since aesthetic alone doesn’t tell us how relevant the image is to the prompt, we used the [siglip](https://huggingface.co/google/siglip-so400m-patch14-384) model to compute the alignment score between the SVG and the prompt - multiplying them to get a rerank score. This improved the result significantly for 384x384 and 512x512, but not so much for 640x640\n- The SVGs were ranked in descending order of the rerank score and VQA/OCR was attempted until the time exceeded 63 seconds (on average, it can run 7 such evaluations). \n- The SVG with the highest proxy fidelity score was chosen.\n\nNotes\n==========\n- We tested our pipeline on our validation set of 500 examples (dataset to be shared later), and found it to be relatively stable on both CV and LB, with scores around 0.705-0.715 on public and 0.700-0.705 on private. The CV was correlating well up till 0.7 LB scores. \n- However, there was one submission that stood out (0.717 private, gold zone) and it was just a small change from our selected submission 😢 - the validation and public LB scores was not able to explain that (probably lucky OCR?). EDIT: it probably is a fluke, the resubmission got 0.709\n- We did not try vtracer or any other methods to refine the SVG, probably would have done it if there was a few more days.\n- We did not try to fine tune any stable diffusion model.\n\nFailed Ideas\n===============\n- An additional deduplication step using similarity matching\n- Training LLM to generate real-time questions during inference\n- Adding backgrounds to images with the hope of improving aesthetic score\n- Using more complicated reranking techniques without estimating VQA score. Our best public/private score without estimating VQA/OCR is 0.701/0.698 (with 25 candidate images at 512x512 resolution)\n- Using 3b PaliGemma model to estimate VQA and OCR",
      "votes": 13
    },
    {
      "id": 3217099,
      "postDate": "2025-06-04T14:28:28.390Z",
      "content": "<h2>Update</h2>\n<p>Our solution has been deployed and is accessible via this URL: <a href=\"https://geremieyeo--text-to-svg-generator-run.modal.run//\" target=\"_blank\">https://geremieyeo--text-to-svg-generator-run.modal.run//</a></p>\n<p>Code: <a href=\"https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms\" target=\"_blank\">https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms</a></p>\n<h2>Note</h2>\n<p>The application uses a 15-minute idle timeout. If no requests are made within 15 minutes, the container automatically shuts down to save resources. When you visit the URL after a period of inactivity, expect approximately 1 minute of waiting time for the container to restart and load.</p>\n<p>The rendering of the bitmap and SVG on the UI takes about 25 seconds after clicking \"Generate SVG\"</p>",
      "rawMarkdown": "Update\n--------------------\n\nOur solution has been deployed and is accessible via this URL: https://geremieyeo--text-to-svg-generator-run.modal.run//\n\nCode: https://github.com/bogoconic1/16th-place-kaggle-drawing-with-llms\n\nNote\n--------------------\n\nThe application uses a 15-minute idle timeout. If no requests are made within 15 minutes, the container automatically shuts down to save resources. When you visit the URL after a period of inactivity, expect approximately 1 minute of waiting time for the container to restart and load.\n\nThe rendering of the bitmap and SVG on the UI takes about 25 seconds after clicking \"Generate SVG\"",
      "votes": 1
    },
    {
      "id": 3214328,
      "postDate": "2025-05-31T09:34:02.483Z",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/yeoyunsianggeremie\" target=\"_blank\">@yeoyunsianggeremie</a> Thank you for sharing. N,ce work.  I was looking at your notebook <a href=\"https://www.kaggle.com/code/yeoyunsianggeremie/fork-of-16th-place-solution-sd-reranker-prox\" target=\"_blank\">https://www.kaggle.com/code/yeoyunsianggeremie/fork-of-16th-place-solution-sd-reranker-prox</a>    Question: can you make the PRIVATE inputs at your notebook public, so that we can try?  Thanks</p>",
      "rawMarkdown": "Hi @yeoyunsianggeremie Thank you for sharing. N,ce work.  I was looking at your notebook https://www.kaggle.com/code/yeoyunsianggeremie/fork-of-16th-place-solution-sd-reranker-prox    Question: can you make the PRIVATE inputs at your notebook public, so that we can try?  Thanks",
      "replies": [
        {
          "id": 3214821,
          "postDate": "2025-06-01T06:08:55.203Z",
          "content": "<p>done 😀<br>\nfeel free to use the original notebook <a href=\"https://www.kaggle.com/code/yeoyunsianggeremie/16th-place-solution-sd-reranker-proxy-vqa\" target=\"_blank\">here</a> if the forked one has issues </p>",
          "rawMarkdown": "done 😀\nfeel free to use the original notebook [here](https://www.kaggle.com/code/yeoyunsianggeremie/16th-place-solution-sd-reranker-proxy-vqa) if the forked one has issues "
        }
      ]
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-20T09:09:51Z",
  "competition_id": 89659,
  "competition_slug": "drawing-with-llms",
  "team_id": 13410565,
  "solution_url": "/competitions/drawing-with-llms/writeups/coconut-tree-on-an-island-16th-place-solution-sdxl"
}