{
  "id": 287918,
  "title": "13th Place Solution",
  "content": "<p>I would like to thank Kaggle and Chaii (Challenge in AI for India) for setting up this interesting Multilingual Question Answering Challenge. </p>\n<p>It turns out we have a couple of solutions that would put us Gold Position but that is how these competitions go sometimes! </p>\n<p><strong>Acknowledgements</strong></p>\n<p>A big shout out to <a href=\"https://www.kaggle.com/kishalmandal\" target=\"_blank\">@kishalmandal</a>, <a href=\"https://www.kaggle.com/abhishek\" target=\"_blank\">@abhishek</a> and <a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a> for their wonderful kernels and models that we could leverage. </p>\n<p>Also thanks to my wonderful teammates <a href=\"https://www.kaggle.com/khyeh0719\" target=\"_blank\">@khyeh0719</a> and <a href=\"https://www.kaggle.com/maxjeblick\" target=\"_blank\">@maxjeblick</a> for their contributions to our solution. This was a team effort! </p>\n<p><strong>External Datasets</strong></p>\n<p>The models in the final pipeline used a mix of the baseline dataset and the MLQA and Squad datasets that were disclosed early on in the competition in the datasets page here: <a href=\"https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/264581\" target=\"_blank\">https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/264581</a> </p>\n<p><strong>Models</strong></p>\n<p>All models below were trained with doc_stride=135, max_length=400</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>LB Score</th>\n<th>Comments</th>\n<th># Folds Used</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>deepset/xlm-roberta-large-squad2</td>\n<td>0.792</td>\n<td>5 fold Public Model</td>\n<td>5</td>\n</tr>\n<tr>\n<td>deepset/xlm-roberta-large-squad2</td>\n<td>0.781</td>\n<td>10 fold Tez model Trained Locally</td>\n<td>3</td>\n</tr>\n<tr>\n<td>google/rembert</td>\n<td>0.777</td>\n<td>5 Fold Trained Locally</td>\n<td>4</td>\n</tr>\n<tr>\n<td>google/muril-base-cased</td>\n<td>0.772</td>\n<td>5 Fold Trained Locally</td>\n<td>4</td>\n</tr>\n</tbody>\n</table>\n<p>Apart from the models above we tried various different architectures including but not limited to <strong>electra, muril-base, multilingual BERT, span BERT, tamillion, indic-bert</strong> but none of them were as good as the architectures in the table for this task. </p>\n<p>There was very little CV -&gt; LB correlation in the competition for us. High CV scores did poorly on LB while decent but not too poor CV results gave higher LB scores. I suspect that this is due to the noise in the dataset and also that private dataset is cleaner with multiple annotators labeling the data. </p>\n<p><strong>Speeding up calculations</strong><br>\n    - <code>model.half()</code>  - FP16 for slight improvement in speed and no impact to LB score<br>\n    - Reusing features for same archs<br>\n    - Torchscript/jit - Experiments resulted in out of memory<br>\n    - Tried joblib and multiprocessing to do parallel calculations - All experiments worked on train set but out of memory on test. Maybe because test set had longer contexts? </p>\n<p><strong>Ensemble Strategies</strong><br>\nOne of the main challenges was the 5 hr kernel run limit. With different architectures and possibly different max_len/doc_stride it became pretty evident that we needed a good way to ensemble models. Averaging logits only works for same archs and if same doc_stride/max len is used.<br>\n I read up best practises on how do to this including top solution in the TensorFlow Question Answering Challenge here: <a href=\"https://www.kaggle.com/c/tensorflow2-question-answering/discussion/128832\" target=\"_blank\">https://www.kaggle.com/c/tensorflow2-question-answering/discussion/128832</a> . I came across majority/hard voting in the solution descriptions and decided to implement a very simple voting algorithm that landed up giving a significant boost to LB score. </p>\n<p><strong>Voting</strong><br>\nThe voter took the cleaned predictions (after basic post processing) as inputs. We had 4 architectures in the final pipeline and the first stage checked for a majority vote among the 4 candidate predictions based on the top answer from each architecture. If there was no majority, the voting pool was expanded to top N predictions among all architectures. We found that taking top 2 votes from each arch gave good results. To further improve on the 2nd stage of the voting, if there was still a deadlock in voting, the votes were compared for similarity using the Levenshtein Ratio and if votes were within a certain threshold, one of those answers were selected as the final since the metric is Jaccard and having part of the answer correct would still be useful. </p>\n<p><strong>Score progression</strong> <br>\n    - Public LB kernel -&gt; <strong>LB 0.792</strong> <br>\n    -  Voting ensemble with 3 different architectures  -&gt; <strong>LB 0.798</strong>  (+0.006)<br>\n    -  Improving models in voting -&gt; <strong>LB 0.801</strong>  (+0.003)<br>\n    -  Adding another architecture to voting and selecting best models  -&gt; <strong>LB 0.809</strong>  (+0.003)<br>\n    - Fine tuning voting logic (see above) -&gt; <strong>LB 0.811</strong></p>\n<p>Code can be found here: <a href=\"https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity\" target=\"_blank\">https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity</a></p>\n<p>Description of voting logic: <a href=\"https://www.kaggle.com/trushk/ensemble-using-voting-13th-place-solution\" target=\"_blank\">https://www.kaggle.com/trushk/ensemble-using-voting-13th-place-solution</a></p>",
  "comments": [
    {
      "id": 1583913,
      "author_name": "KhanhVD",
      "author_url": "",
      "post_date": "2021-11-16T06:26:25.200000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/trushk\" target=\"_blank\">@trushk</a> and team and thanks for sharing the writeup </p>",
      "votes": 3,
      "replies": [
        {
          "id": 1583960,
          "author_name": "Trushant Kalyanpur",
          "author_url": "",
          "post_date": "2021-11-16T07:05:31.637000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/duykhanh99\" target=\"_blank\">@duykhanh99</a> !</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1584211,
      "author_name": "Max Jeblick",
      "author_url": "",
      "post_date": "2021-11-16T10:45:04.583000",
      "content": "<p>Things which didn't work (many 😄):<br>\nMy general impression after this competition (and having worked with quite a few NLP datasets) is that the default settings (AdamW, lr~O(1e-5)) are near optimal for many problem types.</p>\n<ul>\n<li><strong>Layer reinitialization</strong>: It gave some boost in the Commonlit Readability Competition. Here, it clearly worsened the performance.</li>\n<li><strong>Adjust Target</strong>: Several top teams figured out ways how to fix the noise in the training data (<code>answer_start</code> being always the first occurrence which might not be true). As I'm not a speaker of Hindi nor Tamil, I tried to find an automated way how to fix these labeling issues. What I tried is to mark all occurrences of <code>answer_text</code> in the first <code>context[:N]</code> as a target. That is, if the model's input is <code>&lt;Question&gt; &lt;Context Chunk_i&gt;</code> and <code>&lt;Context Chunk_i&gt;</code> is from the beginning of the text and contains <code>answer_text</code>, the corresponding target will be the start and end position of that answer.<br>\nThis relatively naive method didn't improve the scores and I stopped refining it.</li>\n<li><strong>Create Token Type IDs</strong>: Most models (e.g. <code>deepset/xlm-roberta-squad2</code>) don't use <code>token_type_ids</code>. Yet, they may be important, as the input is given by <code>&lt;Question&gt; &lt;Context Chunk_i&gt;</code>. I tried adding <code>token_type_ids</code> back to <code>xlm-roberta</code> models, with 0 denoting the question and 1 denoting the answer. Embedding was initialized with the <code>token_type_id==0</code> embedding vector of the respective pretrained model (<code>token_type_ids</code> embedding layer is still used by many models, the lookup is always for 0). Surprisingly, OOF scores didn't improve.</li>\n<li>Played quite some time with <strong>different losses</strong> (tried similar ones to what the <a href=\"https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/287917\" target=\"_blank\">second place</a> used). In the end, normal Crossentropy was the winner.</li>\n<li>Tried <strong>different optimizers</strong>, most where comparable to the default one (AdamW) used in the public kernels.</li>\n<li><strong>Pretraining</strong> <code>deepset/xlm-roberta-squad2</code> on translated squad2 first, scores where slightly worse</li>\n<li><strong>Postprocessing of the answer</strong>. This is a clear example how to boost CV which doesn't get reflected in the leaderboard. In general, I stored Top_N predicted answers and noticed that the correct answer is, if not the best one, often then second best. The question is how to decide whether to swap second-best -&gt; best answer.<br>\nan example of top-N answers might be<br>\n['1895',<br>\n'11 सितंबर 1895',<br>\n'सितम्बर 1895',<br>\n'11 सितंबर 1895',<br>\n'11 सितंबर 1895 को',<br>\n'11 सितंबर',<br>\n'1895',]. <br>\nThen, if the best answer is a year and the second-best answer is the same year, but with DD/MM/YYYY format, swap the answers. One can get quite creative with this kind of postprocessing (in the end it is similar to ensembling N model predictions), but it lowered our score on public lb.</li>\n<li>Tried the <a href=\"https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/287919\" target=\"_blank\"><strong>same method</strong></a> as <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> (modifying <code>score = start_logits + end_logits</code>). For us, it improved oof scores, but lowered public LB.</li>\n</ul>",
      "votes": 4,
      "replies": []
    },
    {
      "id": 1591233,
      "author_name": "Parv Yadav",
      "author_url": "",
      "post_date": "2021-11-22T05:32:16.107000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/trushk\" target=\"_blank\">@trushk</a> !😄</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1590698,
      "author_name": "MINGOOK KIM",
      "author_url": "",
      "post_date": "2021-11-21T15:08:37.657000",
      "content": "<p>Congratulations on your achievements.</p>\n<p>Congratulations~</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1586348,
      "author_name": "Ayush Singh",
      "author_url": "",
      "post_date": "2021-11-18T02:23:04.973000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/trushk\" target=\"_blank\">@trushk</a> very nice approach. and thanks for sharing the code as well. It is very helpful. </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1585924,
      "author_name": "Tsuno",
      "author_url": "",
      "post_date": "2021-11-17T16:44:25.987000",
      "content": "<p>Congratulations</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1584860,
      "author_name": "Udbhav Bamba",
      "author_url": "",
      "post_date": "2021-11-16T20:16:07.630000",
      "content": "<p>Thanks for the overview. The voting logic seems very fascinating. </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1584837,
      "author_name": "Darek Kłeczek",
      "author_url": "",
      "post_date": "2021-11-16T19:54:33.327000",
      "content": "<p>Congratulations, an interesting solution! I also used majority voting across 3 models blends but in case of no agreement I just stuck defaulted to the best model (MURIL in my case) predictions. Need to try out your method!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1584841,
          "author_name": "Trushant Kalyanpur",
          "author_url": "",
          "post_date": "2021-11-16T19:57:52.983000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/thedrcat\" target=\"_blank\">@thedrcat</a>. Yes, that is what I had started off with but I found that increasing the voting pool increased the LB score by +0.004 and further checking for similar answers improved the score by +.001</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1584516,
      "author_name": "Mathurin Ache",
      "author_url": "",
      "post_date": "2021-11-16T15:12:48.620000",
      "content": "<p>Great Overview of Your Solution. Thank you</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1584034,
      "author_name": "Luca Massaron",
      "author_url": "",
      "post_date": "2021-11-16T08:16:22.567000",
      "content": "<p>I also notice that in the end you used 16 folds :-)</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1584033,
      "author_name": "Luca Massaron",
      "author_url": "",
      "post_date": "2021-11-16T08:15:54.460000",
      "content": "<p>We struggled with voting (just used most voted solution, breaking ties by length - shorter favored) and I like very much your voting solution (If there was no majority, the voting pool was expanded to top N predictions among all architectures / votes were compared for similarity using the Levenshtein Ratio). Great solution! I will surely use that on the next QA competition/problem :-)</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1583663,
      "author_name": "Kiran Chaudhary",
      "author_url": "",
      "post_date": "2021-11-16T01:42:42.700000",
      "content": "<p>Congratulations!!!!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1583613,
      "author_name": "Chris Deotte",
      "author_url": "",
      "post_date": "2021-11-16T01:03:24.763000",
      "content": "<p>Congratulations! When ensembling different models did you need to convert to a common tokenization? Do the different models use different tokenization?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1583621,
          "author_name": "Trushant Kalyanpur",
          "author_url": "",
          "post_date": "2021-11-16T01:09:45.320000",
          "content": "<p>Yes different archs used different tokenizations. That coupled with different doc stride and max-len means that start/end logits have different shapes. So I just ensembled based on multi stage voting of count of predictions- Kernel is here: <a href=\"https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity#Change-vote-count-if-votes-are-similar\" target=\"_blank\">https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity#Change-vote-count-if-votes-are-similar</a></p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1583738,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2021-11-16T03:14:12.387000",
          "content": "<p>Great solution for ensemble. Well done!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    }
  ],
  "comment_count": 17,
  "messages": [
    {
      "id": 1583570,
      "postDate": "2021-11-16T00:24:24.297Z",
      "content": "<p>I would like to thank Kaggle and Chaii (Challenge in AI for India) for setting up this interesting Multilingual Question Answering Challenge. </p>\n<p>It turns out we have a couple of solutions that would put us Gold Position but that is how these competitions go sometimes! </p>\n<p><strong>Acknowledgements</strong></p>\n<p>A big shout out to <a href=\"https://www.kaggle.com/kishalmandal\" target=\"_blank\">@kishalmandal</a>, <a href=\"https://www.kaggle.com/abhishek\" target=\"_blank\">@abhishek</a> and <a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a> for their wonderful kernels and models that we could leverage. </p>\n<p>Also thanks to my wonderful teammates <a href=\"https://www.kaggle.com/khyeh0719\" target=\"_blank\">@khyeh0719</a> and <a href=\"https://www.kaggle.com/maxjeblick\" target=\"_blank\">@maxjeblick</a> for their contributions to our solution. This was a team effort! </p>\n<p><strong>External Datasets</strong></p>\n<p>The models in the final pipeline used a mix of the baseline dataset and the MLQA and Squad datasets that were disclosed early on in the competition in the datasets page here: <a href=\"https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/264581\" target=\"_blank\">https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/264581</a> </p>\n<p><strong>Models</strong></p>\n<p>All models below were trained with doc_stride=135, max_length=400</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>LB Score</th>\n<th>Comments</th>\n<th># Folds Used</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>deepset/xlm-roberta-large-squad2</td>\n<td>0.792</td>\n<td>5 fold Public Model</td>\n<td>5</td>\n</tr>\n<tr>\n<td>deepset/xlm-roberta-large-squad2</td>\n<td>0.781</td>\n<td>10 fold Tez model Trained Locally</td>\n<td>3</td>\n</tr>\n<tr>\n<td>google/rembert</td>\n<td>0.777</td>\n<td>5 Fold Trained Locally</td>\n<td>4</td>\n</tr>\n<tr>\n<td>google/muril-base-cased</td>\n<td>0.772</td>\n<td>5 Fold Trained Locally</td>\n<td>4</td>\n</tr>\n</tbody>\n</table>\n<p>Apart from the models above we tried various different architectures including but not limited to <strong>electra, muril-base, multilingual BERT, span BERT, tamillion, indic-bert</strong> but none of them were as good as the architectures in the table for this task. </p>\n<p>There was very little CV -&gt; LB correlation in the competition for us. High CV scores did poorly on LB while decent but not too poor CV results gave higher LB scores. I suspect that this is due to the noise in the dataset and also that private dataset is cleaner with multiple annotators labeling the data. </p>\n<p><strong>Speeding up calculations</strong><br>\n    - <code>model.half()</code>  - FP16 for slight improvement in speed and no impact to LB score<br>\n    - Reusing features for same archs<br>\n    - Torchscript/jit - Experiments resulted in out of memory<br>\n    - Tried joblib and multiprocessing to do parallel calculations - All experiments worked on train set but out of memory on test. Maybe because test set had longer contexts? </p>\n<p><strong>Ensemble Strategies</strong><br>\nOne of the main challenges was the 5 hr kernel run limit. With different architectures and possibly different max_len/doc_stride it became pretty evident that we needed a good way to ensemble models. Averaging logits only works for same archs and if same doc_stride/max len is used.<br>\n I read up best practises on how do to this including top solution in the TensorFlow Question Answering Challenge here: <a href=\"https://www.kaggle.com/c/tensorflow2-question-answering/discussion/128832\" target=\"_blank\">https://www.kaggle.com/c/tensorflow2-question-answering/discussion/128832</a> . I came across majority/hard voting in the solution descriptions and decided to implement a very simple voting algorithm that landed up giving a significant boost to LB score. </p>\n<p><strong>Voting</strong><br>\nThe voter took the cleaned predictions (after basic post processing) as inputs. We had 4 architectures in the final pipeline and the first stage checked for a majority vote among the 4 candidate predictions based on the top answer from each architecture. If there was no majority, the voting pool was expanded to top N predictions among all architectures. We found that taking top 2 votes from each arch gave good results. To further improve on the 2nd stage of the voting, if there was still a deadlock in voting, the votes were compared for similarity using the Levenshtein Ratio and if votes were within a certain threshold, one of those answers were selected as the final since the metric is Jaccard and having part of the answer correct would still be useful. </p>\n<p><strong>Score progression</strong> <br>\n    - Public LB kernel -&gt; <strong>LB 0.792</strong> <br>\n    -  Voting ensemble with 3 different architectures  -&gt; <strong>LB 0.798</strong>  (+0.006)<br>\n    -  Improving models in voting -&gt; <strong>LB 0.801</strong>  (+0.003)<br>\n    -  Adding another architecture to voting and selecting best models  -&gt; <strong>LB 0.809</strong>  (+0.003)<br>\n    - Fine tuning voting logic (see above) -&gt; <strong>LB 0.811</strong></p>\n<p>Code can be found here: <a href=\"https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity\" target=\"_blank\">https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity</a></p>\n<p>Description of voting logic: <a href=\"https://www.kaggle.com/trushk/ensemble-using-voting-13th-place-solution\" target=\"_blank\">https://www.kaggle.com/trushk/ensemble-using-voting-13th-place-solution</a></p>",
      "rawMarkdown": "I would like to thank Kaggle and Chaii (Challenge in AI for India) for setting up this interesting Multilingual Question Answering Challenge. \n\nIt turns out we have a couple of solutions that would put us Gold Position but that is how these competitions go sometimes! \n\n\n**Acknowledgements**\n\nA big shout out to @kishalmandal, @abhishek and @nbroad for their wonderful kernels and models that we could leverage. \n\nAlso thanks to my wonderful teammates @khyeh0719 and @maxjeblick for their contributions to our solution. This was a team effort! \n\n\n**External Datasets**\n\nThe models in the final pipeline used a mix of the baseline dataset and the MLQA and Squad datasets that were disclosed early on in the competition in the datasets page here: https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/264581 \n\n\n**Models**\n\nAll models below were trained with doc_stride=135, max_length=400\n\n| Model | LB Score  | Comments | # Folds Used |\n| --- | --- | --- | --- |\n| deepset/xlm-roberta-large-squad2 |  0.792 | 5 fold Public Model | 5 |\n| deepset/xlm-roberta-large-squad2 |  0.781 |  10 fold Tez model Trained Locally | 3 |\n|google/rembert  |  0.777 | 5 Fold Trained Locally | 4 |\n| google/muril-base-cased |  0.772 | 5 Fold Trained Locally | 4 |\n\n\nApart from the models above we tried various different architectures including but not limited to **electra, muril-base, multilingual BERT, span BERT, tamillion, indic-bert** but none of them were as good as the architectures in the table for this task. \n\nThere was very little CV -> LB correlation in the competition for us. High CV scores did poorly on LB while decent but not too poor CV results gave higher LB scores. I suspect that this is due to the noise in the dataset and also that private dataset is cleaner with multiple annotators labeling the data. \n\n\n**Speeding up calculations**\n\t- `model.half()`  - FP16 for slight improvement in speed and no impact to LB score\n\t- Reusing features for same archs\n\t- Torchscript/jit - Experiments resulted in out of memory\n\t- Tried joblib and multiprocessing to do parallel calculations - All experiments worked on train set but out of memory on test. Maybe because test set had longer contexts? \n\n**Ensemble Strategies**\nOne of the main challenges was the 5 hr kernel run limit. With different architectures and possibly different max_len/doc_stride it became pretty evident that we needed a good way to ensemble models. Averaging logits only works for same archs and if same doc_stride/max len is used.\n I read up best practises on how do to this including top solution in the TensorFlow Question Answering Challenge here: https://www.kaggle.com/c/tensorflow2-question-answering/discussion/128832 . I came across majority/hard voting in the solution descriptions and decided to implement a very simple voting algorithm that landed up giving a significant boost to LB score. \n\n**Voting**\nThe voter took the cleaned predictions (after basic post processing) as inputs. We had 4 architectures in the final pipeline and the first stage checked for a majority vote among the 4 candidate predictions based on the top answer from each architecture. If there was no majority, the voting pool was expanded to top N predictions among all architectures. We found that taking top 2 votes from each arch gave good results. To further improve on the 2nd stage of the voting, if there was still a deadlock in voting, the votes were compared for similarity using the Levenshtein Ratio and if votes were within a certain threshold, one of those answers were selected as the final since the metric is Jaccard and having part of the answer correct would still be useful. \n\n\n\n**Score progression** \n\t- Public LB kernel -> **LB 0.792** \n\t-  Voting ensemble with 3 different architectures  -> **LB 0.798**  (+0.006)\n\t-  Improving models in voting -> **LB 0.801**  (+0.003)\n\t-  Adding another architecture to voting and selecting best models  -> **LB 0.809**  (+0.003)\n\t- Fine tuning voting logic (see above) -> **LB 0.811**\n\nCode can be found here: https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity\n\nDescription of voting logic: https://www.kaggle.com/trushk/ensemble-using-voting-13th-place-solution",
      "votes": 29
    },
    {
      "id": 1583913,
      "postDate": "2021-11-16T06:26:25.200Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/trushk\" target=\"_blank\">@trushk</a> and team and thanks for sharing the writeup </p>",
      "rawMarkdown": "Congratulations @trushk and team and thanks for sharing the writeup ",
      "votes": 3,
      "replies": [
        {
          "id": 1583960,
          "postDate": "2021-11-16T07:05:31.637Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/duykhanh99\" target=\"_blank\">@duykhanh99</a> !</p>",
          "rawMarkdown": "Thanks @duykhanh99 !"
        }
      ]
    },
    {
      "id": 1584211,
      "postDate": "2021-11-16T10:45:04.583Z",
      "content": "<p>Things which didn't work (many 😄):<br>\nMy general impression after this competition (and having worked with quite a few NLP datasets) is that the default settings (AdamW, lr~O(1e-5)) are near optimal for many problem types.</p>\n<ul>\n<li><strong>Layer reinitialization</strong>: It gave some boost in the Commonlit Readability Competition. Here, it clearly worsened the performance.</li>\n<li><strong>Adjust Target</strong>: Several top teams figured out ways how to fix the noise in the training data (<code>answer_start</code> being always the first occurrence which might not be true). As I'm not a speaker of Hindi nor Tamil, I tried to find an automated way how to fix these labeling issues. What I tried is to mark all occurrences of <code>answer_text</code> in the first <code>context[:N]</code> as a target. That is, if the model's input is <code>&lt;Question&gt; &lt;Context Chunk_i&gt;</code> and <code>&lt;Context Chunk_i&gt;</code> is from the beginning of the text and contains <code>answer_text</code>, the corresponding target will be the start and end position of that answer.<br>\nThis relatively naive method didn't improve the scores and I stopped refining it.</li>\n<li><strong>Create Token Type IDs</strong>: Most models (e.g. <code>deepset/xlm-roberta-squad2</code>) don't use <code>token_type_ids</code>. Yet, they may be important, as the input is given by <code>&lt;Question&gt; &lt;Context Chunk_i&gt;</code>. I tried adding <code>token_type_ids</code> back to <code>xlm-roberta</code> models, with 0 denoting the question and 1 denoting the answer. Embedding was initialized with the <code>token_type_id==0</code> embedding vector of the respective pretrained model (<code>token_type_ids</code> embedding layer is still used by many models, the lookup is always for 0). Surprisingly, OOF scores didn't improve.</li>\n<li>Played quite some time with <strong>different losses</strong> (tried similar ones to what the <a href=\"https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/287917\" target=\"_blank\">second place</a> used). In the end, normal Crossentropy was the winner.</li>\n<li>Tried <strong>different optimizers</strong>, most where comparable to the default one (AdamW) used in the public kernels.</li>\n<li><strong>Pretraining</strong> <code>deepset/xlm-roberta-squad2</code> on translated squad2 first, scores where slightly worse</li>\n<li><strong>Postprocessing of the answer</strong>. This is a clear example how to boost CV which doesn't get reflected in the leaderboard. In general, I stored Top_N predicted answers and noticed that the correct answer is, if not the best one, often then second best. The question is how to decide whether to swap second-best -&gt; best answer.<br>\nan example of top-N answers might be<br>\n['1895',<br>\n'11 सितंबर 1895',<br>\n'सितम्बर 1895',<br>\n'11 सितंबर 1895',<br>\n'11 सितंबर 1895 को',<br>\n'11 सितंबर',<br>\n'1895',]. <br>\nThen, if the best answer is a year and the second-best answer is the same year, but with DD/MM/YYYY format, swap the answers. One can get quite creative with this kind of postprocessing (in the end it is similar to ensembling N model predictions), but it lowered our score on public lb.</li>\n<li>Tried the <a href=\"https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/287919\" target=\"_blank\"><strong>same method</strong></a> as <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> (modifying <code>score = start_logits + end_logits</code>). For us, it improved oof scores, but lowered public LB.</li>\n</ul>",
      "rawMarkdown": "Things which didn't work (many 😄):\nMy general impression after this competition (and having worked with quite a few NLP datasets) is that the default settings (AdamW, lr~O(1e-5)) are near optimal for many problem types.\n\n- **Layer reinitialization**: It gave some boost in the Commonlit Readability Competition. Here, it clearly worsened the performance.\n- **Adjust Target**: Several top teams figured out ways how to fix the noise in the training data (`answer_start` being always the first occurrence which might not be true). As I'm not a speaker of Hindi nor Tamil, I tried to find an automated way how to fix these labeling issues. What I tried is to mark all occurrences of `answer_text` in the first `context[:N]` as a target. That is, if the model's input is `<Question> <Context Chunk_i>` and `<Context Chunk_i>` is from the beginning of the text and contains `answer_text`, the corresponding target will be the start and end position of that answer.\nThis relatively naive method didn't improve the scores and I stopped refining it.\n- **Create Token Type IDs**: Most models (e.g. `deepset/xlm-roberta-squad2`) don't use `token_type_ids`. Yet, they may be important, as the input is given by `<Question> <Context Chunk_i>`. I tried adding `token_type_ids` back to `xlm-roberta` models, with 0 denoting the question and 1 denoting the answer. Embedding was initialized with the `token_type_id==0` embedding vector of the respective pretrained model (`token_type_ids` embedding layer is still used by many models, the lookup is always for 0). Surprisingly, OOF scores didn't improve.\n- Played quite some time with **different losses** (tried similar ones to what the [second place](https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/287917) used). In the end, normal Crossentropy was the winner.\n- Tried **different optimizers**, most where comparable to the default one (AdamW) used in the public kernels.\n- **Pretraining** `deepset/xlm-roberta-squad2` on translated squad2 first, scores where slightly worse\n- **Postprocessing of the answer**. This is a clear example how to boost CV which doesn't get reflected in the leaderboard. In general, I stored Top_N predicted answers and noticed that the correct answer is, if not the best one, often then second best. The question is how to decide whether to swap second-best -> best answer.\nan example of top-N answers might be\n ['1895',\n '11 सितंबर 1895',\n 'सितम्बर 1895',\n '11 सितंबर 1895',\n '11 सितंबर 1895 को',\n '11 सितंबर',\n '1895',]. \nThen, if the best answer is a year and the second-best answer is the same year, but with DD/MM/YYYY format, swap the answers. One can get quite creative with this kind of postprocessing (in the end it is similar to ensembling N model predictions), but it lowered our score on public lb.\n- Tried the [**same method**]( https://www.kaggle.com/c/chaii-hindi-and-tamil-question-answering/discussion/287919) as @cdeotte (modifying `score = start_logits + end_logits`). For us, it improved oof scores, but lowered public LB.\n\n",
      "votes": 4
    },
    {
      "id": 1591233,
      "postDate": "2021-11-22T05:32:16.107Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/trushk\" target=\"_blank\">@trushk</a> !😄</p>",
      "rawMarkdown": "Congratulations @trushk !😄",
      "votes": 1
    },
    {
      "id": 1590698,
      "postDate": "2021-11-21T15:08:37.657Z",
      "content": "<p>Congratulations on your achievements.</p>\n<p>Congratulations~</p>",
      "rawMarkdown": "Congratulations on your achievements.\n\nCongratulations~",
      "votes": 1
    },
    {
      "id": 1586348,
      "postDate": "2021-11-18T02:23:04.973Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/trushk\" target=\"_blank\">@trushk</a> very nice approach. and thanks for sharing the code as well. It is very helpful. </p>",
      "rawMarkdown": "Congratulations @trushk very nice approach. and thanks for sharing the code as well. It is very helpful. ",
      "votes": 1
    },
    {
      "id": 1585924,
      "postDate": "2021-11-17T16:44:25.987Z",
      "content": "<p>Congratulations</p>",
      "rawMarkdown": "Congratulations",
      "votes": 1
    },
    {
      "id": 1584860,
      "postDate": "2021-11-16T20:16:07.630Z",
      "content": "<p>Thanks for the overview. The voting logic seems very fascinating. </p>",
      "rawMarkdown": "Thanks for the overview. The voting logic seems very fascinating. ",
      "votes": 1
    },
    {
      "id": 1584837,
      "postDate": "2021-11-16T19:54:33.327Z",
      "content": "<p>Congratulations, an interesting solution! I also used majority voting across 3 models blends but in case of no agreement I just stuck defaulted to the best model (MURIL in my case) predictions. Need to try out your method!</p>",
      "rawMarkdown": "Congratulations, an interesting solution! I also used majority voting across 3 models blends but in case of no agreement I just stuck defaulted to the best model (MURIL in my case) predictions. Need to try out your method!",
      "votes": 1,
      "replies": [
        {
          "id": 1584841,
          "postDate": "2021-11-16T19:57:52.983Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/thedrcat\" target=\"_blank\">@thedrcat</a>. Yes, that is what I had started off with but I found that increasing the voting pool increased the LB score by +0.004 and further checking for similar answers improved the score by +.001</p>",
          "rawMarkdown": "Thanks @thedrcat. Yes, that is what I had started off with but I found that increasing the voting pool increased the LB score by +0.004 and further checking for similar answers improved the score by +.001",
          "votes": 1
        }
      ]
    },
    {
      "id": 1584516,
      "postDate": "2021-11-16T15:12:48.620Z",
      "content": "<p>Great Overview of Your Solution. Thank you</p>",
      "rawMarkdown": "Great Overview of Your Solution. Thank you",
      "votes": 1
    },
    {
      "id": 1584034,
      "postDate": "2021-11-16T08:16:22.567Z",
      "content": "<p>I also notice that in the end you used 16 folds :-)</p>",
      "rawMarkdown": "I also notice that in the end you used 16 folds :-)",
      "votes": 1
    },
    {
      "id": 1584033,
      "postDate": "2021-11-16T08:15:54.460Z",
      "content": "<p>We struggled with voting (just used most voted solution, breaking ties by length - shorter favored) and I like very much your voting solution (If there was no majority, the voting pool was expanded to top N predictions among all architectures / votes were compared for similarity using the Levenshtein Ratio). Great solution! I will surely use that on the next QA competition/problem :-)</p>",
      "rawMarkdown": "We struggled with voting (just used most voted solution, breaking ties by length - shorter favored) and I like very much your voting solution (If there was no majority, the voting pool was expanded to top N predictions among all architectures / votes were compared for similarity using the Levenshtein Ratio). Great solution! I will surely use that on the next QA competition/problem :-)",
      "votes": 1
    },
    {
      "id": 1583663,
      "postDate": "2021-11-16T01:42:42.700Z",
      "content": "<p>Congratulations!!!!</p>",
      "rawMarkdown": "Congratulations!!!!",
      "votes": 1
    },
    {
      "id": 1583613,
      "postDate": "2021-11-16T01:03:24.763Z",
      "content": "<p>Congratulations! When ensembling different models did you need to convert to a common tokenization? Do the different models use different tokenization?</p>",
      "rawMarkdown": "Congratulations! When ensembling different models did you need to convert to a common tokenization? Do the different models use different tokenization?",
      "votes": 1,
      "replies": [
        {
          "id": 1583621,
          "postDate": "2021-11-16T01:09:45.320Z",
          "content": "<p>Yes different archs used different tokenizations. That coupled with different doc stride and max-len means that start/end logits have different shapes. So I just ensembled based on multi stage voting of count of predictions- Kernel is here: <a href=\"https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity#Change-vote-count-if-votes-are-similar\" target=\"_blank\">https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity#Change-vote-count-if-votes-are-similar</a></p>",
          "rawMarkdown": "Yes different archs used different tokenizations. That coupled with different doc stride and max-len means that start/end logits have different shapes. So I just ensembled based on multi stage voting of count of predictions- Kernel is here: https://www.kaggle.com/trushk/qa-ensemble-voter-top-n-votes-similarity#Change-vote-count-if-votes-are-similar",
          "votes": 1
        },
        {
          "id": 1583738,
          "postDate": "2021-11-16T03:14:12.387Z",
          "content": "<p>Great solution for ensemble. Well done!</p>",
          "rawMarkdown": "Great solution for ensemble. Well done!",
          "votes": 1
        }
      ]
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T16:22:06Z",
  "competition_id": 30060,
  "competition_slug": "chaii-hindi-and-tamil-question-answering",
  "team_id": 7262703,
  "solution_url": "/competitions/chaii-hindi-and-tamil-question-answering/writeups/chaii-paani-13th-place-solution"
}