{
  "id": 572948,
  "title": "2nd place solution (Team imagination-research)",
  "content": "<ul>\n<li><strong>Repository</strong>: <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\">https://github.com/imagination-research/aimo2</a></li>\n<li><strong>Models</strong>:<br>\n<a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4\" target=\"_blank\">https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4</a><br>\n<a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2\" target=\"_blank\">https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2</a><br>\n<a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft\" target=\"_blank\">https://huggingface.co/imagination-research/deepseek-14b-sft</a></li>\n<li><strong>Notebook</strong>: <a href=\"https://www.kaggle.com/code/youyc22/imagination-research-2nd-place-solution/\" target=\"_blank\">https://www.kaggle.com/code/youyc22/imagination-research-2nd-place-solution/</a><br>\nThanks to Aimo and Kaggle for hosting this great competition. We are also grateful to all the competitors during the competition and all the open source projects for sharing their great ideas. Now it's time to share our ideas and experiences with the community!<br>\nOur solution gets the 2nd place. It gets <strong>34/50</strong> on the public leaderboard (ranked <strong>1st</strong>), and <strong>31/50</strong> (ranked <strong>2nd</strong>) on the private leaderboard. </li>\n</ul>\n<h2>Solution Summary</h2>\n<p>This competition required optimizing both efficiency and reasoning performance. Our final solution consists of three main parts:</p>\n<ul>\n<li>Part I: <strong>Reasoning-Oriented Training</strong> -- <em>Improve the model's reasoning ability</em>: Stage 1 - SFT and Stage 2 - DPO with selected data.</li>\n<li>Part II: <strong>Efficiency Optimization</strong> -- <em>Improve inference efficiency</em>: Selecting a suitable inference engine, weight quantization, and KV cache quantization.</li>\n<li>Part III: <strong>Inference-Time Strategies</strong> -- <em>Improve efficiency-reasoning performance trade-off</em>: Prompt design, self-consistency aggregation, sample-level/question-level early stopping, and some heuristic hyperparameter adjusting.<br>\nFor local validation, we used the AIME 2025 test set (30 problems) along with the reference set (10 problems), evaluating both average sample accuracy and aggregated accuracy (via self-consistency) to obtain preliminary judgments of our trial solutions.</li>\n</ul>\n<h2>Part I: Reasoning-Oriented Training</h2>\n<p>Our training scripts are based on <a href=\"https://github.com/Qihoo360/Light-R1\" target=\"_blank\"><code>Light-R1</code></a> project, we are really grateful to their work.</p>\n<h3>Stage1: SFT</h3>\n<p>We choose <a href=\"https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-14B\" target=\"_blank\"><code>DeepSeek-R1-Distill-Qwen-14B</code></a> as the base model considering its great performance in mathematics, coding and reasoning.<br>\nWe combine the stage2 data from <a href=\"https://huggingface.co/datasets/qihoo360/Light-R1-SFTData\" target=\"_blank\"><code>Light-R1</code></a> and training data from <a href=\"https://huggingface.co/datasets/GAIR/LIMO\" target=\"_blank\"><code>Limo</code></a> together (duplicates removed), which are both high-difficulty math problems' reasoning trajectories generated from deepseek-r1<br>\nWe finetune the base model for 8 epochs on single 8×A800 machine, taking 11 hours:<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F641a0798dbca8be9adbf1b010cb49159%2F2e6707889efebafd252bd2ad0443d232.png?generation=1744460831585737&amp;alt=media\" alt=\"\"><br>\nThe accuracy improves but the output length also improves significantly.</p>\n<h3>Stage2: DPO</h3>\n<p>We use DPO to reduce the output length of the model<br>\nWe choose the default subset of <a href=\"https://huggingface.co/datasets/open-r1/OpenR1-Math-220k/tree/main/data\" target=\"_blank\"><code>OpenR1-Math-220k</code></a> to build our dataset<br>\nSpecifically, we try to use the following four criteria to construct DPO pairs (y_w, y_l means chosen response and rejected response):</p>\n<ul>\n<li><strong>Correctness</strong>: y_w must be correct, y_l may be correct or incorrect</li>\n<li><strong>Length ratio</strong>:  len(y_w) &lt; ratio_threshold * len(y_l)</li>\n<li><strong>Min Length</strong>: len(y_w) &gt; min_threshold</li>\n<li><strong>Similarity</strong>: sim(y_w,y_l) &lt; sim_threshold</li>\n<li>use sentence transformer model to calculate embeddings<br>\nApplying the first three criteria, we construct the dataset dpo-1, which is used to train the models we submit.<br>\nApplying the four criteria, we construct the dataset dpo-2, which is used to train another model, but its performance is similar to the model we submit.<br>\nWe use <a href=\"https://github.com/Qihoo360/360-LLaMA-Factory/tree/adfd1708b94a921637c3821bca4a6dd3d81d0387\" target=\"_blank\"><code>360-LLaMA-Factory</code></a> because they add sequence parallelism (SP) technology to support longer context training with limited memory.<br>\nWe use a single 8×A800 machine to train for 4 epochs on dpo-1 dataset(2k pairs), taking 40 hours.<br>\nFrom the above process, we get two models we finally submitted:<br>\n<strong><a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2\" target=\"_blank\"><code>deepseek-14b-sft-dpo2</code></a></strong> and <strong><a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4\" target=\"_blank\"><code>deepseek-14b-sft-dpo4</code></a></strong><br>\nAll our training data can be found here:<br>\n<strong><a href=\"https://huggingface.co/datasets/imagination-research/aimo2-datasets\" target=\"_blank\"><code>training data</code></a></strong><br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fb0a29a66664d9236e04b532fbc0e03c8%2F7187e4e6d0daeae809ac6559ffa3b103.png?generation=1744460986607785&amp;alt=media\" alt=\"\"><br>\n<strong><em>Note: in the above table, we sample 32 times (direct reasoning 16 times and code solving 16 times) for each question. Pass@1 is computed on AIME 2025 dataset. More details on our inference method are discussed later.</em></strong></li>\n</ul>\n<h2>Part II: Efficiency Optimization</h2>\n<h3>Inference Engine</h3>\n<p>We choose <a href=\"https://github.com/InternLM/lmdeploy\" target=\"_blank\"><code>lmdeploy</code></a> as the LLM inference framework. Compared with <code>vllm</code>, the <code>lmdeploy</code> framework with the TurboMind engine can provide higher throughput and shorter model initialization time.<br>\nThe lmdeploy version we use is  0.7.0.post1<br>\nThe first picture comes from <a href=\"https://github.com/InternLM/lmdeploy\" target=\"_blank\"><code>here</code></a><br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F5e8c198ab84475ca77c1b8b27adfcdd9%2F5f126916d91bb2519cb69dd4b3256ef3.png?generation=1744461014286477&amp;alt=media\" alt=\"\"></p>\n<h3>Quantization</h3>\n<p>We apply 4-bit AWQ weight quantization, and 8-bit KV Cache quantization (setting the configuration <code>main_model.inference_cfg.quant_policy</code> to 8 to use 8-bit KV Cache quantization implemented by <code>lmdeploy</code>).<br>\nOur two models for submissions can be found here: <a href=\"https://www.kaggle.com/models/youyc22/dpsk-14b-sft-dpo-3-16-awq-tb/Keras/default\" target=\"_blank\">model1</a>, <a href=\"https://www.kaggle.com/models/youyc22/dpsk-14b-sft-dpo-3-13-awq-tb/Keras/default\" target=\"_blank\">model2</a><br>\n<strong>Some efficiency results</strong>:</p>\n<ul>\n<li>Online test (4xL4, batch size=15): W4KV8 decreases the time per output token by about 20% compared with W4KV16, 55% compared with FP16.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F1f2074a4fa450da09049e99f3d97f2ab%2Fc1af1024b94a2d7511b234b44df1ab6e.png?generation=1744461043302217&amp;alt=media\" alt=\"\"></li>\n<li>Local test (2xA800, batch size=32): W4KV8, W4KV16 decreases the overall latency by 40% and 20%-25% compared with FP16, respectively.<br>\n<strong>Some reasoning performance results</strong>:</li>\n<li>Local test: The average sample accuracy (not aggregated accuracy) drops by 5%~10%, compared with FP16; W4KV8 is not worse than W4KV16. W4KV4 is worse.</li>\n</ul>\n<h2>Part III: Inference-Time Strategies</h2>\n<h3>Overall Inference Workflow</h3>\n<p>The inference workflow is shown in the figure below: A question is provided as the input. We first prepare two types of prompts, including the CoT prompt and the Code prompt (\"Prompt Preparation Task\"). Then, we let the LLM start batchify generation of multiple samples with <code>lmdeploy</code> (\"LLM Generation Task\"). In the mean time, we continuouly try extract the answer from the streaming output of each sample, aggregate the answers of multiple samples, and judge whether to early stop some generation:</p>\n<ol>\n<li>We do sample-level checking upon every N yields from the iterator got by the <code>stream_infer(...)</code> call, and judge whether to early stop the generation of the corresponding sample. The Python code executor and answer extractor components are used here.</li>\n<li>We do question-level checking upon the end of every sample, and judge whether to early stop the generation of all remaining samples of the current question. The answer aggregator component is used here.<br>\nFinally, we return the aggregated answer.<br>\nNote that, for each question, we adjust the speed-related hyperparameters (number of samples, sampling-level max time, question-level early-stop criterion) according to the remaining time, so that the time quota can be allocated in a more balanced way across the remaining questions when the remaining time is limited.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fef0d82c4b38753bb20a279e0f9c84148%2F4ff9e80d8347169f359c9f8a32a7331b.png?generation=1744461072712397&amp;alt=media\" alt=\"\"></li>\n</ol>\n<h3>Prompt Preparation</h3>\n<p><strong>Method</strong>:</p>\n<ul>\n<li>Initially, we use 15 samples for one question, and aggregate their answers by self-consistency.</li>\n<li>Note that we don't necessarily aggregate the answers of all samples, see <a href=\"#question-level-answer-aggregation--early-stopping\">discussions below</a> for more details.</li>\n<li>Note that we decrease the number of samples when there is limited time left, see <a href=\"#speed-hyperparameter-adjusting\">discussions below</a> for more details.</li>\n<li>We use the commonly used code-based reasoning: (1) Prompt the model to provide Python code to solve the problem; (2) Extract Python code from the output, create a subprocess to execute the code; (3) Extract the answer from the execution results.</li>\n<li>We use two types of prompts - a CoT prompt and a Code prompt. Among 15 samples, 7 samples use the CoT prompt and 8 samples use the Code prompt:</li>\n</ul>\n<pre><code>\n  \n \n\n  \n \n</code></pre>\n<p><strong>Some experiments</strong>:</p>\n<p></p><ul><br>\n<li>System prompt choice: We find diversifying the system prompt doesn't help for reasoning models.</li><br>\n<li>Prompt list choice: In the local test, we find only using our Code prompt result in a consistent (across seed and models) and small improvements than using half CoT and half code prompts. However, when we submit this (only once), it doesn't help with the public submission score, thus, we don't further test this empirical choice.</li><br>\n<li>Number of samples: In the local test, we find that using 32 samples achieve better results than using 16 samples. However, due to the limited computing power on the submission platform and limited submission quota, we do not thoroughly experiment with more samples on the submission platform to find a sweet point -- we just go with 15 samples.</li><br>\n<li>How frequently the code prompt lead to code output, code error, wrong answer (32 samples, 16 CoT Prompts, 16 Code Prompts):</li><br>\n<li>Cases where the code runs correctly but we cannot parse an integer from its output are rare and can be ignored.</li><br>\n<li><strong>Before fine-tuning</strong>, the model is more inclined to output code: on average, in only 1.9 or 3.3 out of 16 cases where a code prompt is used, the model does not output code.</li><br>\n<li><strong>After our fine-tuning</strong> with only math data, the model becomes less inclined to output code: on average, in about 11 out of 16 cases, the code prompt does not cause the model to output code. When the new model does output code, its conditional accuracy is slightly higher than the pre-fine-tuning model (45% and 55% vs. 42%).<br><p></p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Quantization</th>\n<th>Total solving time</th>\n<th>Avg outlen</th>\n<th>Aggregated correct questions (/30)</th>\n<th>Average correct samples (/32)</th>\n<th>Code error break down (/16)</th>\n<th><br></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dpsk-qwen-14b</td>\n<td>KV16</td>\n<td>11838.22</td>\n<td>9776.94</td>\n<td>20.00</td>\n<td>14.63</td>\n<td>No code: 1.93; Exec error: 2.97; Fail parseint: 0.13; Wrong number: 5.30</td>\n<td><br></td>\n</tr>\n<tr>\n<td>dpsk-qwen-14b-awq</td>\n<td>AWQ4 KV8</td>\n<td>6844.75</td>\n<td>10118.54</td>\n<td>21.00</td>\n<td>14.40</td>\n<td>No code: 3.30; Exec error: 2.53; Fail parseint: 0.33; Wrong number: 4.57</td>\n<td><br></td>\n</tr>\n<tr>\n<td>dpsk-qwen-14b-finetune-v1-epoch4</td>\n<td>KV16</td>\n<td>12971.18</td>\n<td>11151.10</td>\n<td>21.00</td>\n<td>18.90</td>\n<td>No code: 11.00; Exec error: 0.83; Fail parseint: 0.03; Wrong number: 1.43</td>\n<td><br></td>\n</tr>\n<tr>\n<td>dpsk-qwen-14b-finetune-v1-epoch4-awq</td>\n<td>AWQ4 KV8</td>\n<td>7963.94</td>\n<td>11557.06</td>\n<td>21.00</td>\n<td>16.80</td>\n<td>No code: 11.07; Exec error: 1.30; Fail parseint: 0.03; Wrong number: 0.90</td>\n<td></td></tr></tbody></table></li>\n\n\n</ul>\n\n\n\n\n\n\n\n\n\n<h3>Sample-level Answer Extraction &amp; Early Stopping</h3>\n\n\n\n\n\n\n\n\n\n\n<p><strong>Motivation</strong>: Usually, the reasoning model will self-doubt a lot after obtaining the answer early, even if it usually gives out the same answer finally. And in most cases, after giving the answer between <code>&lt;think&gt;&lt;/think&gt;</code>, the model will rewrite the solution again (at least twice). Can we reduce the wasting of tokens?<br>\n<strong>Method</strong>: Although we experimented with the active probing method from \"Fu et al., \"Efficiently Serving LLM Reasoning Programs with Certaindex, arXiv 2412\", we ultimately adopted a much simpler sample-level early stopping technique to simplify our inference workflow. Specifically, once we detect either the first successfully executable code or the first answer in \"\\boxed{…}\", we stop the generation process for that sample.<br>\n<strong>Some experiments</strong>: A natural question is whether this might harm the potential to revise an initially incorrect answer into a correct one later. In our local tests, we use <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\"><code>scripts/analyze_early_stop.py</code></a> to verify that such cases are relatively rare, as shown in the figure below.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fe0046e83f954d42e3133ea88947b4b89%2Fdc372cc270acc1d5dc01f37c533e0bc8.png?generation=1744461139162863&amp;alt=media\" alt=\"\"></p>\n<h3>Question-level Answer Aggregation &amp; Early Stopping</h3>\n<p>We use the commonly used self-consistency method for answer aggregation. We use a question-level early-stop strategy as follows.<br>\n<strong>Motivation</strong>: The difficulty varies across problems, so we aim to avoid spending too much time on easy ones. As shown in the figure below, the output length varies considerably across samples for a single problem. This suggests that for some problems, we may obtain several correct answers early on but still need to wait for the longest sample to finish -- resulting in significant time waste (e.g., q1, q11, q16–q20, etc.).<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Ff42ad387359f025fcd84406d2522fc07%2F4856497485f90b1ee37ee3d907f90419.png?generation=1744461161694426&amp;alt=media\" alt=\"\"><br>\n<strong>Method</strong>: We can stop generation early for a question if sufficient certainty is achieved by examining the existing answers. Specifically, we terminate generation at the question level when a majority of the outputs are consistent, e.g., if 5 out of 7 answers agree. See the configurations in <code>early_stop_strategy.consistency_rules</code> in <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\"><code>imagination_aimo2/local_eval_kaggle.py</code></a>.</p>\n<h3>Speed Hyperparameter Adjusting</h3>\n<p><strong>Motivation</strong>: The time to solve questions of different difficulty levels varies greatly, we design a <code>adjust_speed</code> module to dynamically adjust some hyperparameters.<br>\n<strong>Method</strong>: As reasoning progresses, our <code>adjust_speed</code> module calculates the remaining time and number of remaining questions, and dynamically adjusts the model's sampling number and early stopping strategy accordingly.<br>\nFor example, the default speed is <code>3(normal)</code>, if the system detects that the average remaining time for each question is less than 5 minutes, it automatically adjust the speed to <code>1(fastest)</code> .This means the number of samples is decreased to 10 and the maximum reasoning time for each question is also decreased. Please refer to our code for detailed implementation.</p>\n<h2>Other methods we tried but did not reach a conclusion and include in our final solution</h2>\n<ul>\n<li>GRPO: we tried four training runs but did not observe significant improvement on accuracy.</li>\n<li>RAG: we use this <a href=\"https://www.kaggle.com/datasets/artemgoncarov/math-problems-imo\" target=\"_blank\">dataset</a> as a document bank. When solving a question, we fetch 1~2 most similar questions from the bank, use them and their corresponding solutions as the few-shot demonstrations. But we did not get improvement on AIME2025 nor online submission. </li>\n<li>Model-based Aggregation: We give the LLM the 5 most frequent answers, and one representatitive rationale for each, ask the LLM to reason about the correct answer. But this aggregation method cannot stably achieve improvements. </li>\n<li>Quantization-related trials: We try quantization-aware training (QAT) by finetuning the scales of an AWQ-quantized model with DPO on our 2k-sized DPO dataset, but that doesn't bring improvement. We also try to apply the reparametrization of <code>W_k</code> and <code>W_q</code> to get more channel-balanced key for better KV cache quantization. This brings a consistent but small reasoning performance improvement in our local test, especially in the KV4 setting. However, as we don't have enough submission quota to tune other hyperparameters for KV4 setting, our final solution doesn't use KV4.<br>\nWe decided to briefly share these preliminary trials, but please note that they are not thorough enough to provide a reliable negative signal. Our qualitative inspection of the above trials actually suggests potentials to further explore, but we simply lacked the capacity to explore them further.</li>\n</ul>",
  "comments": [
    {
      "id": 3177240,
      "author_name": "SIRAJ AHMAD",
      "author_url": "",
      "post_date": "2025-04-12T13:21:32.640000",
      "content": "<p>Impressive work! A well-structured and innovative approach—great balance of reasoning optimization and inference efficiency. Congrats on the 2nd place win! 👏</p>",
      "votes": 3,
      "replies": []
    },
    {
      "id": 3177636,
      "author_name": "tascj",
      "author_url": "",
      "post_date": "2025-04-13T04:45:06.333000",
      "content": "<p>Congratulations!</p>\n<p>I have to say this is one of the best solution write-ups I've ever read on Kaggle.</p>",
      "votes": 4,
      "replies": [
        {
          "id": 3177645,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-13T05:02:26.983000",
          "content": "<p>Thanks a million!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3179861,
      "author_name": "Yuki",
      "author_url": "",
      "post_date": "2025-04-15T19:41:57.103000",
      "content": "<p>Congratulations to your team and thanks for this amazing write-up! I learnt a lot from your post-decision processing. I have one question regarding your training process, the training data extract and built from Limo and openr1-math-220k is simply chain-of-thought prompt (given the math problem, respond with chain-of-thought and solution and python code is not required). In the last year, the top2 winner from aimo both applies tora corpus and tool-integrated training examples. May I ask what's your opinion and suggestion regarding tora corpus training and why this is not considered in your solution. Thanks! </p>",
      "votes": 1,
      "replies": [
        {
          "id": 3183591,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-21T03:41:19.140000",
          "content": "<p>Thanks! We did not find a suitable dataset (solving math problems with Python code), and when we tried to use deepseek-r1, we found it difficult to use prompts to let the model solve math problems with code (it always tends to think directly);I think if you use tool integration training, there will be further improvement in our problem-solving framework.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3177382,
      "author_name": "Quickpanda",
      "author_url": "",
      "post_date": "2025-04-12T16:43:20.640000",
      "content": "<p>great work! Thanks for sharing! Your work make this competition more meaningful, it is the real value of this competition! Really thanks for sharing. Thanks kaggle and organizer <a href=\"https://www.kaggle.com/friederrr\" target=\"_blank\">@friederrr</a> !</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 3177301,
      "author_name": "Sangram Patil",
      "author_url": "",
      "post_date": "2025-04-12T14:45:37.167000",
      "content": "<p>First of all, congratulations to your team — you guys have built a great pipeline!<br>\nCan I ask how you converted the models to <code>triton_models format</code>, because I didn’t see that code anywhere?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3177310,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-12T14:57:25.890000",
          "content": "<p>We have updated: <a href=\"https://github.com/imagination-research/aimo2/blob/master/scripts/run_convert.sh\" target=\"_blank\">https://github.com/imagination-research/aimo2/blob/master/scripts/run_convert.sh</a></p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3177243,
      "author_name": "ducnh279",
      "author_url": "",
      "post_date": "2025-04-12T13:25:44.680000",
      "content": "<p>Congrats on the great pipeline! 🙌</p>\n<p>I’m curious about your choice of 8 epochs for SFT. Given that Light-R1 and LIMO are high-quality datasets, I would think that more epochs might lead to additional improvements, similar to how transfer learning benefits from extended training on refined data.</p>\n<p>This reminds me of the Phi-4 technical report, where increasing epochs on synthetic data significantly boosted performance - more than just adding mixed lower-quality (web) data. Did you consider this approach, or was the optimal stopping point determined purely by validation performance?</p>\n<p>Also, using DPO to control response length is actually a wise strategy, especially with the challenges of unstable RL training for concise and effective reasoning!</p>\n<p>Big congrats again!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3177314,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-12T15:00:38.327000",
          "content": "<p>We found that fine-tuning too many epochs will significantly increase the output length of the model. 8 epochs is enough.</p>",
          "votes": 5,
          "replies": []
        }
      ]
    },
    {
      "id": 3183920,
      "author_name": "Vinu1729",
      "author_url": "",
      "post_date": "2025-04-21T12:47:25.043000",
      "content": "<p>Thanks Guys for sharing your all analysis on this competition , the thing u tried i done some of them but due to lack of knowledge i got confused and this was my 1st competition , yet i dont submitted on this competition , but i have an idea like why can we make a ai maths agent which would think like a general mathematian ( find whats given , what to find , how to find , any formulas/theorem ets)… like that , i have a idea to make a ramanujam model which can answer the best of any , just i need knowlege and a better can we make this , and i forget to say , \"Congrats Guys\" , here is my email: <a href=\"mailto:shindevinayak233@gmail.com\">shindevinayak233@gmail.com</a> reach me out there and here is linkedin :<br>\n<a href=\"url\" target=\"_blank\">https://www.linkedin.com/in/vinayak-shinde-1aa968223/</a> , Thanks for that Idea</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3177932,
      "author_name": "Chan Kha Vu",
      "author_url": "",
      "post_date": "2025-04-13T13:34:58.913000",
      "content": "<p>Congratulations to your team, and thanks for the amazing write-up! One of the most thoughtful and clever solution I've ever seen on Kaggle. The attention to details and the effort your team has put into your solution is insane!</p>\n<p>The effort and attention to the inference strategies of your team is truly next level!</p>\n<hr>\n<p>I tried to evaluate your <code>deepseek-14b-sft-dpo4</code> model on AIME'25, in BF16, with 64 rollouts per prompt, max_len is 32768 tokens, temperature 0.75 and top_p 0.95. I made sure that the prompt I'm using is the same as your CoT prompt, for example:</p>\n<pre><code>&lt;｜begin▁of▁sentence｜&gt;You are a helpful math assistant. Please reason step by step to put the answer in \\boxed{}.&lt;｜User｜&gt;Find the sum of the roots of the equation $x^2 - 6x + 9 = 0$. \nYou excel at reasoning.\nYou must put the final answer in \\boxed{}.\nIf the final answer is greater than1000, then take the modulo of 1000.\nThink carefully and thoroughly, avoid duplication.&lt;｜Assistant｜&gt;\n</code></pre>\n<p>However, here are my numbers (your model is last column):</p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>DeepSeek-R1-Distill-14B</th>\n<th>Light-R1-14B-DS</th>\n<th>One of our team's GRPO</th>\n<th>2nd-Place-DPO4</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>accuracy</td>\n<td>0.484896</td>\n<td>0.581771</td>\n<td>0.542188</td>\n<td>0.557813</td>\n</tr>\n<tr>\n<td>avg_len</td>\n<td>13071.5</td>\n<td>13827.4</td>\n<td>11274.5</td>\n<td>12183</td>\n</tr>\n<tr>\n<td>maj@5</td>\n<td>0.591667</td>\n<td>0.679167</td>\n<td>0.695833</td>\n<td>0.679167</td>\n</tr>\n<tr>\n<td>maj@8</td>\n<td>0.591667</td>\n<td>0.7</td>\n<td>0.7125</td>\n<td>0.679167</td>\n</tr>\n<tr>\n<td>maj@12</td>\n<td>0.6125</td>\n<td>0.716667</td>\n<td>0.741667</td>\n<td>0.708333</td>\n</tr>\n</tbody>\n</table>\n<p>PS: the majority voting accuracy <code>maj@k</code> numbers are averaged over multiple \"virtual\" runs, where I sample traces from a bank of reasoning traces (64 to be exact).</p>\n<p>My numbers for Deepseek-R1-14B and Light-R1-14B matches the reported numbers. But your model's accuracy in my tests is <code>0.558</code> (averaged over 64 rollouts per problem), but you reported <code>0.589</code>. Was that number pure COT performance or it's mixed with TIR?</p>",
      "votes": 2,
      "replies": [
        {
          "id": 3177938,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-13T13:49:16.423000",
          "content": "<p>Thanks! This number is mixed with TIR, so pure COT may be lower, we mentioned it here.<br>\nBesides, we applied the sample-level early stop strategy (as we mentioned) for evaluation.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F691182fd63eb695112d9d70135e6a5a3%2F92241a106152d3a12616bdbe40d76631.png?generation=1744552045434973&amp;alt=media\" alt=\"\"></p>",
          "votes": 3,
          "replies": [
            {
              "id": 3177939,
              "author_name": "Chan Kha Vu",
              "author_url": "",
              "post_date": "2025-04-13T13:51:51.907000",
              "content": "<p>Thanks, that makes a lot more sense. Now I feel silly for even trying your model with CoT only 😅</p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3182290,
      "author_name": "William Lien",
      "author_url": "",
      "post_date": "2025-04-19T04:47:08.450000",
      "content": "<p>Very impressive thought &amp; solution.</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3180988,
      "author_name": "john",
      "author_url": "",
      "post_date": "2025-04-17T10:52:08.413000",
      "content": "<p>Congratulations.  Thanks for the write-up &amp; excellent plots!<br>\nI have one question after read the quant_awq.py code.<br>\nThe default max_calib_seq_len of autoawq is 512. What's the reason for choosing max_calib_seq_len=128 &amp; max_calib_samples=1024? </p>",
      "votes": 0,
      "replies": [
        {
          "id": 3183537,
          "author_name": "Joe T",
          "author_url": "",
          "post_date": "2025-04-21T01:05:46.853000",
          "content": "<p>Well done!</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3180684,
      "author_name": "planet2020",
      "author_url": "",
      "post_date": "2025-04-17T02:12:16.843000",
      "content": "<p>After spending hours reading the notebook and codes, I am still confused. Can you please share the original notebook used to submit for the private LB?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3180699,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-17T02:39:40.807000",
          "content": "<p>This backup notebook is <strong>exactly the same as</strong> the notebook we finally scored 31, there may be some irregularities in the writing, we still recommend you to read our cleaned version, which is more structured.<br>\n<a href=\"https://github.com/imagination-research/aimo2/blob/master/imagination_aimo2/backup_submission.ipynb\" target=\"_blank\">https://github.com/imagination-research/aimo2/blob/master/imagination_aimo2/backup_submission.ipynb</a></p>",
          "votes": 2,
          "replies": [
            {
              "id": 3181313,
              "author_name": "Chew Kok Wah",
              "author_url": "",
              "post_date": "2025-04-17T17:57:02.227000",
              "content": "<p>Thanks you.</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3181491,
              "author_name": "Yichen You",
              "author_url": "",
              "post_date": "2025-04-18T00:34:41.533000",
              "content": "<p>version112 got 33/31 on public/private leaderboard and version94 got 34/29.<br>\n<a href=\"https://www.kaggle.com/code/youyc22/imagination-research-original-submission\" target=\"_blank\">https://www.kaggle.com/code/youyc22/imagination-research-original-submission</a><br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fd22cae24037ff5ebd06f0bf30918e69c%2Fc08c0758b2569345f9507f101ca9b13a.png?generation=1744936765179862&amp;alt=media\" alt=\"\"></p>",
              "votes": 2,
              "replies": []
            },
            {
              "id": 3181526,
              "author_name": "planet2020",
              "author_url": "",
              "post_date": "2025-04-18T02:25:03.740000",
              "content": "<p>Thank you for sharing this notebook🙂</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3179940,
      "author_name": "planet2020",
      "author_url": "",
      "post_date": "2025-04-16T00:12:56.353000",
      "content": "<p>Congratulations! I copied your notebook and run it in Kaggle. The program was terminated very quickly, leaving only the following reply. Is it not possible to run it directly on Kaggle?</p>\n<p>2025-04-15 23:52:14,096 - lmdeploy - WARNING - supported_models.py:106 - /kaggle/input/dpsk-14b-sft-dpo-3-13-awq-tb/keras/default/1/dpsk-14b-sft-dpo4-3-13-awq-tb seems to be a turbomind workspace, which can only be ran with turbomind engine.<br>\n[TM][WARNING] [LlamaTritonModel] <code>max_context_token_num</code> is not set, default to 33320.<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n2025-04-15 23:53:08,504 - lmdeploy - WARNING - tokenizer.py:647 - The token &lt;|endoftext|&gt;, its length of indexes [27, 91, 8691, 723, 427, 91, 29] is over than 1. Currently, it can not be used as stop words<br>\nUpdated active prompts. Target: 15, Actual: 15<br>\nbbd91e<br>\n057f8a<br>\n192e23<br>\n1fce4b<br>\n71beb6<br>\n1acac0<br>\na1d40b<br>\n88c219<br>\n480182<br>\n349493</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3179997,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-16T02:19:59.360000",
          "content": "<p>Thanks! You need to comment out the first three lines in predict function<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fd4c766569358a8e6ef6caef86d98f06d%2Feb2e127fcc17081930a6e5bcbccdafd5.png?generation=1744769914560504&amp;alt=media\" alt=\"\"></p>",
          "votes": 0,
          "replies": [
            {
              "id": 3180040,
              "author_name": "planet2020",
              "author_url": "",
              "post_date": "2025-04-16T03:53:45.987000",
              "content": "<p>It works. Thank you very much. The outputs are so detailed👍</p>",
              "votes": 0,
              "replies": []
            }
          ]
        },
        {
          "id": 3213597,
          "author_name": "",
          "author_url": "",
          "post_date": "2025-05-30T08:12:20.890000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3179762,
      "author_name": "GURRAM GOPICHANDH",
      "author_url": "",
      "post_date": "2025-04-15T16:48:46.030000",
      "content": "<p>Impressive thoughts and solution.</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3179704,
      "author_name": "",
      "author_url": "",
      "post_date": "2025-04-15T15:59:29.057000",
      "content": "<p>Thanks for sharing your solution. It was very helpful .</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3178493,
      "author_name": "YANGJIAHUA",
      "author_url": "",
      "post_date": "2025-04-14T08:53:59.600000",
      "content": "<p>Congratulations to your team, and thank you for the excellent paper! I’ve learned a lot from it! Would it be possible for you to share the code for the SFT stage or the DPO stage? I’d be very grateful if you could—I'd love to study and learn more about it!</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3178564,
          "author_name": "Foxfi Ning",
          "author_url": "",
          "post_date": "2025-04-14T10:31:25.723000",
          "content": "<p>Thanks. We use 360-LLama-Factory's code (a git submodule in our repository) to run SFT and DPO. You can check our repository <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\">https://github.com/imagination-research/aimo2</a>, the scripts are given at <code>scripts/run_sft.sh</code> and <code>scripts/run_dpo.sh</code>.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3178404,
      "author_name": "",
      "author_url": "",
      "post_date": "2025-04-14T05:58:53.590000",
      "content": "<p>Congratulations!! This is really great, the way it's written is soo clean and it's spelled out well. For sure your work would be used to build and iterate in the future competitions. <br>\nI have a couple of questions though:<br>\nUpon the completion of the training, did your team think that 8 epochs is a bit too much or what is appropriately enough?<br>\nAnd can you share the training losses you got while fine tuning if possible :)</p>\n<p>And I wanted to ask in general, I see that everyone uses both the system and user role in their prompts. But the model card in huggingface says this thing below. Did you experiment by putting the instruction+question in the user role and ditching the system role? I went through your repo (which is really cool btw) and I can see that you used both the roles. Any specific reason? I mean pretty much everyone did this too, I really want to know what's this about. </p>\n<pre><code>Usage Recommendations\nWe recommend adhering   following configurations when utilizing  DeepSeek-R1 series models, including benchmarking,  achieve  expected performance:\n\nAvoid adding   prompt; all instructions should be contained   user prompt.\n</code></pre>",
      "votes": 0,
      "replies": [
        {
          "id": 3178568,
          "author_name": "Foxfi Ning",
          "author_url": "",
          "post_date": "2025-04-14T10:39:57.770000",
          "content": "<p>Thanks!</p>\n<p>About Q1, 8-epoch SFT is appropriately enough in our case. More epochs will lead to longer token length.</p>\n<p>About Q3, thank you for letting us to know this note. We don't know this note, so we are just following early practice of using both the system prompt and user prompt.</p>\n<p>About Q2, I need to ping Yichen to plot the loss curve <a href=\"https://www.kaggle.com/youyc22\" target=\"_blank\">@youyc22</a> </p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 3178571,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-14T10:46:27.350000",
          "content": "<p>SFT loss curve is as follows</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fde64ae59cdb37dfe61fc77bef5508759%2Fd132ee85970b588f4e7070d91ea47d9b.png?generation=1744627553753428&amp;alt=media\" alt=\"\"></p>",
          "votes": 3,
          "replies": [
            {
              "id": 3178595,
              "author_name": "",
              "author_url": "",
              "post_date": "2025-04-14T11:16:07.643000",
              "content": "",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3178126,
      "author_name": "xcape74",
      "author_url": "",
      "post_date": "2025-04-13T18:42:58.157000",
      "content": "<p>Congratulations! Great job!<br>\nHave you tried model merging ?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3178308,
          "author_name": "Foxfi Ning",
          "author_url": "",
          "post_date": "2025-04-14T02:57:17.360000",
          "content": "<p>We have tried model merging, between the two checkpoints and another checkpoint of a new DPO run. We can get an FP16 model that has a slightly higher average sample accuracy and an obviously higher (+2/+3 out of 30 problems) aggregated accuracy in our local test. However, when quantized, the model is no better than the original quantized checkpoints in the local test, and as the submission quota is limited to test multiple time of that model, we didn't submit it.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3177948,
      "author_name": "Chew Kok Wah",
      "author_url": "",
      "post_date": "2025-04-13T14:23:05.743000",
      "content": "<p>Can you share your original winning submission notebook. (Do understand the cleaned version could be similar but community might be able to learn something from the original one)</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3177891,
      "author_name": "Wadiel Rahman",
      "author_url": "",
      "post_date": "2025-04-13T12:14:56.563000",
      "content": "<p>Fantastic work! I would love to see more of it!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3177723,
      "author_name": "Jason Bourne",
      "author_url": "",
      "post_date": "2025-04-13T07:23:50.573000",
      "content": "<p>最实至名归的一集。从前至后各阶段的实验安排条理清晰，模型提升的方法思路很让人受启发。期待你们下一次取得更好的成绩💪。<br>\n羡慕8块A800啊，穷人真是玩不起大模型😂</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3177727,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-13T07:28:44.427000",
          "content": "<p>Thanks a lot!<br>\n感谢支持！</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3177718,
      "author_name": "Chew Kok Wah",
      "author_url": "",
      "post_date": "2025-04-13T07:11:20.517000",
      "content": "<p>Congratulations!</p>\n<ol>\n<li><p>Can you provide the data deduplication script for dataset duplicates removal?</p></li>\n<li><p>Please share the FP16 model weight for Stage 1 SFT as well as Stage 2 DPO similar to the way AIMO1 winner did it.<br>\n<a href=\"https://huggingface.co/AI-MO\" target=\"_blank\">https://huggingface.co/AI-MO</a></p></li>\n</ol>",
      "votes": 0,
      "replies": [
        {
          "id": 3177790,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-13T09:29:07.680000",
          "content": "<p>We have updated here:<a href=\"https://github.com/imagination-research/aimo2/blob/master/scripts/run_deduplicate.sh\" target=\"_blank\">https://github.com/imagination-research/aimo2/blob/master/scripts/run_deduplicate.sh</a></p>\n<p>Stage2 DPO model can be found on huggingface:<a href=\"https://huggingface.co/collections/imagination-research/aimo2-67f92097e2a4e04d995f3d75\" target=\"_blank\">https://huggingface.co/collections/imagination-research/aimo2-67f92097e2a4e04d995f3d75</a>, which can be found at the beginning of our write-up</p>\n<p>Stage1 SFT model will be uploaded sooner</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3177560,
      "author_name": "RabotniKuma",
      "author_url": "",
      "post_date": "2025-04-13T01:09:37.850000",
      "content": "<p>Congrats! Such a beautiful and well-designed solution.<br>\nDo you have records of how Public LB improved after each tranining step?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3177598,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-13T02:52:10.743000",
          "content": "<p>Thanks! We got <code>28</code> without any finetuning, scored <code>33</code> after sft (8 epochs) and dpo (2 epochs), scored <code>34</code> after dpo for 4 epochs(ranging between 32~34). We didn't submit the model that only had SFT applied.</p>",
          "votes": 5,
          "replies": []
        }
      ]
    },
    {
      "id": 3177531,
      "author_name": "Olabode James",
      "author_url": "",
      "post_date": "2025-04-12T23:03:14.350000",
      "content": "<p>This is an absolutely remarkable solution, and thank you more for sharing your approach to improve the quality of future contributions in the field. Looking forward to more works from you</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3177335,
      "author_name": "xz",
      "author_url": "",
      "post_date": "2025-04-12T15:43:50.377000",
      "content": "<p>Congrats! What was the score with the stage 1 SFT model and did DPO give significant improvement over it?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3177599,
          "author_name": "Yichen You",
          "author_url": "",
          "post_date": "2025-04-13T02:55:24.770000",
          "content": "<p>Thanks! We didn't submit the stage 1 SFT model, base model got <code>28</code>, dpo-2 got <code>33</code> and dpo-4 got <code>34</code>, but on private leaderboard they got <code>31</code> and <code>29</code> respectively.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 3177323,
      "author_name": "Kawa",
      "author_url": "",
      "post_date": "2025-04-12T15:19:56.043000",
      "content": "<p>Amazing work, congratulations.</p>\n<p>I am interested in quantization-aware training, I had quite a bit of trouble setting up QAT. Can you share how you did it?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3177590,
          "author_name": "Foxfi Ning",
          "author_url": "",
          "post_date": "2025-04-13T02:36:16.660000",
          "content": "<p>Thanks for your question. We just do a very cursory and incomplete trial, the following is just for your reference. We use the 360-LLama-Factory library, which uses <code>autoawq</code> to load the AWQ model. In order to tune the scales of AWQ-quantized model, we do the following ugly fixes:</p>\n<p>(1) In <code>autoawq</code>'s <code>awq.modules.linear.WQLinear_GEMM.__init__</code>: We register the scales as parameters instead of buffers, in order for let the optimizer update them:</p>\n<pre><code>        .register_parameter(\n            ,\n            torch.nn.Parameter(torch.zeros(\n                  (in_features // .group_size, out_features),\n        dtype=torch.float16,\n                device=dev,\n            )),\n    )\n</code></pre>\n<p>(2) In <code>autoawq</code>'s <code>awq.modules.linear.WQLinear_GEMM.forward</code>: Instead of calling <code>WQLinearMMFunction.apply</code>, we change it to use the naive implementation of decoding+matrix-multiplication. The original implementation uses a more efficient Triton-implemented decoding+matrix-multiplication, but they don't implement gradient backward for the scale.</p>\n<pre><code>        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n      user_has_been_warned:\n            warnings.warn( + msg)\n        user_has_been_warned = \n         torch.cuda.amp.autocast():\n            out = dequantize_gemm(.qweight, .qzeros, .scales, .w_bit, .g\\\nroup_size)\n            out = torch.matmul(x, out)\n              out = out + .bias  .bias     out\n        out = out.reshape(out_shape)\n        \n     (out.shape) == :\n        out = out.unsqueeze()\n</code></pre>\n<p>(3) In the 360-Llama-Factory lib, we add the following call to the <code>llamafactory.train.dpo.workflow.run_dpo</code> function after loading the model, to set the <code>requires_grad</code> of scales to be True.</p>\n<pre><code>\n\n\n\n\n\n\n\n\n def run_dpo(\n     model_args: \"ModelArguments\",\n     data_args: \"DataArguments\",\n def run_dpo(\n     template = get_template_and_fix_tokenizer(tokenizer, data_args)\n     dataset_module = get_dataset(template, model_args, data_args, training_args, stage=\"rm\", **tokenizer_module)\n     model = load_model(tokenizer, model_args, finetuning_args, training_args.do_train, full_determinism=training_args.full_determinism)\n\n</code></pre>\n<p>As you can see, we do some ugly fixes instead of writing a clean code. A detail is that due to our computational capability limitation, we use of cutoff length of 16k (instead of 32k) to do the training on 4 GPUs. This small quick attempt doesn't get improvements. We think tuning the weights might still be needed, and longer context length might be needed, but we don't have the GPU &amp; development capacity to further try that. </p>",
          "votes": 1,
          "replies": [
            {
              "id": 3177792,
              "author_name": "Kawa",
              "author_url": "",
              "post_date": "2025-04-13T09:36:32.430000",
              "content": "<p>Thanks for detail. Seems AWQ model so hard to finetune(especially reasoning model). My tests came out pretty bad, 15-18 on public lb.</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3180012,
              "author_name": "Chan Kha Vu",
              "author_url": "",
              "post_date": "2025-04-16T03:23:31.467000",
              "content": "<p>Wow! this is actually really cool, so much care going into each detail…</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3177315,
      "author_name": "Danyal Abbas",
      "author_url": "",
      "post_date": "2025-04-12T15:01:28.947000",
      "content": "<p>Very incredibly structured approach<br>\nCongratulations on the 2nd place win!</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3177259,
      "author_name": "Timmy Juicehouse",
      "author_url": "",
      "post_date": "2025-04-12T13:54:50.443000",
      "content": "<p>It's a huge work for your team, and it takes a long time to ultimately win the 2nd place, truly well-deserved. Great performance your Tsinghua and Microsoft.</p>\n<blockquote>\n  <p>RAG: we use this dataset as a document bank. When solving a question, we fetch 1~2 most similar questions from the bank, use them and their corresponding solutions as the few-shot demonstrations. But we did not get improvement on AIME2025 nor online submission.</p>\n</blockquote>\n<p>Once I thought RAG was a key solution for this competition, but in reality, it didn’t work when I tried it myself. I’m a bit confused, maybe the dataset is just too difficult?</p>",
      "votes": 0,
      "replies": [
        {
          "id": 3177312,
          "author_name": "",
          "author_url": "",
          "post_date": "2025-04-12T14:58:53.647000",
          "content": "",
          "votes": 0,
          "replies": []
        },
        {
          "id": 3177321,
          "author_name": "Foxfi Ning",
          "author_url": "",
          "post_date": "2025-04-12T15:10:41.440000",
          "content": "<p>Thanks! </p>\n<p>About RAG, we try RAG in an early stage of our experiments. Back then, we qualitatively inspect some runs (no statistics), and find out that the questions that have similar embedding not necessarily have similar solving strategies (e.g., have similar words instead of reasoning structure). To further explore this, maybe we can try better embedding or retrieval strategies, e.g., (1) use a more appropriate feature as the embedding (we just use the mean of the last layer's feature across tokens), which might be more reflective of the reasoning state instead of language-related information, or (2) rely on the model to do some analyses and improve the embedding based on intermediate analyses, or (3) actively search for reference and reason in a more flexible agentic way. </p>\n<p>However, we don’t further experiment with these possible mitigations. Therefore, we cannot say we have reached a reliable negative conclusion for this pathway. It still needs further inspection and exploration.</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 3177594,
          "author_name": "",
          "author_url": "",
          "post_date": "2025-04-13T02:41:34.490000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 3181250,
      "author_name": "",
      "author_url": "",
      "post_date": "2025-04-17T16:07:19.640000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3178152,
      "author_name": "",
      "author_url": "",
      "post_date": "2025-04-13T19:32:39.093000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3178757,
      "author_name": "",
      "author_url": "",
      "post_date": "2025-04-14T15:11:50.600000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "comment_count": 59,
  "messages": [
    {
      "id": 3177222,
      "postDate": "2025-04-12T12:39:42.440Z",
      "content": "<ul>\n<li><strong>Repository</strong>: <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\">https://github.com/imagination-research/aimo2</a></li>\n<li><strong>Models</strong>:<br>\n<a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4\" target=\"_blank\">https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4</a><br>\n<a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2\" target=\"_blank\">https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2</a><br>\n<a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft\" target=\"_blank\">https://huggingface.co/imagination-research/deepseek-14b-sft</a></li>\n<li><strong>Notebook</strong>: <a href=\"https://www.kaggle.com/code/youyc22/imagination-research-2nd-place-solution/\" target=\"_blank\">https://www.kaggle.com/code/youyc22/imagination-research-2nd-place-solution/</a><br>\nThanks to Aimo and Kaggle for hosting this great competition. We are also grateful to all the competitors during the competition and all the open source projects for sharing their great ideas. Now it's time to share our ideas and experiences with the community!<br>\nOur solution gets the 2nd place. It gets <strong>34/50</strong> on the public leaderboard (ranked <strong>1st</strong>), and <strong>31/50</strong> (ranked <strong>2nd</strong>) on the private leaderboard. </li>\n</ul>\n<h2>Solution Summary</h2>\n<p>This competition required optimizing both efficiency and reasoning performance. Our final solution consists of three main parts:</p>\n<ul>\n<li>Part I: <strong>Reasoning-Oriented Training</strong> -- <em>Improve the model's reasoning ability</em>: Stage 1 - SFT and Stage 2 - DPO with selected data.</li>\n<li>Part II: <strong>Efficiency Optimization</strong> -- <em>Improve inference efficiency</em>: Selecting a suitable inference engine, weight quantization, and KV cache quantization.</li>\n<li>Part III: <strong>Inference-Time Strategies</strong> -- <em>Improve efficiency-reasoning performance trade-off</em>: Prompt design, self-consistency aggregation, sample-level/question-level early stopping, and some heuristic hyperparameter adjusting.<br>\nFor local validation, we used the AIME 2025 test set (30 problems) along with the reference set (10 problems), evaluating both average sample accuracy and aggregated accuracy (via self-consistency) to obtain preliminary judgments of our trial solutions.</li>\n</ul>\n<h2>Part I: Reasoning-Oriented Training</h2>\n<p>Our training scripts are based on <a href=\"https://github.com/Qihoo360/Light-R1\" target=\"_blank\"><code>Light-R1</code></a> project, we are really grateful to their work.</p>\n<h3>Stage1: SFT</h3>\n<p>We choose <a href=\"https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-14B\" target=\"_blank\"><code>DeepSeek-R1-Distill-Qwen-14B</code></a> as the base model considering its great performance in mathematics, coding and reasoning.<br>\nWe combine the stage2 data from <a href=\"https://huggingface.co/datasets/qihoo360/Light-R1-SFTData\" target=\"_blank\"><code>Light-R1</code></a> and training data from <a href=\"https://huggingface.co/datasets/GAIR/LIMO\" target=\"_blank\"><code>Limo</code></a> together (duplicates removed), which are both high-difficulty math problems' reasoning trajectories generated from deepseek-r1<br>\nWe finetune the base model for 8 epochs on single 8×A800 machine, taking 11 hours:<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F641a0798dbca8be9adbf1b010cb49159%2F2e6707889efebafd252bd2ad0443d232.png?generation=1744460831585737&amp;alt=media\" alt=\"\"><br>\nThe accuracy improves but the output length also improves significantly.</p>\n<h3>Stage2: DPO</h3>\n<p>We use DPO to reduce the output length of the model<br>\nWe choose the default subset of <a href=\"https://huggingface.co/datasets/open-r1/OpenR1-Math-220k/tree/main/data\" target=\"_blank\"><code>OpenR1-Math-220k</code></a> to build our dataset<br>\nSpecifically, we try to use the following four criteria to construct DPO pairs (y_w, y_l means chosen response and rejected response):</p>\n<ul>\n<li><strong>Correctness</strong>: y_w must be correct, y_l may be correct or incorrect</li>\n<li><strong>Length ratio</strong>:  len(y_w) &lt; ratio_threshold * len(y_l)</li>\n<li><strong>Min Length</strong>: len(y_w) &gt; min_threshold</li>\n<li><strong>Similarity</strong>: sim(y_w,y_l) &lt; sim_threshold</li>\n<li>use sentence transformer model to calculate embeddings<br>\nApplying the first three criteria, we construct the dataset dpo-1, which is used to train the models we submit.<br>\nApplying the four criteria, we construct the dataset dpo-2, which is used to train another model, but its performance is similar to the model we submit.<br>\nWe use <a href=\"https://github.com/Qihoo360/360-LLaMA-Factory/tree/adfd1708b94a921637c3821bca4a6dd3d81d0387\" target=\"_blank\"><code>360-LLaMA-Factory</code></a> because they add sequence parallelism (SP) technology to support longer context training with limited memory.<br>\nWe use a single 8×A800 machine to train for 4 epochs on dpo-1 dataset(2k pairs), taking 40 hours.<br>\nFrom the above process, we get two models we finally submitted:<br>\n<strong><a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2\" target=\"_blank\"><code>deepseek-14b-sft-dpo2</code></a></strong> and <strong><a href=\"https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4\" target=\"_blank\"><code>deepseek-14b-sft-dpo4</code></a></strong><br>\nAll our training data can be found here:<br>\n<strong><a href=\"https://huggingface.co/datasets/imagination-research/aimo2-datasets\" target=\"_blank\"><code>training data</code></a></strong><br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fb0a29a66664d9236e04b532fbc0e03c8%2F7187e4e6d0daeae809ac6559ffa3b103.png?generation=1744460986607785&amp;alt=media\" alt=\"\"><br>\n<strong><em>Note: in the above table, we sample 32 times (direct reasoning 16 times and code solving 16 times) for each question. Pass@1 is computed on AIME 2025 dataset. More details on our inference method are discussed later.</em></strong></li>\n</ul>\n<h2>Part II: Efficiency Optimization</h2>\n<h3>Inference Engine</h3>\n<p>We choose <a href=\"https://github.com/InternLM/lmdeploy\" target=\"_blank\"><code>lmdeploy</code></a> as the LLM inference framework. Compared with <code>vllm</code>, the <code>lmdeploy</code> framework with the TurboMind engine can provide higher throughput and shorter model initialization time.<br>\nThe lmdeploy version we use is  0.7.0.post1<br>\nThe first picture comes from <a href=\"https://github.com/InternLM/lmdeploy\" target=\"_blank\"><code>here</code></a><br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F5e8c198ab84475ca77c1b8b27adfcdd9%2F5f126916d91bb2519cb69dd4b3256ef3.png?generation=1744461014286477&amp;alt=media\" alt=\"\"></p>\n<h3>Quantization</h3>\n<p>We apply 4-bit AWQ weight quantization, and 8-bit KV Cache quantization (setting the configuration <code>main_model.inference_cfg.quant_policy</code> to 8 to use 8-bit KV Cache quantization implemented by <code>lmdeploy</code>).<br>\nOur two models for submissions can be found here: <a href=\"https://www.kaggle.com/models/youyc22/dpsk-14b-sft-dpo-3-16-awq-tb/Keras/default\" target=\"_blank\">model1</a>, <a href=\"https://www.kaggle.com/models/youyc22/dpsk-14b-sft-dpo-3-13-awq-tb/Keras/default\" target=\"_blank\">model2</a><br>\n<strong>Some efficiency results</strong>:</p>\n<ul>\n<li>Online test (4xL4, batch size=15): W4KV8 decreases the time per output token by about 20% compared with W4KV16, 55% compared with FP16.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F1f2074a4fa450da09049e99f3d97f2ab%2Fc1af1024b94a2d7511b234b44df1ab6e.png?generation=1744461043302217&amp;alt=media\" alt=\"\"></li>\n<li>Local test (2xA800, batch size=32): W4KV8, W4KV16 decreases the overall latency by 40% and 20%-25% compared with FP16, respectively.<br>\n<strong>Some reasoning performance results</strong>:</li>\n<li>Local test: The average sample accuracy (not aggregated accuracy) drops by 5%~10%, compared with FP16; W4KV8 is not worse than W4KV16. W4KV4 is worse.</li>\n</ul>\n<h2>Part III: Inference-Time Strategies</h2>\n<h3>Overall Inference Workflow</h3>\n<p>The inference workflow is shown in the figure below: A question is provided as the input. We first prepare two types of prompts, including the CoT prompt and the Code prompt (\"Prompt Preparation Task\"). Then, we let the LLM start batchify generation of multiple samples with <code>lmdeploy</code> (\"LLM Generation Task\"). In the mean time, we continuouly try extract the answer from the streaming output of each sample, aggregate the answers of multiple samples, and judge whether to early stop some generation:</p>\n<ol>\n<li>We do sample-level checking upon every N yields from the iterator got by the <code>stream_infer(...)</code> call, and judge whether to early stop the generation of the corresponding sample. The Python code executor and answer extractor components are used here.</li>\n<li>We do question-level checking upon the end of every sample, and judge whether to early stop the generation of all remaining samples of the current question. The answer aggregator component is used here.<br>\nFinally, we return the aggregated answer.<br>\nNote that, for each question, we adjust the speed-related hyperparameters (number of samples, sampling-level max time, question-level early-stop criterion) according to the remaining time, so that the time quota can be allocated in a more balanced way across the remaining questions when the remaining time is limited.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fef0d82c4b38753bb20a279e0f9c84148%2F4ff9e80d8347169f359c9f8a32a7331b.png?generation=1744461072712397&amp;alt=media\" alt=\"\"></li>\n</ol>\n<h3>Prompt Preparation</h3>\n<p><strong>Method</strong>:</p>\n<ul>\n<li>Initially, we use 15 samples for one question, and aggregate their answers by self-consistency.</li>\n<li>Note that we don't necessarily aggregate the answers of all samples, see <a href=\"#question-level-answer-aggregation--early-stopping\">discussions below</a> for more details.</li>\n<li>Note that we decrease the number of samples when there is limited time left, see <a href=\"#speed-hyperparameter-adjusting\">discussions below</a> for more details.</li>\n<li>We use the commonly used code-based reasoning: (1) Prompt the model to provide Python code to solve the problem; (2) Extract Python code from the output, create a subprocess to execute the code; (3) Extract the answer from the execution results.</li>\n<li>We use two types of prompts - a CoT prompt and a Code prompt. Among 15 samples, 7 samples use the CoT prompt and 8 samples use the Code prompt:</li>\n</ul>\n<pre><code>\n  \n \n\n  \n \n</code></pre>\n<p><strong>Some experiments</strong>:</p>\n<p></p><ul><br>\n<li>System prompt choice: We find diversifying the system prompt doesn't help for reasoning models.</li><br>\n<li>Prompt list choice: In the local test, we find only using our Code prompt result in a consistent (across seed and models) and small improvements than using half CoT and half code prompts. However, when we submit this (only once), it doesn't help with the public submission score, thus, we don't further test this empirical choice.</li><br>\n<li>Number of samples: In the local test, we find that using 32 samples achieve better results than using 16 samples. However, due to the limited computing power on the submission platform and limited submission quota, we do not thoroughly experiment with more samples on the submission platform to find a sweet point -- we just go with 15 samples.</li><br>\n<li>How frequently the code prompt lead to code output, code error, wrong answer (32 samples, 16 CoT Prompts, 16 Code Prompts):</li><br>\n<li>Cases where the code runs correctly but we cannot parse an integer from its output are rare and can be ignored.</li><br>\n<li><strong>Before fine-tuning</strong>, the model is more inclined to output code: on average, in only 1.9 or 3.3 out of 16 cases where a code prompt is used, the model does not output code.</li><br>\n<li><strong>After our fine-tuning</strong> with only math data, the model becomes less inclined to output code: on average, in about 11 out of 16 cases, the code prompt does not cause the model to output code. When the new model does output code, its conditional accuracy is slightly higher than the pre-fine-tuning model (45% and 55% vs. 42%).<br><p></p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>Quantization</th>\n<th>Total solving time</th>\n<th>Avg outlen</th>\n<th>Aggregated correct questions (/30)</th>\n<th>Average correct samples (/32)</th>\n<th>Code error break down (/16)</th>\n<th><br></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dpsk-qwen-14b</td>\n<td>KV16</td>\n<td>11838.22</td>\n<td>9776.94</td>\n<td>20.00</td>\n<td>14.63</td>\n<td>No code: 1.93; Exec error: 2.97; Fail parseint: 0.13; Wrong number: 5.30</td>\n<td><br></td>\n</tr>\n<tr>\n<td>dpsk-qwen-14b-awq</td>\n<td>AWQ4 KV8</td>\n<td>6844.75</td>\n<td>10118.54</td>\n<td>21.00</td>\n<td>14.40</td>\n<td>No code: 3.30; Exec error: 2.53; Fail parseint: 0.33; Wrong number: 4.57</td>\n<td><br></td>\n</tr>\n<tr>\n<td>dpsk-qwen-14b-finetune-v1-epoch4</td>\n<td>KV16</td>\n<td>12971.18</td>\n<td>11151.10</td>\n<td>21.00</td>\n<td>18.90</td>\n<td>No code: 11.00; Exec error: 0.83; Fail parseint: 0.03; Wrong number: 1.43</td>\n<td><br></td>\n</tr>\n<tr>\n<td>dpsk-qwen-14b-finetune-v1-epoch4-awq</td>\n<td>AWQ4 KV8</td>\n<td>7963.94</td>\n<td>11557.06</td>\n<td>21.00</td>\n<td>16.80</td>\n<td>No code: 11.07; Exec error: 1.30; Fail parseint: 0.03; Wrong number: 0.90</td>\n<td></td></tr></tbody></table></li>\n\n\n</ul>\n\n\n\n\n\n\n\n\n\n<h3>Sample-level Answer Extraction &amp; Early Stopping</h3>\n\n\n\n\n\n\n\n\n\n\n<p><strong>Motivation</strong>: Usually, the reasoning model will self-doubt a lot after obtaining the answer early, even if it usually gives out the same answer finally. And in most cases, after giving the answer between <code>&lt;think&gt;&lt;/think&gt;</code>, the model will rewrite the solution again (at least twice). Can we reduce the wasting of tokens?<br>\n<strong>Method</strong>: Although we experimented with the active probing method from \"Fu et al., \"Efficiently Serving LLM Reasoning Programs with Certaindex, arXiv 2412\", we ultimately adopted a much simpler sample-level early stopping technique to simplify our inference workflow. Specifically, once we detect either the first successfully executable code or the first answer in \"\\boxed{…}\", we stop the generation process for that sample.<br>\n<strong>Some experiments</strong>: A natural question is whether this might harm the potential to revise an initially incorrect answer into a correct one later. In our local tests, we use <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\"><code>scripts/analyze_early_stop.py</code></a> to verify that such cases are relatively rare, as shown in the figure below.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fe0046e83f954d42e3133ea88947b4b89%2Fdc372cc270acc1d5dc01f37c533e0bc8.png?generation=1744461139162863&amp;alt=media\" alt=\"\"></p>\n<h3>Question-level Answer Aggregation &amp; Early Stopping</h3>\n<p>We use the commonly used self-consistency method for answer aggregation. We use a question-level early-stop strategy as follows.<br>\n<strong>Motivation</strong>: The difficulty varies across problems, so we aim to avoid spending too much time on easy ones. As shown in the figure below, the output length varies considerably across samples for a single problem. This suggests that for some problems, we may obtain several correct answers early on but still need to wait for the longest sample to finish -- resulting in significant time waste (e.g., q1, q11, q16–q20, etc.).<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Ff42ad387359f025fcd84406d2522fc07%2F4856497485f90b1ee37ee3d907f90419.png?generation=1744461161694426&amp;alt=media\" alt=\"\"><br>\n<strong>Method</strong>: We can stop generation early for a question if sufficient certainty is achieved by examining the existing answers. Specifically, we terminate generation at the question level when a majority of the outputs are consistent, e.g., if 5 out of 7 answers agree. See the configurations in <code>early_stop_strategy.consistency_rules</code> in <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\"><code>imagination_aimo2/local_eval_kaggle.py</code></a>.</p>\n<h3>Speed Hyperparameter Adjusting</h3>\n<p><strong>Motivation</strong>: The time to solve questions of different difficulty levels varies greatly, we design a <code>adjust_speed</code> module to dynamically adjust some hyperparameters.<br>\n<strong>Method</strong>: As reasoning progresses, our <code>adjust_speed</code> module calculates the remaining time and number of remaining questions, and dynamically adjusts the model's sampling number and early stopping strategy accordingly.<br>\nFor example, the default speed is <code>3(normal)</code>, if the system detects that the average remaining time for each question is less than 5 minutes, it automatically adjust the speed to <code>1(fastest)</code> .This means the number of samples is decreased to 10 and the maximum reasoning time for each question is also decreased. Please refer to our code for detailed implementation.</p>\n<h2>Other methods we tried but did not reach a conclusion and include in our final solution</h2>\n<ul>\n<li>GRPO: we tried four training runs but did not observe significant improvement on accuracy.</li>\n<li>RAG: we use this <a href=\"https://www.kaggle.com/datasets/artemgoncarov/math-problems-imo\" target=\"_blank\">dataset</a> as a document bank. When solving a question, we fetch 1~2 most similar questions from the bank, use them and their corresponding solutions as the few-shot demonstrations. But we did not get improvement on AIME2025 nor online submission. </li>\n<li>Model-based Aggregation: We give the LLM the 5 most frequent answers, and one representatitive rationale for each, ask the LLM to reason about the correct answer. But this aggregation method cannot stably achieve improvements. </li>\n<li>Quantization-related trials: We try quantization-aware training (QAT) by finetuning the scales of an AWQ-quantized model with DPO on our 2k-sized DPO dataset, but that doesn't bring improvement. We also try to apply the reparametrization of <code>W_k</code> and <code>W_q</code> to get more channel-balanced key for better KV cache quantization. This brings a consistent but small reasoning performance improvement in our local test, especially in the KV4 setting. However, as we don't have enough submission quota to tune other hyperparameters for KV4 setting, our final solution doesn't use KV4.<br>\nWe decided to briefly share these preliminary trials, but please note that they are not thorough enough to provide a reliable negative signal. Our qualitative inspection of the above trials actually suggests potentials to further explore, but we simply lacked the capacity to explore them further.</li>\n</ul>",
      "rawMarkdown": "\n\n- **Repository**: https://github.com/imagination-research/aimo2\n\n- **Models**:\nhttps://huggingface.co/imagination-research/deepseek-14b-sft-dpo4\nhttps://huggingface.co/imagination-research/deepseek-14b-sft-dpo2\nhttps://huggingface.co/imagination-research/deepseek-14b-sft\n\n- **Notebook**: https://www.kaggle.com/code/youyc22/imagination-research-2nd-place-solution/\n\n\n\nThanks to Aimo and Kaggle for hosting this great competition. We are also grateful to all the competitors during the competition and all the open source projects for sharing their great ideas. Now it's time to share our ideas and experiences with the community!\n\n\nOur solution gets the 2nd place. It gets **34/50** on the public leaderboard (ranked **1st**), and **31/50** (ranked **2nd**) on the private leaderboard. \n\n## Solution Summary\n\nThis competition required optimizing both efficiency and reasoning performance. Our final solution consists of three main parts:\n\n* Part I: **Reasoning-Oriented Training** -- *Improve the model's reasoning ability*: Stage 1 - SFT and Stage 2 - DPO with selected data.\n* Part II: **Efficiency Optimization** -- *Improve inference efficiency*: Selecting a suitable inference engine, weight quantization, and KV cache quantization.\n* Part III: **Inference-Time Strategies** -- *Improve efficiency-reasoning performance trade-off*: Prompt design, self-consistency aggregation, sample-level/question-level early stopping, and some heuristic hyperparameter adjusting.\n\nFor local validation, we used the AIME 2025 test set (30 problems) along with the reference set (10 problems), evaluating both average sample accuracy and aggregated accuracy (via self-consistency) to obtain preliminary judgments of our trial solutions.\n\n## Part I: Reasoning-Oriented Training\n\nOur training scripts are based on [`Light-R1`](https://github.com/Qihoo360/Light-R1) project, we are really grateful to their work.\n\n\n### Stage1: SFT\n\nWe choose [`DeepSeek-R1-Distill-Qwen-14B`](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-14B) as the base model considering its great performance in mathematics, coding and reasoning.\n\nWe combine the stage2 data from [`Light-R1`](https://huggingface.co/datasets/qihoo360/Light-R1-SFTData) and training data from [`Limo`](https://huggingface.co/datasets/GAIR/LIMO) together (duplicates removed), which are both high-difficulty math problems' reasoning trajectories generated from deepseek-r1\n\nWe finetune the base model for 8 epochs on single 8×A800 machine, taking 11 hours:\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F641a0798dbca8be9adbf1b010cb49159%2F2e6707889efebafd252bd2ad0443d232.png?generation=1744460831585737&alt=media)\n\nThe accuracy improves but the output length also improves significantly.\n\n### Stage2: DPO\n\nWe use DPO to reduce the output length of the model\n\nWe choose the default subset of [`OpenR1-Math-220k`](https://huggingface.co/datasets/open-r1/OpenR1-Math-220k/tree/main/data) to build our dataset\n\nSpecifically, we try to use the following four criteria to construct DPO pairs (y_w, y_l means chosen response and rejected response):\n\n* **Correctness**: y_w must be correct, y_l may be correct or incorrect\n* **Length ratio**:  len(y_w) < ratio\\_threshold * len(y_l)\n* **Min Length**: len(y_w) > min\\_threshold\n* **Similarity**: sim(y_w,y_l) < sim\\_threshold\n  * use sentence transformer model to calculate embeddings\n\nApplying the first three criteria, we construct the dataset dpo-1, which is used to train the models we submit.\n\nApplying the four criteria, we construct the dataset dpo-2, which is used to train another model, but its performance is similar to the model we submit.\n\nWe use [`360-LLaMA-Factory`](https://github.com/Qihoo360/360-LLaMA-Factory/tree/adfd1708b94a921637c3821bca4a6dd3d81d0387) because they add sequence parallelism (SP) technology to support longer context training with limited memory.\n\nWe use a single 8×A800 machine to train for 4 epochs on dpo-1 dataset(2k pairs), taking 40 hours.\n\nFrom the above process, we get two models we finally submitted:\n**[`deepseek-14b-sft-dpo2`](https://huggingface.co/imagination-research/deepseek-14b-sft-dpo2)** and **[`deepseek-14b-sft-dpo4`](https://huggingface.co/imagination-research/deepseek-14b-sft-dpo4)**\n\nAll our training data can be found here:\n**[`training data`](https://huggingface.co/datasets/imagination-research/aimo2-datasets)**\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fb0a29a66664d9236e04b532fbc0e03c8%2F7187e4e6d0daeae809ac6559ffa3b103.png?generation=1744460986607785&alt=media)\n\n***Note: in the above table, we sample 32 times (direct reasoning 16 times and code solving 16 times) for each question. Pass@1 is computed on AIME 2025 dataset. More details on our inference method are discussed later.***\n\n## Part II: Efficiency Optimization\n\n### Inference Engine\n\nWe choose [`lmdeploy`](https://github.com/InternLM/lmdeploy) as the LLM inference framework. Compared with `vllm`, the `lmdeploy` framework with the TurboMind engine can provide higher throughput and shorter model initialization time.\n\nThe lmdeploy version we use is  0.7.0.post1\n\nThe first picture comes from [`here`](https://github.com/InternLM/lmdeploy)\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F5e8c198ab84475ca77c1b8b27adfcdd9%2F5f126916d91bb2519cb69dd4b3256ef3.png?generation=1744461014286477&alt=media)\n\n### Quantization\n\nWe apply 4-bit AWQ weight quantization, and 8-bit KV Cache quantization (setting the configuration `main_model.inference_cfg.quant_policy` to 8 to use 8-bit KV Cache quantization implemented by `lmdeploy`).\n\nOur two models for submissions can be found here: [model1](https://www.kaggle.com/models/youyc22/dpsk-14b-sft-dpo-3-16-awq-tb/Keras/default), [model2](https://www.kaggle.com/models/youyc22/dpsk-14b-sft-dpo-3-13-awq-tb/Keras/default)\n\n**Some efficiency results**:\n\n* Online test (4xL4, batch size=15): W4KV8 decreases the time per output token by about 20% compared with W4KV16, 55% compared with FP16.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F1f2074a4fa450da09049e99f3d97f2ab%2Fc1af1024b94a2d7511b234b44df1ab6e.png?generation=1744461043302217&alt=media)\n\n* Local test (2xA800, batch size=32): W4KV8, W4KV16 decreases the overall latency by 40% and 20%-25% compared with FP16, respectively.\n\n**Some reasoning performance results**:\n\n* Local test: The average sample accuracy (not aggregated accuracy) drops by 5%~10%, compared with FP16; W4KV8 is not worse than W4KV16. W4KV4 is worse.\n\n\n## Part III: Inference-Time Strategies\n\n### Overall Inference Workflow\n\nThe inference workflow is shown in the figure below: A question is provided as the input. We first prepare two types of prompts, including the CoT prompt and the Code prompt (\"Prompt Preparation Task\"). Then, we let the LLM start batchify generation of multiple samples with `lmdeploy` (\"LLM Generation Task\"). In the mean time, we continuouly try extract the answer from the streaming output of each sample, aggregate the answers of multiple samples, and judge whether to early stop some generation:\n\n1. We do sample-level checking upon every N yields from the iterator got by the `stream_infer(...)` call, and judge whether to early stop the generation of the corresponding sample. The Python code executor and answer extractor components are used here.\n2. We do question-level checking upon the end of every sample, and judge whether to early stop the generation of all remaining samples of the current question. The answer aggregator component is used here.\n\nFinally, we return the aggregated answer.\n\nNote that, for each question, we adjust the speed-related hyperparameters (number of samples, sampling-level max time, question-level early-stop criterion) according to the remaining time, so that the time quota can be allocated in a more balanced way across the remaining questions when the remaining time is limited.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fef0d82c4b38753bb20a279e0f9c84148%2F4ff9e80d8347169f359c9f8a32a7331b.png?generation=1744461072712397&alt=media)\n\n### Prompt Preparation\n\n**Method**:\n\n* Initially, we use 15 samples for one question, and aggregate their answers by self-consistency.\n  * Note that we don't necessarily aggregate the answers of all samples, see [discussions below](#question-level-answer-aggregation--early-stopping) for more details.\n  * Note that we decrease the number of samples when there is limited time left, see [discussions below](#speed-hyperparameter-adjusting) for more details.\n* We use the commonly used code-based reasoning: (1) Prompt the model to provide Python code to solve the problem; (2) Extract Python code from the output, create a subprocess to execute the code; (3) Extract the answer from the execution results.\n* We use two types of prompts - a CoT prompt and a Code prompt. Among 15 samples, 7 samples use the CoT prompt and 8 samples use the Code prompt:\n\n```yaml\n# CoT prompt\n- system: \"You are a helpful math assistant. Please reason step by step to put the answer in \\\\boxed{}.\"\n  user_suffix: \"\\nYou excel at reasoning.\\nYou must put the final answer in \\\\boxed{}.\\nIf the final answer is greater than 1000, then take the modulo of 1000.\\nThink carefully and thoroughly, avoid duplication.\"\n\n# Code prompt\n- system: \"You are a helpful math assistant. Please provide the python code to solve the math problem and also put the final answer in \\\\boxed{}.\"\n  user_suffix: \"\\nYou excel at coding\\nYou must provide the python code, avoid redundant analysis.\\nIf the final answer is greater than 1000, then take the modulo of 1000.\\nThe answer must be integer.\\nThere is only one answer for each question.\\nImport necessary libraries.\"\n```\n\n**Some experiments**:\n\n* System prompt choice: We find diversifying the system prompt doesn't help for reasoning models.\n* Prompt list choice: In the local test, we find only using our Code prompt result in a consistent (across seed and models) and small improvements than using half CoT and half code prompts. However, when we submit this (only once), it doesn't help with the public submission score, thus, we don't further test this empirical choice.\n* Number of samples: In the local test, we find that using 32 samples achieve better results than using 16 samples. However, due to the limited computing power on the submission platform and limited submission quota, we do not thoroughly experiment with more samples on the submission platform to find a sweet point -- we just go with 15 samples.\n* How frequently the code prompt lead to code output, code error, wrong answer (32 samples, 16 CoT Prompts, 16 Code Prompts):\n  * Cases where the code runs correctly but we cannot parse an integer from its output are rare and can be ignored.\n  * **Before fine-tuning**, the model is more inclined to output code: on average, in only 1.9 or 3.3 out of 16 cases where a code prompt is used, the model does not output code.\n  * **After our fine-tuning** with only math data, the model becomes less inclined to output code: on average, in about 11 out of 16 cases, the code prompt does not cause the model to output code. When the new model does output code, its conditional accuracy is slightly higher than the pre-fine-tuning model (45% and 55% vs. 42%).\n\n| Model                                | Quantization | Total solving time | Avg outlen | Aggregated correct questions (/30) | Average correct samples (/32) | Code error break down (/16)                                               |\n| ------------------------------------ | ------------ | ------------------ | ---------- | ---------------------------------- | ----------------------------- | ------------------------------------------------------------------------- |\n| dpsk-qwen-14b                        | KV16         | 11838.22           | 9776.94    | 20.00                              | 14.63                         | No code: 1.93; Exec error: 2.97; Fail parseint: 0.13; Wrong number: 5.30  |\n| dpsk-qwen-14b-awq                    | AWQ4 KV8     | 6844.75            | 10118.54   | 21.00                              | 14.40                         | No code: 3.30; Exec error: 2.53; Fail parseint: 0.33; Wrong number: 4.57  |\n| dpsk-qwen-14b-finetune-v1-epoch4     | KV16         | 12971.18           | 11151.10   | 21.00                              | 18.90                         | No code: 11.00; Exec error: 0.83; Fail parseint: 0.03; Wrong number: 1.43 |\n| dpsk-qwen-14b-finetune-v1-epoch4-awq | AWQ4 KV8     | 7963.94            | 11557.06   | 21.00                              | 16.80                         | No code: 11.07; Exec error: 1.30; Fail parseint: 0.03; Wrong number: 0.90 |\n\n### Sample-level Answer Extraction & Early Stopping\n\n**Motivation**: Usually, the reasoning model will self-doubt a lot after obtaining the answer early, even if it usually gives out the same answer finally. And in most cases, after giving the answer between `<think></think>`, the model will rewrite the solution again (at least twice). Can we reduce the wasting of tokens?\n\n**Method**: Although we experimented with the active probing method from \"Fu et al., \"Efficiently Serving LLM Reasoning Programs with Certaindex, arXiv 2412\", we ultimately adopted a much simpler sample-level early stopping technique to simplify our inference workflow. Specifically, once we detect either the first successfully executable code or the first answer in \"\\\\boxed{...}\", we stop the generation process for that sample.\n\n**Some experiments**: A natural question is whether this might harm the potential to revise an initially incorrect answer into a correct one later. In our local tests, we use [`scripts/analyze_early_stop.py`](https://github.com/imagination-research/aimo2) to verify that such cases are relatively rare, as shown in the figure below.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fe0046e83f954d42e3133ea88947b4b89%2Fdc372cc270acc1d5dc01f37c533e0bc8.png?generation=1744461139162863&alt=media)\n\n### Question-level Answer Aggregation & Early Stopping\n\nWe use the commonly used self-consistency method for answer aggregation. We use a question-level early-stop strategy as follows.\n\n**Motivation**: The difficulty varies across problems, so we aim to avoid spending too much time on easy ones. As shown in the figure below, the output length varies considerably across samples for a single problem. This suggests that for some problems, we may obtain several correct answers early on but still need to wait for the longest sample to finish -- resulting in significant time waste (e.g., q1, q11, q16–q20, etc.).\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Ff42ad387359f025fcd84406d2522fc07%2F4856497485f90b1ee37ee3d907f90419.png?generation=1744461161694426&alt=media)\n\n**Method**: We can stop generation early for a question if sufficient certainty is achieved by examining the existing answers. Specifically, we terminate generation at the question level when a majority of the outputs are consistent, e.g., if 5 out of 7 answers agree. See the configurations in `early_stop_strategy.consistency_rules` in [`imagination_aimo2/local_eval_kaggle.py`](https://github.com/imagination-research/aimo2).\n\n### Speed Hyperparameter Adjusting\n\n**Motivation**: The time to solve questions of different difficulty levels varies greatly, we design a `adjust_speed` module to dynamically adjust some hyperparameters.\n\n**Method**: As reasoning progresses, our `adjust_speed` module calculates the remaining time and number of remaining questions, and dynamically adjusts the model's sampling number and early stopping strategy accordingly.\n\nFor example, the default speed is `3(normal)`, if the system detects that the average remaining time for each question is less than 5 minutes, it automatically adjust the speed to `1(fastest)` .This means the number of samples is decreased to 10 and the maximum reasoning time for each question is also decreased. Please refer to our code for detailed implementation.\n\n## Other methods we tried but did not reach a conclusion and include in our final solution\n- GRPO: we tried four training runs but did not observe significant improvement on accuracy.\n\n- RAG: we use this [dataset](https://www.kaggle.com/datasets/artemgoncarov/math-problems-imo) as a document bank. When solving a question, we fetch 1~2 most similar questions from the bank, use them and their corresponding solutions as the few-shot demonstrations. But we did not get improvement on AIME2025 nor online submission. \n\n- Model-based Aggregation: We give the LLM the 5 most frequent answers, and one representatitive rationale for each, ask the LLM to reason about the correct answer. But this aggregation method cannot stably achieve improvements. \n\n- Quantization-related trials: We try quantization-aware training (QAT) by finetuning the scales of an AWQ-quantized model with DPO on our 2k-sized DPO dataset, but that doesn't bring improvement. We also try to apply the reparametrization of `W_k` and `W_q` to get more channel-balanced key for better KV cache quantization. This brings a consistent but small reasoning performance improvement in our local test, especially in the KV4 setting. However, as we don't have enough submission quota to tune other hyperparameters for KV4 setting, our final solution doesn't use KV4.\n\nWe decided to briefly share these preliminary trials, but please note that they are not thorough enough to provide a reliable negative signal. Our qualitative inspection of the above trials actually suggests potentials to further explore, but we simply lacked the capacity to explore them further.\n\n",
      "votes": 111
    },
    {
      "id": 3177240,
      "postDate": "2025-04-12T13:21:32.640Z",
      "content": "<p>Impressive work! A well-structured and innovative approach—great balance of reasoning optimization and inference efficiency. Congrats on the 2nd place win! 👏</p>",
      "rawMarkdown": "Impressive work! A well-structured and innovative approach—great balance of reasoning optimization and inference efficiency. Congrats on the 2nd place win! 👏",
      "votes": 3
    },
    {
      "id": 3177636,
      "postDate": "2025-04-13T04:45:06.333Z",
      "content": "<p>Congratulations!</p>\n<p>I have to say this is one of the best solution write-ups I've ever read on Kaggle.</p>",
      "rawMarkdown": "Congratulations!\n\nI have to say this is one of the best solution write-ups I've ever read on Kaggle.",
      "votes": 4,
      "replies": [
        {
          "id": 3177645,
          "postDate": "2025-04-13T05:02:26.983Z",
          "content": "<p>Thanks a million!</p>",
          "rawMarkdown": "Thanks a million!",
          "votes": 1
        }
      ]
    },
    {
      "id": 3179861,
      "postDate": "2025-04-15T19:41:57.103Z",
      "content": "<p>Congratulations to your team and thanks for this amazing write-up! I learnt a lot from your post-decision processing. I have one question regarding your training process, the training data extract and built from Limo and openr1-math-220k is simply chain-of-thought prompt (given the math problem, respond with chain-of-thought and solution and python code is not required). In the last year, the top2 winner from aimo both applies tora corpus and tool-integrated training examples. May I ask what's your opinion and suggestion regarding tora corpus training and why this is not considered in your solution. Thanks! </p>",
      "rawMarkdown": "Congratulations to your team and thanks for this amazing write-up! I learnt a lot from your post-decision processing. I have one question regarding your training process, the training data extract and built from Limo and openr1-math-220k is simply chain-of-thought prompt (given the math problem, respond with chain-of-thought and solution and python code is not required). In the last year, the top2 winner from aimo both applies tora corpus and tool-integrated training examples. May I ask what's your opinion and suggestion regarding tora corpus training and why this is not considered in your solution. Thanks! ",
      "votes": 1,
      "replies": [
        {
          "id": 3183591,
          "postDate": "2025-04-21T03:41:19.140Z",
          "content": "<p>Thanks! We did not find a suitable dataset (solving math problems with Python code), and when we tried to use deepseek-r1, we found it difficult to use prompts to let the model solve math problems with code (it always tends to think directly);I think if you use tool integration training, there will be further improvement in our problem-solving framework.</p>",
          "rawMarkdown": "Thanks! We did not find a suitable dataset (solving math problems with Python code), and when we tried to use deepseek-r1, we found it difficult to use prompts to let the model solve math problems with code (it always tends to think directly);I think if you use tool integration training, there will be further improvement in our problem-solving framework.",
          "votes": 1
        }
      ]
    },
    {
      "id": 3177382,
      "postDate": "2025-04-12T16:43:20.640Z",
      "content": "<p>great work! Thanks for sharing! Your work make this competition more meaningful, it is the real value of this competition! Really thanks for sharing. Thanks kaggle and organizer <a href=\"https://www.kaggle.com/friederrr\" target=\"_blank\">@friederrr</a> !</p>",
      "rawMarkdown": "great work! Thanks for sharing! Your work make this competition more meaningful, it is the real value of this competition! Really thanks for sharing. Thanks kaggle and organizer @friederrr !",
      "votes": 1
    },
    {
      "id": 3177301,
      "postDate": "2025-04-12T14:45:37.167Z",
      "content": "<p>First of all, congratulations to your team — you guys have built a great pipeline!<br>\nCan I ask how you converted the models to <code>triton_models format</code>, because I didn’t see that code anywhere?</p>",
      "rawMarkdown": "First of all, congratulations to your team — you guys have built a great pipeline!\nCan I ask how you converted the models to `triton_models format`, because I didn’t see that code anywhere?",
      "votes": 1,
      "replies": [
        {
          "id": 3177310,
          "postDate": "2025-04-12T14:57:25.890Z",
          "content": "<p>We have updated: <a href=\"https://github.com/imagination-research/aimo2/blob/master/scripts/run_convert.sh\" target=\"_blank\">https://github.com/imagination-research/aimo2/blob/master/scripts/run_convert.sh</a></p>",
          "rawMarkdown": "We have updated: https://github.com/imagination-research/aimo2/blob/master/scripts/run_convert.sh",
          "votes": 1
        }
      ]
    },
    {
      "id": 3177243,
      "postDate": "2025-04-12T13:25:44.680Z",
      "content": "<p>Congrats on the great pipeline! 🙌</p>\n<p>I’m curious about your choice of 8 epochs for SFT. Given that Light-R1 and LIMO are high-quality datasets, I would think that more epochs might lead to additional improvements, similar to how transfer learning benefits from extended training on refined data.</p>\n<p>This reminds me of the Phi-4 technical report, where increasing epochs on synthetic data significantly boosted performance - more than just adding mixed lower-quality (web) data. Did you consider this approach, or was the optimal stopping point determined purely by validation performance?</p>\n<p>Also, using DPO to control response length is actually a wise strategy, especially with the challenges of unstable RL training for concise and effective reasoning!</p>\n<p>Big congrats again!</p>",
      "rawMarkdown": "Congrats on the great pipeline! 🙌\n\nI’m curious about your choice of 8 epochs for SFT. Given that Light-R1 and LIMO are high-quality datasets, I would think that more epochs might lead to additional improvements, similar to how transfer learning benefits from extended training on refined data.\n\nThis reminds me of the Phi-4 technical report, where increasing epochs on synthetic data significantly boosted performance - more than just adding mixed lower-quality (web) data. Did you consider this approach, or was the optimal stopping point determined purely by validation performance?\n\nAlso, using DPO to control response length is actually a wise strategy, especially with the challenges of unstable RL training for concise and effective reasoning!\n\nBig congrats again!",
      "votes": 1,
      "replies": [
        {
          "id": 3177314,
          "postDate": "2025-04-12T15:00:38.327Z",
          "content": "<p>We found that fine-tuning too many epochs will significantly increase the output length of the model. 8 epochs is enough.</p>",
          "rawMarkdown": "We found that fine-tuning too many epochs will significantly increase the output length of the model. 8 epochs is enough.",
          "votes": 5
        }
      ]
    },
    {
      "id": 3183920,
      "postDate": "2025-04-21T12:47:25.043Z",
      "content": "<p>Thanks Guys for sharing your all analysis on this competition , the thing u tried i done some of them but due to lack of knowledge i got confused and this was my 1st competition , yet i dont submitted on this competition , but i have an idea like why can we make a ai maths agent which would think like a general mathematian ( find whats given , what to find , how to find , any formulas/theorem ets)… like that , i have a idea to make a ramanujam model which can answer the best of any , just i need knowlege and a better can we make this , and i forget to say , \"Congrats Guys\" , here is my email: <a href=\"mailto:shindevinayak233@gmail.com\">shindevinayak233@gmail.com</a> reach me out there and here is linkedin :<br>\n<a href=\"url\" target=\"_blank\">https://www.linkedin.com/in/vinayak-shinde-1aa968223/</a> , Thanks for that Idea</p>",
      "rawMarkdown": "Thanks Guys for sharing your all analysis on this competition , the thing u tried i done some of them but due to lack of knowledge i got confused and this was my 1st competition , yet i dont submitted on this competition , but i have an idea like why can we make a ai maths agent which would think like a general mathematian ( find whats given , what to find , how to find , any formulas/theorem ets)... like that , i have a idea to make a ramanujam model which can answer the best of any , just i need knowlege and a better can we make this , and i forget to say , \"Congrats Guys\" , here is my email: shindevinayak233@gmail.com reach me out there and here is linkedin :\n[https://www.linkedin.com/in/vinayak-shinde-1aa968223/](url) , Thanks for that Idea"
    },
    {
      "id": 3177932,
      "postDate": "2025-04-13T13:34:58.913Z",
      "content": "<p>Congratulations to your team, and thanks for the amazing write-up! One of the most thoughtful and clever solution I've ever seen on Kaggle. The attention to details and the effort your team has put into your solution is insane!</p>\n<p>The effort and attention to the inference strategies of your team is truly next level!</p>\n<hr>\n<p>I tried to evaluate your <code>deepseek-14b-sft-dpo4</code> model on AIME'25, in BF16, with 64 rollouts per prompt, max_len is 32768 tokens, temperature 0.75 and top_p 0.95. I made sure that the prompt I'm using is the same as your CoT prompt, for example:</p>\n<pre><code>&lt;｜begin▁of▁sentence｜&gt;You are a helpful math assistant. Please reason step by step to put the answer in \\boxed{}.&lt;｜User｜&gt;Find the sum of the roots of the equation $x^2 - 6x + 9 = 0$. \nYou excel at reasoning.\nYou must put the final answer in \\boxed{}.\nIf the final answer is greater than1000, then take the modulo of 1000.\nThink carefully and thoroughly, avoid duplication.&lt;｜Assistant｜&gt;\n</code></pre>\n<p>However, here are my numbers (your model is last column):</p>\n<table>\n<thead>\n<tr>\n<th></th>\n<th>DeepSeek-R1-Distill-14B</th>\n<th>Light-R1-14B-DS</th>\n<th>One of our team's GRPO</th>\n<th>2nd-Place-DPO4</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>accuracy</td>\n<td>0.484896</td>\n<td>0.581771</td>\n<td>0.542188</td>\n<td>0.557813</td>\n</tr>\n<tr>\n<td>avg_len</td>\n<td>13071.5</td>\n<td>13827.4</td>\n<td>11274.5</td>\n<td>12183</td>\n</tr>\n<tr>\n<td>maj@5</td>\n<td>0.591667</td>\n<td>0.679167</td>\n<td>0.695833</td>\n<td>0.679167</td>\n</tr>\n<tr>\n<td>maj@8</td>\n<td>0.591667</td>\n<td>0.7</td>\n<td>0.7125</td>\n<td>0.679167</td>\n</tr>\n<tr>\n<td>maj@12</td>\n<td>0.6125</td>\n<td>0.716667</td>\n<td>0.741667</td>\n<td>0.708333</td>\n</tr>\n</tbody>\n</table>\n<p>PS: the majority voting accuracy <code>maj@k</code> numbers are averaged over multiple \"virtual\" runs, where I sample traces from a bank of reasoning traces (64 to be exact).</p>\n<p>My numbers for Deepseek-R1-14B and Light-R1-14B matches the reported numbers. But your model's accuracy in my tests is <code>0.558</code> (averaged over 64 rollouts per problem), but you reported <code>0.589</code>. Was that number pure COT performance or it's mixed with TIR?</p>",
      "rawMarkdown": "Congratulations to your team, and thanks for the amazing write-up! One of the most thoughtful and clever solution I've ever seen on Kaggle. The attention to details and the effort your team has put into your solution is insane!\n\nThe effort and attention to the inference strategies of your team is truly next level!\n\n-------------------------\n\nI tried to evaluate your `deepseek-14b-sft-dpo4` model on AIME'25, in BF16, with 64 rollouts per prompt, max_len is 32768 tokens, temperature 0.75 and top_p 0.95. I made sure that the prompt I'm using is the same as your CoT prompt, for example:\n```text\n<｜begin▁of▁sentence｜>You are a helpful math assistant. Please reason step by step to put the answer in \\boxed{}.<｜User｜>Find the sum of the roots of the equation $x^2 - 6x + 9 = 0$. \nYou excel at reasoning.\nYou must put the final answer in \\boxed{}.\nIf the final answer is greater than1000, then take the modulo of 1000.\nThink carefully and thoroughly, avoid duplication.<｜Assistant｜>\n```\n\nHowever, here are my numbers (your model is last column):\n\n|                   |   DeepSeek-R1-Distill-14B |   Light-R1-14B-DS |   One of our team's GRPO |   2nd-Place-DPO4 |\n|:------------------|--------------------------:|------------------:|--------------------:|-------------------:|\n| accuracy          |                  0.484896 |          0.581771 |            0.542188 |           0.557813 |\n| avg_len           |              13071.5      |      13827.4      |        11274.5      |       12183        |\n| maj@5             |                  0.591667 |          0.679167 |            0.695833 |           0.679167 |\n| maj@8             |                  0.591667 |          0.7      |            0.7125   |           0.679167 |\n| maj@12            |                  0.6125   |          0.716667 |            0.741667 |           0.708333 |\n\nPS: the majority voting accuracy `maj@k` numbers are averaged over multiple \"virtual\" runs, where I sample traces from a bank of reasoning traces (64 to be exact).\n\nMy numbers for Deepseek-R1-14B and Light-R1-14B matches the reported numbers. But your model's accuracy in my tests is `0.558` (averaged over 64 rollouts per problem), but you reported `0.589`. Was that number pure COT performance or it's mixed with TIR?",
      "votes": 2,
      "replies": [
        {
          "id": 3177938,
          "postDate": "2025-04-13T13:49:16.423Z",
          "content": "<p>Thanks! This number is mixed with TIR, so pure COT may be lower, we mentioned it here.<br>\nBesides, we applied the sample-level early stop strategy (as we mentioned) for evaluation.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F691182fd63eb695112d9d70135e6a5a3%2F92241a106152d3a12616bdbe40d76631.png?generation=1744552045434973&amp;alt=media\" alt=\"\"></p>",
          "rawMarkdown": "Thanks! This number is mixed with TIR, so pure COT may be lower, we mentioned it here.\nBesides, we applied the sample-level early stop strategy (as we mentioned) for evaluation.\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2F691182fd63eb695112d9d70135e6a5a3%2F92241a106152d3a12616bdbe40d76631.png?generation=1744552045434973&alt=media)",
          "votes": 3,
          "replies": [
            {
              "id": 3177939,
              "postDate": "2025-04-13T13:51:51.907Z",
              "content": "<p>Thanks, that makes a lot more sense. Now I feel silly for even trying your model with CoT only 😅</p>",
              "rawMarkdown": "Thanks, that makes a lot more sense. Now I feel silly for even trying your model with CoT only 😅",
              "votes": 1
            }
          ]
        }
      ]
    },
    {
      "id": 3182290,
      "postDate": "2025-04-19T04:47:08.450Z",
      "content": "<p>Very impressive thought &amp; solution.</p>",
      "rawMarkdown": "Very impressive thought & solution."
    },
    {
      "id": 3180988,
      "postDate": "2025-04-17T10:52:08.413Z",
      "content": "<p>Congratulations.  Thanks for the write-up &amp; excellent plots!<br>\nI have one question after read the quant_awq.py code.<br>\nThe default max_calib_seq_len of autoawq is 512. What's the reason for choosing max_calib_seq_len=128 &amp; max_calib_samples=1024? </p>",
      "rawMarkdown": "Congratulations.  Thanks for the write-up & excellent plots!\nI have one question after read the quant_awq.py code.\nThe default max_calib_seq_len of autoawq is 512. What's the reason for choosing max_calib_seq_len=128 & max_calib_samples=1024? ",
      "replies": [
        {
          "id": 3183537,
          "postDate": "2025-04-21T01:05:46.853Z",
          "content": "<p>Well done!</p>",
          "rawMarkdown": "Well done!"
        }
      ]
    },
    {
      "id": 3180684,
      "postDate": "2025-04-17T02:12:16.843Z",
      "content": "<p>After spending hours reading the notebook and codes, I am still confused. Can you please share the original notebook used to submit for the private LB?</p>",
      "rawMarkdown": "After spending hours reading the notebook and codes, I am still confused. Can you please share the original notebook used to submit for the private LB?",
      "replies": [
        {
          "id": 3180699,
          "postDate": "2025-04-17T02:39:40.807Z",
          "content": "<p>This backup notebook is <strong>exactly the same as</strong> the notebook we finally scored 31, there may be some irregularities in the writing, we still recommend you to read our cleaned version, which is more structured.<br>\n<a href=\"https://github.com/imagination-research/aimo2/blob/master/imagination_aimo2/backup_submission.ipynb\" target=\"_blank\">https://github.com/imagination-research/aimo2/blob/master/imagination_aimo2/backup_submission.ipynb</a></p>",
          "rawMarkdown": "This backup notebook is **exactly the same as** the notebook we finally scored 31, there may be some irregularities in the writing, we still recommend you to read our cleaned version, which is more structured.\nhttps://github.com/imagination-research/aimo2/blob/master/imagination_aimo2/backup_submission.ipynb",
          "votes": 2,
          "replies": [
            {
              "id": 3181313,
              "postDate": "2025-04-17T17:57:02.227Z",
              "content": "<p>Thanks you.</p>",
              "rawMarkdown": "Thanks you."
            },
            {
              "id": 3181491,
              "postDate": "2025-04-18T00:34:41.533Z",
              "content": "<p>version112 got 33/31 on public/private leaderboard and version94 got 34/29.<br>\n<a href=\"https://www.kaggle.com/code/youyc22/imagination-research-original-submission\" target=\"_blank\">https://www.kaggle.com/code/youyc22/imagination-research-original-submission</a><br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fd22cae24037ff5ebd06f0bf30918e69c%2Fc08c0758b2569345f9507f101ca9b13a.png?generation=1744936765179862&amp;alt=media\" alt=\"\"></p>",
              "rawMarkdown": "version112 got 33/31 on public/private leaderboard and version94 got 34/29.\nhttps://www.kaggle.com/code/youyc22/imagination-research-original-submission\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fd22cae24037ff5ebd06f0bf30918e69c%2Fc08c0758b2569345f9507f101ca9b13a.png?generation=1744936765179862&alt=media)",
              "votes": 2
            },
            {
              "id": 3181526,
              "postDate": "2025-04-18T02:25:03.740Z",
              "content": "<p>Thank you for sharing this notebook🙂</p>",
              "rawMarkdown": "Thank you for sharing this notebook🙂"
            }
          ]
        }
      ]
    },
    {
      "id": 3179940,
      "postDate": "2025-04-16T00:12:56.353Z",
      "content": "<p>Congratulations! I copied your notebook and run it in Kaggle. The program was terminated very quickly, leaving only the following reply. Is it not possible to run it directly on Kaggle?</p>\n<p>2025-04-15 23:52:14,096 - lmdeploy - WARNING - supported_models.py:106 - /kaggle/input/dpsk-14b-sft-dpo-3-13-awq-tb/keras/default/1/dpsk-14b-sft-dpo4-3-13-awq-tb seems to be a turbomind workspace, which can only be ran with turbomind engine.<br>\n[TM][WARNING] [LlamaTritonModel] <code>max_context_token_num</code> is not set, default to 33320.<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n[WARNING] gemm_config.in is not found; using default GEMM algo<br>\n2025-04-15 23:53:08,504 - lmdeploy - WARNING - tokenizer.py:647 - The token &lt;|endoftext|&gt;, its length of indexes [27, 91, 8691, 723, 427, 91, 29] is over than 1. Currently, it can not be used as stop words<br>\nUpdated active prompts. Target: 15, Actual: 15<br>\nbbd91e<br>\n057f8a<br>\n192e23<br>\n1fce4b<br>\n71beb6<br>\n1acac0<br>\na1d40b<br>\n88c219<br>\n480182<br>\n349493</p>",
      "rawMarkdown": "Congratulations! I copied your notebook and run it in Kaggle. The program was terminated very quickly, leaving only the following reply. Is it not possible to run it directly on Kaggle?\n\n2025-04-15 23:52:14,096 - lmdeploy - WARNING - supported_models.py:106 - /kaggle/input/dpsk-14b-sft-dpo-3-13-awq-tb/keras/default/1/dpsk-14b-sft-dpo4-3-13-awq-tb seems to be a turbomind workspace, which can only be ran with turbomind engine.\n[TM][WARNING] [LlamaTritonModel] `max_context_token_num` is not set, default to 33320.\n[WARNING] gemm_config.in is not found; using default GEMM algo\n[WARNING] gemm_config.in is not found; using default GEMM algo\n[WARNING] gemm_config.in is not found; using default GEMM algo\n[WARNING] gemm_config.in is not found; using default GEMM algo\n2025-04-15 23:53:08,504 - lmdeploy - WARNING - tokenizer.py:647 - The token <|endoftext|>, its length of indexes [27, 91, 8691, 723, 427, 91, 29] is over than 1. Currently, it can not be used as stop words\nUpdated active prompts. Target: 15, Actual: 15\nbbd91e\n057f8a\n192e23\n1fce4b\n71beb6\n1acac0\na1d40b\n88c219\n480182\n349493",
      "replies": [
        {
          "id": 3179997,
          "postDate": "2025-04-16T02:19:59.360Z",
          "content": "<p>Thanks! You need to comment out the first three lines in predict function<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fd4c766569358a8e6ef6caef86d98f06d%2Feb2e127fcc17081930a6e5bcbccdafd5.png?generation=1744769914560504&amp;alt=media\" alt=\"\"></p>",
          "rawMarkdown": "Thanks! You need to comment out the first three lines in predict function![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fd4c766569358a8e6ef6caef86d98f06d%2Feb2e127fcc17081930a6e5bcbccdafd5.png?generation=1744769914560504&alt=media)",
          "replies": [
            {
              "id": 3180040,
              "postDate": "2025-04-16T03:53:45.987Z",
              "content": "<p>It works. Thank you very much. The outputs are so detailed👍</p>",
              "rawMarkdown": "It works. Thank you very much. The outputs are so detailed👍"
            }
          ]
        },
        {
          "id": 3213597,
          "postDate": "2025-05-30T08:12:20.890Z",
          "rawMarkdown": "",
          "isDeleted": true
        }
      ]
    },
    {
      "id": 3179762,
      "postDate": "2025-04-15T16:48:46.030Z",
      "content": "<p>Impressive thoughts and solution.</p>",
      "rawMarkdown": "Impressive thoughts and solution."
    },
    {
      "id": 3179704,
      "postDate": "2025-04-15T15:59:29.057Z",
      "content": "<p>Thanks for sharing your solution. It was very helpful .</p>",
      "rawMarkdown": "Thanks for sharing your solution. It was very helpful ."
    },
    {
      "id": 3178493,
      "postDate": "2025-04-14T08:53:59.600Z",
      "content": "<p>Congratulations to your team, and thank you for the excellent paper! I’ve learned a lot from it! Would it be possible for you to share the code for the SFT stage or the DPO stage? I’d be very grateful if you could—I'd love to study and learn more about it!</p>",
      "rawMarkdown": "Congratulations to your team, and thank you for the excellent paper! I’ve learned a lot from it! Would it be possible for you to share the code for the SFT stage or the DPO stage? I’d be very grateful if you could—I'd love to study and learn more about it!",
      "replies": [
        {
          "id": 3178564,
          "postDate": "2025-04-14T10:31:25.723Z",
          "content": "<p>Thanks. We use 360-LLama-Factory's code (a git submodule in our repository) to run SFT and DPO. You can check our repository <a href=\"https://github.com/imagination-research/aimo2\" target=\"_blank\">https://github.com/imagination-research/aimo2</a>, the scripts are given at <code>scripts/run_sft.sh</code> and <code>scripts/run_dpo.sh</code>.</p>",
          "rawMarkdown": "Thanks. We use 360-LLama-Factory's code (a git submodule in our repository) to run SFT and DPO. You can check our repository https://github.com/imagination-research/aimo2, the scripts are given at `scripts/run_sft.sh` and `scripts/run_dpo.sh`."
        }
      ]
    },
    {
      "id": 3178404,
      "postDate": "2025-04-14T05:58:53.590Z",
      "content": "<p>Congratulations!! This is really great, the way it's written is soo clean and it's spelled out well. For sure your work would be used to build and iterate in the future competitions. <br>\nI have a couple of questions though:<br>\nUpon the completion of the training, did your team think that 8 epochs is a bit too much or what is appropriately enough?<br>\nAnd can you share the training losses you got while fine tuning if possible :)</p>\n<p>And I wanted to ask in general, I see that everyone uses both the system and user role in their prompts. But the model card in huggingface says this thing below. Did you experiment by putting the instruction+question in the user role and ditching the system role? I went through your repo (which is really cool btw) and I can see that you used both the roles. Any specific reason? I mean pretty much everyone did this too, I really want to know what's this about. </p>\n<pre><code>Usage Recommendations\nWe recommend adhering   following configurations when utilizing  DeepSeek-R1 series models, including benchmarking,  achieve  expected performance:\n\nAvoid adding   prompt; all instructions should be contained   user prompt.\n</code></pre>",
      "rawMarkdown": "Congratulations!! This is really great, the way it's written is soo clean and it's spelled out well. For sure your work would be used to build and iterate in the future competitions. \nI have a couple of questions though:\nUpon the completion of the training, did your team think that 8 epochs is a bit too much or what is appropriately enough?\nAnd can you share the training losses you got while fine tuning if possible :)\n\nAnd I wanted to ask in general, I see that everyone uses both the system and user role in their prompts. But the model card in huggingface says this thing below. Did you experiment by putting the instruction+question in the user role and ditching the system role? I went through your repo (which is really cool btw) and I can see that you used both the roles. Any specific reason? I mean pretty much everyone did this too, I really want to know what's this about. \n \n```\nUsage Recommendations\nWe recommend adhering to the following configurations when utilizing the DeepSeek-R1 series models, including benchmarking, to achieve the expected performance:\n\nAvoid adding a system prompt; all instructions should be contained within the user prompt.\n```\n\n",
      "replies": [
        {
          "id": 3178568,
          "postDate": "2025-04-14T10:39:57.770Z",
          "content": "<p>Thanks!</p>\n<p>About Q1, 8-epoch SFT is appropriately enough in our case. More epochs will lead to longer token length.</p>\n<p>About Q3, thank you for letting us to know this note. We don't know this note, so we are just following early practice of using both the system prompt and user prompt.</p>\n<p>About Q2, I need to ping Yichen to plot the loss curve <a href=\"https://www.kaggle.com/youyc22\" target=\"_blank\">@youyc22</a> </p>",
          "rawMarkdown": "Thanks!\n\nAbout Q1, 8-epoch SFT is appropriately enough in our case. More epochs will lead to longer token length.\n\nAbout Q3, thank you for letting us to know this note. We don't know this note, so we are just following early practice of using both the system prompt and user prompt.\n\nAbout Q2, I need to ping Yichen to plot the loss curve @youyc22 ",
          "votes": 1
        },
        {
          "id": 3178571,
          "postDate": "2025-04-14T10:46:27.350Z",
          "content": "<p>SFT loss curve is as follows</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fde64ae59cdb37dfe61fc77bef5508759%2Fd132ee85970b588f4e7070d91ea47d9b.png?generation=1744627553753428&amp;alt=media\" alt=\"\"></p>",
          "rawMarkdown": "SFT loss curve is as follows\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F23572158%2Fde64ae59cdb37dfe61fc77bef5508759%2Fd132ee85970b588f4e7070d91ea47d9b.png?generation=1744627553753428&alt=media)",
          "votes": 3,
          "replies": [
            {
              "id": 3178595,
              "postDate": "2025-04-14T11:16:07.643Z",
              "rawMarkdown": "",
              "isDeleted": true
            }
          ]
        }
      ]
    },
    {
      "id": 3178126,
      "postDate": "2025-04-13T18:42:58.157Z",
      "content": "<p>Congratulations! Great job!<br>\nHave you tried model merging ?</p>",
      "rawMarkdown": "Congratulations! Great job!\nHave you tried model merging ?",
      "replies": [
        {
          "id": 3178308,
          "postDate": "2025-04-14T02:57:17.360Z",
          "content": "<p>We have tried model merging, between the two checkpoints and another checkpoint of a new DPO run. We can get an FP16 model that has a slightly higher average sample accuracy and an obviously higher (+2/+3 out of 30 problems) aggregated accuracy in our local test. However, when quantized, the model is no better than the original quantized checkpoints in the local test, and as the submission quota is limited to test multiple time of that model, we didn't submit it.</p>",
          "rawMarkdown": "We have tried model merging, between the two checkpoints and another checkpoint of a new DPO run. We can get an FP16 model that has a slightly higher average sample accuracy and an obviously higher (+2/+3 out of 30 problems) aggregated accuracy in our local test. However, when quantized, the model is no better than the original quantized checkpoints in the local test, and as the submission quota is limited to test multiple time of that model, we didn't submit it."
        }
      ]
    },
    {
      "id": 3177948,
      "postDate": "2025-04-13T14:23:05.743Z",
      "content": "<p>Can you share your original winning submission notebook. (Do understand the cleaned version could be similar but community might be able to learn something from the original one)</p>",
      "rawMarkdown": "Can you share your original winning submission notebook. (Do understand the cleaned version could be similar but community might be able to learn something from the original one)"
    },
    {
      "id": 3177891,
      "postDate": "2025-04-13T12:14:56.563Z",
      "content": "<p>Fantastic work! I would love to see more of it!</p>",
      "rawMarkdown": "Fantastic work! I would love to see more of it!\n"
    },
    {
      "id": 3177723,
      "postDate": "2025-04-13T07:23:50.573Z",
      "content": "<p>最实至名归的一集。从前至后各阶段的实验安排条理清晰，模型提升的方法思路很让人受启发。期待你们下一次取得更好的成绩💪。<br>\n羡慕8块A800啊，穷人真是玩不起大模型😂</p>",
      "rawMarkdown": "最实至名归的一集。从前至后各阶段的实验安排条理清晰，模型提升的方法思路很让人受启发。期待你们下一次取得更好的成绩💪。\n羡慕8块A800啊，穷人真是玩不起大模型😂",
      "replies": [
        {
          "id": 3177727,
          "postDate": "2025-04-13T07:28:44.427Z",
          "content": "<p>Thanks a lot!<br>\n感谢支持！</p>",
          "rawMarkdown": "Thanks a lot!\n感谢支持！"
        }
      ]
    },
    {
      "id": 3177718,
      "postDate": "2025-04-13T07:11:20.517Z",
      "content": "<p>Congratulations!</p>\n<ol>\n<li><p>Can you provide the data deduplication script for dataset duplicates removal?</p></li>\n<li><p>Please share the FP16 model weight for Stage 1 SFT as well as Stage 2 DPO similar to the way AIMO1 winner did it.<br>\n<a href=\"https://huggingface.co/AI-MO\" target=\"_blank\">https://huggingface.co/AI-MO</a></p></li>\n</ol>",
      "rawMarkdown": "Congratulations!\n1. Can you provide the data deduplication script for dataset duplicates removal?\n\n2. Please share the FP16 model weight for Stage 1 SFT as well as Stage 2 DPO similar to the way AIMO1 winner did it.\nhttps://huggingface.co/AI-MO",
      "replies": [
        {
          "id": 3177790,
          "postDate": "2025-04-13T09:29:07.680Z",
          "content": "<p>We have updated here:<a href=\"https://github.com/imagination-research/aimo2/blob/master/scripts/run_deduplicate.sh\" target=\"_blank\">https://github.com/imagination-research/aimo2/blob/master/scripts/run_deduplicate.sh</a></p>\n<p>Stage2 DPO model can be found on huggingface:<a href=\"https://huggingface.co/collections/imagination-research/aimo2-67f92097e2a4e04d995f3d75\" target=\"_blank\">https://huggingface.co/collections/imagination-research/aimo2-67f92097e2a4e04d995f3d75</a>, which can be found at the beginning of our write-up</p>\n<p>Stage1 SFT model will be uploaded sooner</p>",
          "rawMarkdown": "We have updated here:https://github.com/imagination-research/aimo2/blob/master/scripts/run_deduplicate.sh\n\nStage2 DPO model can be found on huggingface:https://huggingface.co/collections/imagination-research/aimo2-67f92097e2a4e04d995f3d75, which can be found at the beginning of our write-up\n\nStage1 SFT model will be uploaded sooner",
          "votes": 1
        }
      ]
    },
    {
      "id": 3177560,
      "postDate": "2025-04-13T01:09:37.850Z",
      "content": "<p>Congrats! Such a beautiful and well-designed solution.<br>\nDo you have records of how Public LB improved after each tranining step?</p>",
      "rawMarkdown": "Congrats! Such a beautiful and well-designed solution.\nDo you have records of how Public LB improved after each tranining step?",
      "replies": [
        {
          "id": 3177598,
          "postDate": "2025-04-13T02:52:10.743Z",
          "content": "<p>Thanks! We got <code>28</code> without any finetuning, scored <code>33</code> after sft (8 epochs) and dpo (2 epochs), scored <code>34</code> after dpo for 4 epochs(ranging between 32~34). We didn't submit the model that only had SFT applied.</p>",
          "rawMarkdown": "Thanks! We got `28` without any finetuning, scored `33` after sft (8 epochs) and dpo (2 epochs), scored `34` after dpo for 4 epochs(ranging between 32~34). We didn't submit the model that only had SFT applied.",
          "votes": 5
        }
      ]
    },
    {
      "id": 3177531,
      "postDate": "2025-04-12T23:03:14.350Z",
      "content": "<p>This is an absolutely remarkable solution, and thank you more for sharing your approach to improve the quality of future contributions in the field. Looking forward to more works from you</p>",
      "rawMarkdown": "This is an absolutely remarkable solution, and thank you more for sharing your approach to improve the quality of future contributions in the field. Looking forward to more works from you"
    },
    {
      "id": 3177335,
      "postDate": "2025-04-12T15:43:50.377Z",
      "content": "<p>Congrats! What was the score with the stage 1 SFT model and did DPO give significant improvement over it?</p>",
      "rawMarkdown": "Congrats! What was the score with the stage 1 SFT model and did DPO give significant improvement over it?",
      "replies": [
        {
          "id": 3177599,
          "postDate": "2025-04-13T02:55:24.770Z",
          "content": "<p>Thanks! We didn't submit the stage 1 SFT model, base model got <code>28</code>, dpo-2 got <code>33</code> and dpo-4 got <code>34</code>, but on private leaderboard they got <code>31</code> and <code>29</code> respectively.</p>",
          "rawMarkdown": "Thanks! We didn't submit the stage 1 SFT model, base model got `28`, dpo-2 got `33` and dpo-4 got `34`, but on private leaderboard they got `31` and `29` respectively.",
          "votes": 1
        }
      ]
    },
    {
      "id": 3177323,
      "postDate": "2025-04-12T15:19:56.043Z",
      "content": "<p>Amazing work, congratulations.</p>\n<p>I am interested in quantization-aware training, I had quite a bit of trouble setting up QAT. Can you share how you did it?</p>",
      "rawMarkdown": "Amazing work, congratulations.\n\nI am interested in quantization-aware training, I had quite a bit of trouble setting up QAT. Can you share how you did it?",
      "replies": [
        {
          "id": 3177590,
          "postDate": "2025-04-13T02:36:16.660Z",
          "content": "<p>Thanks for your question. We just do a very cursory and incomplete trial, the following is just for your reference. We use the 360-LLama-Factory library, which uses <code>autoawq</code> to load the AWQ model. In order to tune the scales of AWQ-quantized model, we do the following ugly fixes:</p>\n<p>(1) In <code>autoawq</code>'s <code>awq.modules.linear.WQLinear_GEMM.__init__</code>: We register the scales as parameters instead of buffers, in order for let the optimizer update them:</p>\n<pre><code>        .register_parameter(\n            ,\n            torch.nn.Parameter(torch.zeros(\n                  (in_features // .group_size, out_features),\n        dtype=torch.float16,\n                device=dev,\n            )),\n    )\n</code></pre>\n<p>(2) In <code>autoawq</code>'s <code>awq.modules.linear.WQLinear_GEMM.forward</code>: Instead of calling <code>WQLinearMMFunction.apply</code>, we change it to use the naive implementation of decoding+matrix-multiplication. The original implementation uses a more efficient Triton-implemented decoding+matrix-multiplication, but they don't implement gradient backward for the scale.</p>\n<pre><code>        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n      user_has_been_warned:\n            warnings.warn( + msg)\n        user_has_been_warned = \n         torch.cuda.amp.autocast():\n            out = dequantize_gemm(.qweight, .qzeros, .scales, .w_bit, .g\\\nroup_size)\n            out = torch.matmul(x, out)\n              out = out + .bias  .bias     out\n        out = out.reshape(out_shape)\n        \n     (out.shape) == :\n        out = out.unsqueeze()\n</code></pre>\n<p>(3) In the 360-Llama-Factory lib, we add the following call to the <code>llamafactory.train.dpo.workflow.run_dpo</code> function after loading the model, to set the <code>requires_grad</code> of scales to be True.</p>\n<pre><code>\n\n\n\n\n\n\n\n\n def run_dpo(\n     model_args: \"ModelArguments\",\n     data_args: \"DataArguments\",\n def run_dpo(\n     template = get_template_and_fix_tokenizer(tokenizer, data_args)\n     dataset_module = get_dataset(template, model_args, data_args, training_args, stage=\"rm\", **tokenizer_module)\n     model = load_model(tokenizer, model_args, finetuning_args, training_args.do_train, full_determinism=training_args.full_determinism)\n\n</code></pre>\n<p>As you can see, we do some ugly fixes instead of writing a clean code. A detail is that due to our computational capability limitation, we use of cutoff length of 16k (instead of 32k) to do the training on 4 GPUs. This small quick attempt doesn't get improvements. We think tuning the weights might still be needed, and longer context length might be needed, but we don't have the GPU &amp; development capacity to further try that. </p>",
          "rawMarkdown": "Thanks for your question. We just do a very cursory and incomplete trial, the following is just for your reference. We use the 360-LLama-Factory library, which uses `autoawq` to load the AWQ model. In order to tune the scales of AWQ-quantized model, we do the following ugly fixes:\n\n(1) In `autoawq`'s `awq.modules.linear.WQLinear_GEMM.__init__`: We register the scales as parameters instead of buffers, in order for let the optimizer update them:\n```python\n        self.register_parameter(\n            \"scales\",\n            torch.nn.Parameter(torch.zeros(\n      \t        (in_features // self.group_size, out_features),\n\t\tdtype=torch.float16,\n                device=dev,\n            )),\n\t)\n```\n(2) In `autoawq`'s `awq.modules.linear.WQLinear_GEMM.forward`: Instead of calling `WQLinearMMFunction.apply`, we change it to use the naive implementation of decoding+matrix-multiplication. The original implementation uses a more efficient Triton-implemented decoding+matrix-multiplication, but they don't implement gradient backward for the scale.\n```python\n        # out = WQLinearMMFunction.apply(\n        #     x,\n        #     self.qweight,\n        #     self.qzeros,\n        #     self.scales,\n        #     self.w_bit,\n        #     self.group_size,\n        #     self.bias,\n        #     self.out_features,\n        # )\n\tif not user_has_been_warned:\n            warnings.warn(\"Using naive (slow) implementation.\" + msg)\n\t    user_has_been_warned = True\n        with torch.cuda.amp.autocast():\n            out = dequantize_gemm(self.qweight, self.qzeros, self.scales, self.w_bit, self.g\\\nroup_size)\n            out = torch.matmul(x, out)\n      \t    out = out + self.bias if self.bias is not None else out\n\t    out = out.reshape(out_shape)\n        # always want 3D tensor if tensor is 2D\n\tif len(out.shape) == 2:\n\t    out = out.unsqueeze(0)\n```\n(3) In the 360-Llama-Factory lib, we add the following call to the `llamafactory.train.dpo.workflow.run_dpo` function after loading the model, to set the `requires_grad` of scales to be True.\n```\n+from awq.modules.linear.gemm import WQLinear_GEMM\n+def make_awq_scales_trainable(model):\n+    num = 0\n+    for name, module in model.named_modules():\n+        if isinstance(module, WQLinear_GEMM):\n+            module.scales.requires_grad_()\n+            num += 1\n+    print(f\"Set {num} AWQ scales to be trainable\")`\n+\n def run_dpo(\n     model_args: \"ModelArguments\",\n     data_args: \"DataArguments\",\n@@ -45,6 +75,8 @@ def run_dpo(\n     template = get_template_and_fix_tokenizer(tokenizer, data_args)\n     dataset_module = get_dataset(template, model_args, data_args, training_args, stage=\"rm\", **tokenizer_module)\n     model = load_model(tokenizer, model_args, finetuning_args, training_args.do_train, full_determinism=training_args.full_determinism)\n+   make_awq_scales_trainable(model)\n```\n\nAs you can see, we do some ugly fixes instead of writing a clean code. A detail is that due to our computational capability limitation, we use of cutoff length of 16k (instead of 32k) to do the training on 4 GPUs. This small quick attempt doesn't get improvements. We think tuning the weights might still be needed, and longer context length might be needed, but we don't have the GPU & development capacity to further try that. ",
          "votes": 1,
          "replies": [
            {
              "id": 3177792,
              "postDate": "2025-04-13T09:36:32.430Z",
              "content": "<p>Thanks for detail. Seems AWQ model so hard to finetune(especially reasoning model). My tests came out pretty bad, 15-18 on public lb.</p>",
              "rawMarkdown": "Thanks for detail. Seems AWQ model so hard to finetune(especially reasoning model). My tests came out pretty bad, 15-18 on public lb."
            },
            {
              "id": 3180012,
              "postDate": "2025-04-16T03:23:31.467Z",
              "content": "<p>Wow! this is actually really cool, so much care going into each detail…</p>",
              "rawMarkdown": "Wow! this is actually really cool, so much care going into each detail..."
            }
          ]
        }
      ]
    },
    {
      "id": 3177315,
      "postDate": "2025-04-12T15:01:28.947Z",
      "content": "<p>Very incredibly structured approach<br>\nCongratulations on the 2nd place win!</p>",
      "rawMarkdown": "Very incredibly structured approach\nCongratulations on the 2nd place win!"
    },
    {
      "id": 3177259,
      "postDate": "2025-04-12T13:54:50.443Z",
      "content": "<p>It's a huge work for your team, and it takes a long time to ultimately win the 2nd place, truly well-deserved. Great performance your Tsinghua and Microsoft.</p>\n<blockquote>\n  <p>RAG: we use this dataset as a document bank. When solving a question, we fetch 1~2 most similar questions from the bank, use them and their corresponding solutions as the few-shot demonstrations. But we did not get improvement on AIME2025 nor online submission.</p>\n</blockquote>\n<p>Once I thought RAG was a key solution for this competition, but in reality, it didn’t work when I tried it myself. I’m a bit confused, maybe the dataset is just too difficult?</p>",
      "rawMarkdown": "It's a huge work for your team, and it takes a long time to ultimately win the 2nd place, truly well-deserved. Great performance your Tsinghua and Microsoft.\n\n>RAG: we use this dataset as a document bank. When solving a question, we fetch 1~2 most similar questions from the bank, use them and their corresponding solutions as the few-shot demonstrations. But we did not get improvement on AIME2025 nor online submission.\n\nOnce I thought RAG was a key solution for this competition, but in reality, it didn’t work when I tried it myself. I’m a bit confused, maybe the dataset is just too difficult?",
      "replies": [
        {
          "id": 3177312,
          "postDate": "2025-04-12T14:58:53.647Z",
          "rawMarkdown": "",
          "isDeleted": true
        },
        {
          "id": 3177321,
          "postDate": "2025-04-12T15:10:41.440Z",
          "content": "<p>Thanks! </p>\n<p>About RAG, we try RAG in an early stage of our experiments. Back then, we qualitatively inspect some runs (no statistics), and find out that the questions that have similar embedding not necessarily have similar solving strategies (e.g., have similar words instead of reasoning structure). To further explore this, maybe we can try better embedding or retrieval strategies, e.g., (1) use a more appropriate feature as the embedding (we just use the mean of the last layer's feature across tokens), which might be more reflective of the reasoning state instead of language-related information, or (2) rely on the model to do some analyses and improve the embedding based on intermediate analyses, or (3) actively search for reference and reason in a more flexible agentic way. </p>\n<p>However, we don’t further experiment with these possible mitigations. Therefore, we cannot say we have reached a reliable negative conclusion for this pathway. It still needs further inspection and exploration.</p>",
          "rawMarkdown": "Thanks! \n\nAbout RAG, we try RAG in an early stage of our experiments. Back then, we qualitatively inspect some runs (no statistics), and find out that the questions that have similar embedding not necessarily have similar solving strategies (e.g., have similar words instead of reasoning structure). To further explore this, maybe we can try better embedding or retrieval strategies, e.g., (1) use a more appropriate feature as the embedding (we just use the mean of the last layer's feature across tokens), which might be more reflective of the reasoning state instead of language-related information, or (2) rely on the model to do some analyses and improve the embedding based on intermediate analyses, or (3) actively search for reference and reason in a more flexible agentic way. \n\nHowever, we don’t further experiment with these possible mitigations. Therefore, we cannot say we have reached a reliable negative conclusion for this pathway. It still needs further inspection and exploration.\n",
          "votes": 3
        },
        {
          "id": 3177594,
          "postDate": "2025-04-13T02:41:34.490Z",
          "rawMarkdown": "",
          "isDeleted": true
        }
      ]
    },
    {
      "id": 3181250,
      "postDate": "2025-04-17T16:07:19.640Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 3178152,
      "postDate": "2025-04-13T19:32:39.093Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 3178757,
      "postDate": "2025-04-14T15:11:50.600Z",
      "content": "<p>Great work!</p>",
      "rawMarkdown": "Great work!"
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-20T06:42:18Z",
  "competition_id": 86023,
  "competition_slug": "ai-mathematical-olympiad-progress-prize-2",
  "team_id": 12926868,
  "solution_url": "/competitions/ai-mathematical-olympiad-progress-prize-2/writeups/imagination-research-2nd-place-solution-team-imagi"
}