{
  "id": 313389,
  "title": "2nd Place - Weighted Box Fusion and Post Process",
  "content": "<h1>Second Place Solution</h1>\n<p>Thank you Georgia State University, The Learning Agency Lab, and Kaggle for an awesome competition. The data was high quality and interesting. The metric and train test split were well done. This competition was a success and will benefit a good cause.</p>\n<p>Teaming with Chun Ming Lee and Udbhav Bamba has been wonderful. I learned more about NLP than if I had taken an online course. These two Kagglers are grandmasters at NLP and I now know how to use HuggingFace Trainer efficiently and effectively. I also know how to customize models and losses. Thank you <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> <a href=\"https://www.kaggle.com/ubamba98\" target=\"_blank\">@ubamba98</a> </p>\n<h1>Solution Summary</h1>\n<p>The secret sauce to our solution is powerful <strong>post process</strong> by Chun Ming (boost CV LB!), a huge <strong>variety of models</strong> implemented by Udbhav (many long sequence models!), and <strong>weighted box fusion</strong> by Chris (used in my previous comp <a href=\"https://www.kaggle.com/c/tensorflow-great-barrier-reef/discussion/307609\" target=\"_blank\">here</a>). Everything was fine tuned on local CV and achieved 2nd Place $35,000!</p>\n<table>\n<thead>\n<tr>\n<th>Hugging Face Model</th>\n<th>CV</th>\n<th>Public LB</th>\n<th>Private LB</th>\n<th>special</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>microsoft/deberta-large</td>\n<td>706</td>\n<td>710</td>\n<td>721</td>\n<td>trained with 100% train data</td>\n</tr>\n<tr>\n<td>microsoft/deberta-large</td>\n<td>699</td>\n<td>706</td>\n<td>719</td>\n<td>add lstm, add jaccard loss</td>\n</tr>\n<tr>\n<td>microsoft/deberta-v3-large</td>\n<td>694</td>\n<td>697</td>\n<td>709</td>\n<td><a href=\"https://www.kaggle.com/nbroad/deberta-v2-3-fast-tokenizer\" target=\"_blank\">convert slow tokenizer to fast</a></td>\n</tr>\n<tr>\n<td>microsoft/deberta-xlarge</td>\n<td>708</td>\n<td>704</td>\n<td>713</td>\n<td></td>\n</tr>\n<tr>\n<td>microsoft/deberta-v2-xlarge</td>\n<td>699</td>\n<td>700</td>\n<td>716</td>\n<td><a href=\"https://www.kaggle.com/nbroad/deberta-v2-3-fast-tokenizer\" target=\"_blank\">convert slow tokenizer to fast</a></td>\n</tr>\n<tr>\n<td>allenai/longformer-large-4096</td>\n<td>702</td>\n<td>705</td>\n<td>716</td>\n<td>add lstm head</td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/ccdv-ai/convert_checkpoint_to_lsg\" target=\"_blank\">LSG converted roberta</a></td>\n<td>703</td>\n<td>702</td>\n<td>714</td>\n<td>convert 512 roberta to 1536</td>\n</tr>\n<tr>\n<td>funnel-transformer/large</td>\n<td>688</td>\n<td>689</td>\n<td>708</td>\n<td></td>\n</tr>\n<tr>\n<td>google/bigbird-roberta-base</td>\n<td>675</td>\n<td>676</td>\n<td>692</td>\n<td>train 1024 infer 1024</td>\n</tr>\n<tr>\n<td>uw-madison/yoso-4096</td>\n<td>652</td>\n<td>655</td>\n<td>668</td>\n<td>lsh_backward=False</td>\n</tr>\n</tbody>\n</table>\n<h1>Weighted Box Fusion - CV 741, Public 727, Private 740</h1>\n<p>Our final solution contained the 10 models listed above. We included 3 out of 10 K-folds for each of the 10 models. Our 8 hour 30 minute submission inferred 27 models! (we removed 3 folds from 30)</p>\n<p>Weighted Box Fusion by <a href=\"https://www.kaggle.com/zfturbo\" target=\"_blank\">@zfturbo</a> from his GitHub <a href=\"https://github.com/ZFTurbo/Weighted-Boxes-Fusion\" target=\"_blank\">here</a> was the magic that combined all the model predictions together. Individual models had average CV around 700 and the WBF ensemble achieved CV 741. (Folds from same models were averaged before WBF).</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Mar-2022/wbf.png\" alt=\"\"></p>\n<p>Weighted Box Fusion can do something that no other ensemble method can do. If one model has prediction string <code>8 9 10 11</code> and another model has <code>10 11 12 13</code>. Then weighted box fusion takes the average of the two starts, <code>(8 + 10)/2 = 9</code> and the average of the two ends, <code>(11 + 13)/2 = 12</code> resulting in <code>9 10 11 12</code>. Furthermore, WBF reads <code>submission.csv</code> files and doesn't care what tokenizer you used, so its easy to use. (Note we add an extra column to submission dataframe with span confidence).</p>\n<p>If we averaged the token/word probabilities, or used a voting classifier, we would either get the union <code>8 9 10 11 12 13</code> or the intersection <code>10 11</code>. Neither of which we want. Also averaging two \"BIO\" predictions gives a new prediction with two different \"B\" which we do not want either.</p>\n<h1>Post Process</h1>\n<p>Chun Ming is the mastermind behind our team's strong PP. We applied the same PP to each model before WBF. Our PP code is posted <a href=\"https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\" target=\"_blank\">here</a> and Chun Ming will now describe it. Our PP significantly boosted CV LB!</p>\n<p>We applied heavy post-processing to the word-level soft predictions each model made (after averaging token probabilities across folds and before the WBF ensembler). Overall CV was improved by ~.008. </p>\n<p>In order of descending impact on CV: </p>\n<ol>\n<li><p>Repairing span predictions<br>\nSince we trained using cross-entropy loss at the token level, the raw predictions would often result in broken spans. For example, given a chain of Lead token predictions, there might be a misprediction of an “Other” in the middle. We had a rule to convert that “Other” back to Lead. </p></li>\n<li><p>Discourse-specific rules<br>\nWe came up with common sense heuristics for the discourses. For example, for Lead, Position, and Concluding Statement - there should only be a maximum of one each for a text. We’d predict the most probable candidate for each or merge close duplicate spans. </p></li>\n<li><p>Adjusting lengths of predicted spans<br>\nWe adjusted lengths of spans based on their original predicted length. For example, for a predicted Evidence span that was less than 45 words long, we’d shift the start of the predicted span back by 9 words. These rules and the improvement in LB/CV suggest we were taking advantage of the evaluation metric only requiring a 50% overlap in prediction and label to be counted as correct.</p></li>\n</ol>\n<p>It’s not sexy but sitting down and eye-balling model predictions and comparing them with ground truths using a tool like displacy was rewarding in helping us better understand the task, how our models were behaving, and how to improve model predictions. </p>\n<h1>Model Details</h1>\n<p>Surprisingly many more models than LongFormer and BigBird could be trained with sequence lengths greater than 512. All our models were trained with sequence length 1536 and inferred at 1536 (except BigBird-base at 1024).</p>\n<p>The model DeBERTa accepts any input size, so we just train with 1536 as is. </p>\n<p>The model Funnel-transformer can accept any size after updating its config.</p>\n<pre><code>model = AutoModelForTokenClassification.from_pretrained(\n    'funnel-transformer/large', num_labels=15,\n    max_position_embeddings=1536)\n</code></pre>\n<p>For BigBird, we used full attention</p>\n<pre><code>model = AutoModelForTokenClassification.from_pretrained(\n    'google/bigbird-roberta-base', num_labels=15,\n    attention_type=\"original_full\")\n</code></pre>\n<p>For YOSO, we disabled <code>lsh_backward</code></p>\n<pre><code>model = AutoModelForTokenClassification.from_pretrained(\n    'uw-madison/yoso-4096', num_labels=15,\n    lsh_backward=False)\n</code></pre>\n<h1>Model Training</h1>\n<p>Thank you Nvidia for providing us some V100 32GB GPUs and A100 40GB GPUs. For each model, we trained 6 out of 10 KFolds and built our CV from the resultant 60% train data OOF. Each fold would take approximately 4 hours on 1xGPU and required between 3 and 5 epochs to maximize val score. </p>\n<p>For two models, we used my train public notebooks <a href=\"https://www.kaggle.com/cdeotte/tensorflow-longformer-ner-cv-0-633\" target=\"_blank\">here</a> and <a href=\"https://www.kaggle.com/cdeotte/pytorch-bigbird-ner-cv-0-615\" target=\"_blank\">here</a>. For the other eight models, we used Hugging Face Trainer. Most models, used the following parameters. And we added <a href=\"https://www.kaggle.com/robikscube\" target=\"_blank\">@robikscube</a> Kaggle metric <a href=\"https://www.kaggle.com/robikscube/student-writing-competition-twitch-stream\" target=\"_blank\">here</a> and our PP directly to the Trainer evaluation, so we could watch the Kaggle metric score every 500 steps and save the model weights with best Kaggle score.</p>\n<p>Notice how we use FP16, gradient_accumulation_steps, and gradient_checkpointing. With these settings, you can basically train any size model on any GPU including Kaggle's P100 16GB GPU.</p>\n<pre><code>from transformers import TrainingArguments, Trainer\nargs = TrainingArguments( NAME,\n                     PRETRAINED_MODEL,\n                     evaluation_strategy = 'steps',\n                     eval_steps = 500,\n                     dataloader_num_workers=8,\n                     warmup_ratio=0,\n                     lr_scheduler_type = 'linear',\n                     learning_rate = 2e-5,\n                     log_level = 'warning',\n                     fp16 = True,\n                     per_device_train_batch_size = 2,\n                     per_device_eval_batch_size = 2,\n                     gradient_accumulation_steps = 2,\n                     gradient_checkpointing = True,\n                     num_train_epochs = 5,\n                     save_strategy = 'no',\n                     save_total_limit = 1)\n\ntrainer = Trainer(model,\n              args,\n              train_dataset=train_dataset,\n              eval_dataset=valid_dataset,\n              compute_metrics=KaggleMetric(valid_df, valid_dataset),\n              callbacks=[SaveBestModelCallback],\n              data_collator=data_collator,\n              tokenizer=tokenizer)\n</code></pre>\n<h1>Inference Code with PP with WBF</h1>\n<p>We posted our final submission inference code on Kaggle <a href=\"https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\" target=\"_blank\">here</a>. It includes our post process and weighted box fusion implementation. Enjoy!</p>\n<h1>Training Code on GitHub</h1>\n<p>Our training code is published on GitHub <a href=\"https://github.com/ubamba98/feedback-prize\" target=\"_blank\">here</a></p>",
  "comments": [
    {
      "id": 1725276,
      "author_name": "Nicholas Broad",
      "author_url": "",
      "post_date": "2022-03-17T01:14:46.953000",
      "content": "<table>\n<thead>\n<tr>\n<th>Hugging Face Model</th>\n<th>CV</th>\n<th>Public LB</th>\n<th>Private LB</th>\n<th>special</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>microsoft/deberta-large</td>\n<td>706</td>\n<td>710</td>\n<td>721</td>\n<td>trained with 100% train data</td>\n</tr>\n</tbody>\n</table>\n<p>How do you get CV when training on 100% of the data?</p>",
      "votes": 8,
      "replies": [
        {
          "id": 1725281,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-17T01:21:33.547000",
          "content": "<p>ha, good question. The \"CV score\" is the score when training with 10 K-Fold. First we train with 10 K-Fold, and make note of the learning rate and number of epochs. Second we trained a second time using 100% data. So actually it's two models. The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721</p>",
          "votes": 9,
          "replies": []
        },
        {
          "id": 1725283,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-17T01:23:32.277000",
          "content": "<p><a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a> thanks for all your great work at Hugging Face. The NLP library <code>transformers</code> and model repository are fantastic. We also used your code to convert deberta-v2 and v3 slow tokenizers to fast tokenizers. Thanks.</p>",
          "votes": 9,
          "replies": []
        },
        {
          "id": 1725639,
          "author_name": "Nicholas Broad",
          "author_url": "",
          "post_date": "2022-03-17T09:24:15.813000",
          "content": "<p>I greatly appreciate the comment, even though my contributions to <code>transformers</code> are pretty small relative to others. </p>\n<p>I'm always happy to share what I learn through Hugging Face with the community here.  I think the deberta v2/3 fast tokenizers should be merged to the main branch soon so it won't be so awkward to use on Kaggle. </p>\n<p>I forgot to congratulate you! This is another fantastic approach and final rank 😊</p>",
          "votes": 4,
          "replies": []
        },
        {
          "id": 1725709,
          "author_name": "GUNER",
          "author_url": "",
          "post_date": "2022-03-17T11:00:46.857000",
          "content": "<p><em>'''The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721'''</em></p>\n<p>so 706 is out of CV of 10 models(so 10 models are submitted each being one fold of 10), whereas 710 is from a single model (only a single model is submitted) trained from all the data??</p>\n<p>Big congrats again!!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1732556,
          "author_name": "Devansh Chowdhury",
          "author_url": "",
          "post_date": "2022-03-23T14:05:24.470000",
          "content": "<blockquote>\n  <p>ha, good question. The \"CV score\" is the score when training with 10 K-Fold. First we train with 10 K-Fold, and make note of the learning rate and number of epochs. Second we trained a second time using 100% data. So actually it's two models. The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721</p>\n</blockquote>\n<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Is this technique subjective to just the NLP area or you have used this approach for Computer vision and tabular data as well?</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1725294,
      "author_name": "Dewei Chen",
      "author_url": "",
      "post_date": "2022-03-17T01:36:58.300000",
      "content": "<p>Would you mind public all the training models? Because it's too hard for us to Reappearance it.<br>\nThanks!</p>",
      "votes": 6,
      "replies": [
        {
          "id": 1725298,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-17T01:40:08.153000",
          "content": "<p>We published our inference code <a href=\"https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\" target=\"_blank\">here</a>. And we made all trained models (i.e. Kaggle datasets) public.</p>",
          "votes": 8,
          "replies": []
        },
        {
          "id": 1725338,
          "author_name": "Dewei Chen",
          "author_url": "",
          "post_date": "2022-03-17T02:35:17.913000",
          "content": "<p>Got it, cheers :)</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1725135,
      "author_name": "gezi",
      "author_url": "",
      "post_date": "2022-03-16T20:51:49.637000",
      "content": "<p>Great work! The ensemble use WBF of each model only, not using per word soft logits/prob merge?</p>",
      "votes": 3,
      "replies": [
        {
          "id": 1725137,
          "author_name": "Udbhav Bamba",
          "author_url": "",
          "post_date": "2022-03-16T20:53:56.140000",
          "content": "<p>For different folds but same architecture, we average the probabilities and for different architectures we use WBF.</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 1725139,
          "author_name": "gezi",
          "author_url": "",
          "post_date": "2022-03-16T20:55:54.330000",
          "content": "<p>Cool! Thanks!</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 1725234,
      "author_name": "KhanhVD",
      "author_url": "",
      "post_date": "2022-03-17T00:14:50.640000",
      "content": "<p>Nice solution! Congrats <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> and team.  I will try your WBF method in the next NLP competition ;)</p>",
      "votes": 4,
      "replies": []
    },
    {
      "id": 1735972,
      "author_name": "Sharaf Mukhtar",
      "author_url": "",
      "post_date": "2022-03-26T18:56:51.920000",
      "content": "<p>Congratulations, thanks for sharing this </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1735423,
      "author_name": "FPiotro",
      "author_url": "",
      "post_date": "2022-03-26T08:27:41.333000",
      "content": "<p>Congratulations on this solution <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> and team 🧐<br>\nWell explained as always 👍<br>\nKeep up the good work!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1736048,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-26T21:41:42.450000",
          "content": "<p>Thanks FPiotro</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1734398,
      "author_name": "Sdilshad",
      "author_url": "",
      "post_date": "2022-03-25T09:56:52.950000",
      "content": "<p>congrats.. Great work, thanks for sharing </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1733310,
      "author_name": "biubiubiu~",
      "author_url": "",
      "post_date": "2022-03-24T07:13:14.743000",
      "content": "<p>Congrats and thanks for sharing!!!<br>\nDid post processing make a big difference to improve final score? Or an enough large model like deberta and with enough training time can bring a impressive result.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1735359,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-26T06:29:45.980000",
          "content": "<p>Post processing made a large difference. Probably around +0.010</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1733060,
      "author_name": "Tom Zheng",
      "author_url": "",
      "post_date": "2022-03-24T01:18:38.210000",
      "content": "<p>It is really a great code.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1733064,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-24T01:25:14.227000",
          "content": "<p>Thanks Jingyuan</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1732976,
      "author_name": "spin fit",
      "author_url": "",
      "post_date": "2022-03-23T22:46:32.777000",
      "content": "<p>Wow..<br>\nCongratulations ~!! </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1732589,
      "author_name": "Jakub Dębski",
      "author_url": "",
      "post_date": "2022-03-23T14:34:42.820000",
      "content": "<p>Great work, thanks for sharing details. This post process is looking great. </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1732005,
      "author_name": "AtulVerma",
      "author_url": "",
      "post_date": "2022-03-22T23:21:57.423000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a></p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1727990,
      "author_name": "ONIONCORE",
      "author_url": "",
      "post_date": "2022-03-18T14:02:03.570000",
      "content": "<p>Great work. Thanks for sharing the code.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1727879,
      "author_name": "Nicholas Broad",
      "author_url": "",
      "post_date": "2022-03-18T12:13:18.350000",
      "content": "<blockquote>\n  <p>Adjusting lengths of predicted spans<br>\n  We adjusted lengths of spans based on their original predicted length. For example, for a predicted Evidence span that was less than 45 words long, we’d shift the start of the predicted span back by 9 words. These rules and the improvement in LB/CV suggest we were taking advantage of the evaluation metric only requiring a 50% overlap in prediction and label to be counted as correct.</p>\n</blockquote>\n<p><a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> ,<br>\nHow did you decide how many words to shift the predictions by?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1727885,
          "author_name": "Chun Ming Lee",
          "author_url": "",
          "post_date": "2022-03-18T12:19:54.667000",
          "content": "<p>Optimized against CV.</p>\n<p>I was somewhat paranoid about these rules and pushed for our second sub to use a more conservative subset, excluding the length adjustments. Turns out it was unnecessary as CV/LB showed a strong correlation extending to private LB. </p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 1727904,
          "author_name": "Nicholas Broad",
          "author_url": "",
          "post_date": "2022-03-18T12:35:22.790000",
          "content": "<p>So did you just try a bunch of shifts (-1, +1, -2, +2, etc.) and see how that impacted the CV?</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1727915,
          "author_name": "Chun Ming Lee",
          "author_url": "",
          "post_date": "2022-03-18T12:46:10.590000",
          "content": "<p>Broadly yes - we had optimized CV code that used multiprocessing so we could test hyperparam changes very rapidly (&lt;10s per run for 7K OOF samples). I tried using Optuna but found my gut sense better at optimizing :)</p>\n<p>Ofc, in hindsight, this post-processing could have been potentially been done by a 2nd level ML model as a number of top teams did. </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1726251,
      "author_name": "Ken Krige",
      "author_url": "",
      "post_date": "2022-03-17T19:43:30.263000",
      "content": "<p>Great work. Thanks for sharing the code.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1726184,
      "author_name": "Dranzer",
      "author_url": "",
      "post_date": "2022-03-17T18:07:44.137000",
      "content": "<p>Congrats Amazing Work</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1725666,
      "author_name": "Khushboo",
      "author_url": "",
      "post_date": "2022-03-17T09:55:23.617000",
      "content": "<p>Thank you so much Chris. You've got a new follower to go through your work. ;) </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1725424,
      "author_name": "Niek van der Zwaag",
      "author_url": "",
      "post_date": "2022-03-17T04:49:03.590000",
      "content": "<p>Really appreciate your team's efforts in explaining your thought process and approach - congrats on 2nd 🎉</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1725128,
      "author_name": "Trushant Kalyanpur",
      "author_url": "",
      "post_date": "2022-03-16T20:39:47.723000",
      "content": "<p>Using WBF for ensembling spans is brilliant! Great work! </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1725120,
      "author_name": "CroDoc",
      "author_url": "",
      "post_date": "2022-03-16T20:31:40.967000",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> your last link does not point to the inference kernel?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1725124,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-16T20:35:47.477000",
          "content": "<p>It should work now. It will display a quick save and we're running now too. We will also share the datasets later today. Congratulations CroDoc and team for you great finish and big jump in last few days!</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 1725132,
          "author_name": "CroDoc",
          "author_url": "",
          "post_date": "2022-03-16T20:49:48.840000",
          "content": "<p>It works now. Thank you Chris! It was a crazy ride till the end.</p>\n<p>Congrats to your team. Especially to <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a>. Yellow circle is on its way 😎</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 1731824,
      "author_name": "Clear n' Simple",
      "author_url": "",
      "post_date": "2022-03-22T18:12:12.813000",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> for making it into top 10 competitions ranking for 1st time!</p>\n<p>Best of luck continuing to rise!<br>\nIt's nice when the #1 contributor for kagglers of all stages does well.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 1733066,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-24T01:28:43.840000",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/jacob34\" target=\"_blank\">@jacob34</a> I'm excited to enter competitions top 10. My favorite thing on Kaggle is discussions and notebooks, but recently I've been working hard on competitions.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1725730,
      "author_name": "xbustc",
      "author_url": "",
      "post_date": "2022-03-17T11:26:40.857000",
      "content": "<p>congrats and thanks , learn a lot from you.</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 1725705,
      "author_name": "AK",
      "author_url": "",
      "post_date": "2022-03-17T10:56:18.980000",
      "content": "<p>Kudos to you and your team. Nicely done…<br>\nThanks for the detailed writeup as always 🖖</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 1725691,
      "author_name": "小白Lan",
      "author_url": "",
      "post_date": "2022-03-17T10:36:56.153000",
      "content": "<p>amazing work, thx for ur selfless sharing</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 1725475,
      "author_name": "kwchen",
      "author_url": "",
      "post_date": "2022-03-17T06:19:49.223000",
      "content": "<p>Congratulations!<br>\nFor deberta-v3-large I got worse CV than the longformer-large.<br>\nI trained 5 fold, each fold has CV around 0.680. I trained 5 fold using the same folds from abhishek here:<br>\n<a href=\"https://www.kaggle.com/abhishek/creating-folds-properly-hopefully-p\" target=\"_blank\">https://www.kaggle.com/abhishek/creating-folds-properly-hopefully-p</a><br>\nwith his training code here:<br>\n<a href=\"https://github.com/abhishekkrthakur/long-text-token-classification\" target=\"_blank\">https://github.com/abhishekkrthakur/long-text-token-classification</a><br>\nI also converted the deberta tokenizers using <a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a>'s code.<br>\nI used max_len 1536, batch_size 2, and I tried learning rates 1e-5, 2e-6, 1e-6, 2e-7, using argument --epochs 10, and I would stop training after 3~5 epochs.</p>\n<p>Any idea why I got worse CV than yours? I am guessing it's either batch size, learning rate, or because I used 5 folds.</p>",
      "votes": 2,
      "replies": [
        {
          "id": 1725624,
          "author_name": "Udbhav Bamba",
          "author_url": "",
          "post_date": "2022-03-17T09:07:35.947000",
          "content": "<p>I guess it could be because of the offset mapping each tokenizer has different way of generating offsets (some include spaces and some don't) and it will effect your NER labels and predictions, especially for the B-tag as they are more rare.</p>",
          "votes": 4,
          "replies": []
        }
      ]
    },
    {
      "id": 1725217,
      "author_name": "Theo Viel",
      "author_url": "",
      "post_date": "2022-03-16T23:21:56.723000",
      "content": "<p>Congratz <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> <a href=\"https://www.kaggle.com/ubamba98\" target=\"_blank\">@ubamba98</a> !<br>\nThat 2nd place is no surprise, I was looking forward to your solution :)</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 1725142,
      "author_name": "Kishal Mandal",
      "author_url": "",
      "post_date": "2022-03-16T20:59:41.450000",
      "content": "<p>Congrats Chris, you never fail to amaze :D</p>",
      "votes": 2,
      "replies": [
        {
          "id": 1725144,
          "author_name": "Chris Deotte",
          "author_url": "",
          "post_date": "2022-03-16T21:04:12.647000",
          "content": "<p>Thanks! I could not have done it without my awesome teammates Chun Ming Lee and Udbhav Bamba</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 1840542,
      "author_name": "Allohvk",
      "author_url": "",
      "post_date": "2022-07-02T10:46:56.530000",
      "content": "<p>Did you face any issues customizing trainer API? For one, I think it needs valid_batch_size = 1 else there seems to be an error in its code for the last batch. The other issue is in my case the predictions returned to the compute_metrics (via the EvalPrediction) is a blank array. Any suggestions would immensely help</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 1765966,
      "author_name": "Mi Jiaxin",
      "author_url": "",
      "post_date": "2022-04-24T04:04:11.947000",
      "content": "<p>Congratulations, your sharing has helped me a lot. I have a question about how to get the best thresholds of different classes.</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1765970,
          "author_name": "Udbhav Bamba",
          "author_url": "",
          "post_date": "2022-04-24T04:11:57.723000",
          "content": "<p>You can choose them based on your validation </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1735339,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-26T06:10:08.957000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1727668,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-18T06:55:39.203000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 1734353,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-25T08:44:40.327000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1734264,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-25T06:43:43.143000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1734235,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-25T05:51:49.607000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1733106,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-24T02:35:36.353000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1725886,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-17T13:50:16.643000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1787055,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-05-13T14:40:05.043000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 1727849,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-03-18T11:40:40.370000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "comment_count": 59,
  "messages": [
    {
      "id": 1725117,
      "postDate": "2022-03-16T20:26:11.873Z",
      "content": "<h1>Second Place Solution</h1>\n<p>Thank you Georgia State University, The Learning Agency Lab, and Kaggle for an awesome competition. The data was high quality and interesting. The metric and train test split were well done. This competition was a success and will benefit a good cause.</p>\n<p>Teaming with Chun Ming Lee and Udbhav Bamba has been wonderful. I learned more about NLP than if I had taken an online course. These two Kagglers are grandmasters at NLP and I now know how to use HuggingFace Trainer efficiently and effectively. I also know how to customize models and losses. Thank you <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> <a href=\"https://www.kaggle.com/ubamba98\" target=\"_blank\">@ubamba98</a> </p>\n<h1>Solution Summary</h1>\n<p>The secret sauce to our solution is powerful <strong>post process</strong> by Chun Ming (boost CV LB!), a huge <strong>variety of models</strong> implemented by Udbhav (many long sequence models!), and <strong>weighted box fusion</strong> by Chris (used in my previous comp <a href=\"https://www.kaggle.com/c/tensorflow-great-barrier-reef/discussion/307609\" target=\"_blank\">here</a>). Everything was fine tuned on local CV and achieved 2nd Place $35,000!</p>\n<table>\n<thead>\n<tr>\n<th>Hugging Face Model</th>\n<th>CV</th>\n<th>Public LB</th>\n<th>Private LB</th>\n<th>special</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>microsoft/deberta-large</td>\n<td>706</td>\n<td>710</td>\n<td>721</td>\n<td>trained with 100% train data</td>\n</tr>\n<tr>\n<td>microsoft/deberta-large</td>\n<td>699</td>\n<td>706</td>\n<td>719</td>\n<td>add lstm, add jaccard loss</td>\n</tr>\n<tr>\n<td>microsoft/deberta-v3-large</td>\n<td>694</td>\n<td>697</td>\n<td>709</td>\n<td><a href=\"https://www.kaggle.com/nbroad/deberta-v2-3-fast-tokenizer\" target=\"_blank\">convert slow tokenizer to fast</a></td>\n</tr>\n<tr>\n<td>microsoft/deberta-xlarge</td>\n<td>708</td>\n<td>704</td>\n<td>713</td>\n<td></td>\n</tr>\n<tr>\n<td>microsoft/deberta-v2-xlarge</td>\n<td>699</td>\n<td>700</td>\n<td>716</td>\n<td><a href=\"https://www.kaggle.com/nbroad/deberta-v2-3-fast-tokenizer\" target=\"_blank\">convert slow tokenizer to fast</a></td>\n</tr>\n<tr>\n<td>allenai/longformer-large-4096</td>\n<td>702</td>\n<td>705</td>\n<td>716</td>\n<td>add lstm head</td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/ccdv-ai/convert_checkpoint_to_lsg\" target=\"_blank\">LSG converted roberta</a></td>\n<td>703</td>\n<td>702</td>\n<td>714</td>\n<td>convert 512 roberta to 1536</td>\n</tr>\n<tr>\n<td>funnel-transformer/large</td>\n<td>688</td>\n<td>689</td>\n<td>708</td>\n<td></td>\n</tr>\n<tr>\n<td>google/bigbird-roberta-base</td>\n<td>675</td>\n<td>676</td>\n<td>692</td>\n<td>train 1024 infer 1024</td>\n</tr>\n<tr>\n<td>uw-madison/yoso-4096</td>\n<td>652</td>\n<td>655</td>\n<td>668</td>\n<td>lsh_backward=False</td>\n</tr>\n</tbody>\n</table>\n<h1>Weighted Box Fusion - CV 741, Public 727, Private 740</h1>\n<p>Our final solution contained the 10 models listed above. We included 3 out of 10 K-folds for each of the 10 models. Our 8 hour 30 minute submission inferred 27 models! (we removed 3 folds from 30)</p>\n<p>Weighted Box Fusion by <a href=\"https://www.kaggle.com/zfturbo\" target=\"_blank\">@zfturbo</a> from his GitHub <a href=\"https://github.com/ZFTurbo/Weighted-Boxes-Fusion\" target=\"_blank\">here</a> was the magic that combined all the model predictions together. Individual models had average CV around 700 and the WBF ensemble achieved CV 741. (Folds from same models were averaged before WBF).</p>\n<p><img src=\"https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Mar-2022/wbf.png\" alt=\"\"></p>\n<p>Weighted Box Fusion can do something that no other ensemble method can do. If one model has prediction string <code>8 9 10 11</code> and another model has <code>10 11 12 13</code>. Then weighted box fusion takes the average of the two starts, <code>(8 + 10)/2 = 9</code> and the average of the two ends, <code>(11 + 13)/2 = 12</code> resulting in <code>9 10 11 12</code>. Furthermore, WBF reads <code>submission.csv</code> files and doesn't care what tokenizer you used, so its easy to use. (Note we add an extra column to submission dataframe with span confidence).</p>\n<p>If we averaged the token/word probabilities, or used a voting classifier, we would either get the union <code>8 9 10 11 12 13</code> or the intersection <code>10 11</code>. Neither of which we want. Also averaging two \"BIO\" predictions gives a new prediction with two different \"B\" which we do not want either.</p>\n<h1>Post Process</h1>\n<p>Chun Ming is the mastermind behind our team's strong PP. We applied the same PP to each model before WBF. Our PP code is posted <a href=\"https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\" target=\"_blank\">here</a> and Chun Ming will now describe it. Our PP significantly boosted CV LB!</p>\n<p>We applied heavy post-processing to the word-level soft predictions each model made (after averaging token probabilities across folds and before the WBF ensembler). Overall CV was improved by ~.008. </p>\n<p>In order of descending impact on CV: </p>\n<ol>\n<li><p>Repairing span predictions<br>\nSince we trained using cross-entropy loss at the token level, the raw predictions would often result in broken spans. For example, given a chain of Lead token predictions, there might be a misprediction of an “Other” in the middle. We had a rule to convert that “Other” back to Lead. </p></li>\n<li><p>Discourse-specific rules<br>\nWe came up with common sense heuristics for the discourses. For example, for Lead, Position, and Concluding Statement - there should only be a maximum of one each for a text. We’d predict the most probable candidate for each or merge close duplicate spans. </p></li>\n<li><p>Adjusting lengths of predicted spans<br>\nWe adjusted lengths of spans based on their original predicted length. For example, for a predicted Evidence span that was less than 45 words long, we’d shift the start of the predicted span back by 9 words. These rules and the improvement in LB/CV suggest we were taking advantage of the evaluation metric only requiring a 50% overlap in prediction and label to be counted as correct.</p></li>\n</ol>\n<p>It’s not sexy but sitting down and eye-balling model predictions and comparing them with ground truths using a tool like displacy was rewarding in helping us better understand the task, how our models were behaving, and how to improve model predictions. </p>\n<h1>Model Details</h1>\n<p>Surprisingly many more models than LongFormer and BigBird could be trained with sequence lengths greater than 512. All our models were trained with sequence length 1536 and inferred at 1536 (except BigBird-base at 1024).</p>\n<p>The model DeBERTa accepts any input size, so we just train with 1536 as is. </p>\n<p>The model Funnel-transformer can accept any size after updating its config.</p>\n<pre><code>model = AutoModelForTokenClassification.from_pretrained(\n    'funnel-transformer/large', num_labels=15,\n    max_position_embeddings=1536)\n</code></pre>\n<p>For BigBird, we used full attention</p>\n<pre><code>model = AutoModelForTokenClassification.from_pretrained(\n    'google/bigbird-roberta-base', num_labels=15,\n    attention_type=\"original_full\")\n</code></pre>\n<p>For YOSO, we disabled <code>lsh_backward</code></p>\n<pre><code>model = AutoModelForTokenClassification.from_pretrained(\n    'uw-madison/yoso-4096', num_labels=15,\n    lsh_backward=False)\n</code></pre>\n<h1>Model Training</h1>\n<p>Thank you Nvidia for providing us some V100 32GB GPUs and A100 40GB GPUs. For each model, we trained 6 out of 10 KFolds and built our CV from the resultant 60% train data OOF. Each fold would take approximately 4 hours on 1xGPU and required between 3 and 5 epochs to maximize val score. </p>\n<p>For two models, we used my train public notebooks <a href=\"https://www.kaggle.com/cdeotte/tensorflow-longformer-ner-cv-0-633\" target=\"_blank\">here</a> and <a href=\"https://www.kaggle.com/cdeotte/pytorch-bigbird-ner-cv-0-615\" target=\"_blank\">here</a>. For the other eight models, we used Hugging Face Trainer. Most models, used the following parameters. And we added <a href=\"https://www.kaggle.com/robikscube\" target=\"_blank\">@robikscube</a> Kaggle metric <a href=\"https://www.kaggle.com/robikscube/student-writing-competition-twitch-stream\" target=\"_blank\">here</a> and our PP directly to the Trainer evaluation, so we could watch the Kaggle metric score every 500 steps and save the model weights with best Kaggle score.</p>\n<p>Notice how we use FP16, gradient_accumulation_steps, and gradient_checkpointing. With these settings, you can basically train any size model on any GPU including Kaggle's P100 16GB GPU.</p>\n<pre><code>from transformers import TrainingArguments, Trainer\nargs = TrainingArguments( NAME,\n                     PRETRAINED_MODEL,\n                     evaluation_strategy = 'steps',\n                     eval_steps = 500,\n                     dataloader_num_workers=8,\n                     warmup_ratio=0,\n                     lr_scheduler_type = 'linear',\n                     learning_rate = 2e-5,\n                     log_level = 'warning',\n                     fp16 = True,\n                     per_device_train_batch_size = 2,\n                     per_device_eval_batch_size = 2,\n                     gradient_accumulation_steps = 2,\n                     gradient_checkpointing = True,\n                     num_train_epochs = 5,\n                     save_strategy = 'no',\n                     save_total_limit = 1)\n\ntrainer = Trainer(model,\n              args,\n              train_dataset=train_dataset,\n              eval_dataset=valid_dataset,\n              compute_metrics=KaggleMetric(valid_df, valid_dataset),\n              callbacks=[SaveBestModelCallback],\n              data_collator=data_collator,\n              tokenizer=tokenizer)\n</code></pre>\n<h1>Inference Code with PP with WBF</h1>\n<p>We posted our final submission inference code on Kaggle <a href=\"https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\" target=\"_blank\">here</a>. It includes our post process and weighted box fusion implementation. Enjoy!</p>\n<h1>Training Code on GitHub</h1>\n<p>Our training code is published on GitHub <a href=\"https://github.com/ubamba98/feedback-prize\" target=\"_blank\">here</a></p>",
      "rawMarkdown": "# Second Place Solution\nThank you Georgia State University, The Learning Agency Lab, and Kaggle for an awesome competition. The data was high quality and interesting. The metric and train test split were well done. This competition was a success and will benefit a good cause.\n\nTeaming with Chun Ming Lee and Udbhav Bamba has been wonderful. I learned more about NLP than if I had taken an online course. These two Kagglers are grandmasters at NLP and I now know how to use HuggingFace Trainer efficiently and effectively. I also know how to customize models and losses. Thank you @leecming @ubamba98 \n\n# Solution Summary\nThe secret sauce to our solution is powerful **post process** by Chun Ming (boost CV LB!), a huge **variety of models** implemented by Udbhav (many long sequence models!), and **weighted box fusion** by Chris (used in my previous comp [here][2]). Everything was fine tuned on local CV and achieved 2nd Place $35,000!\n\n| Hugging Face Model | CV | Public LB | Private LB | special |\n| --- | --- | | | |\n| microsoft/deberta-large | 706 | 710 | 721 | trained with 100% train data |\n| microsoft/deberta-large | 699 | 706 | 719 | add lstm, add jaccard loss |\n| microsoft/deberta-v3-large | 694 | 697 | 709 | [convert slow tokenizer to fast][9] |\n| microsoft/deberta-xlarge | 708 | 704 | 713 | |\n| microsoft/deberta-v2-xlarge | 699 | 700 | 716 | [convert slow tokenizer to fast][9] |\n| allenai/longformer-large-4096 | 702 | 705 | 716 | add lstm head|\n| [LSG converted roberta][1] | 703 | 702 | 714 | convert 512 roberta to 1536 |\n| funnel-transformer/large | 688 | 689 | 708 |\n| google/bigbird-roberta-base | 675 | 676 | 692 | train 1024 infer 1024 |\n| uw-madison/yoso-4096 | 652 | 655 | 668 | lsh_backward=False |\n\n# Weighted Box Fusion - CV 741, Public 727, Private 740\nOur final solution contained the 10 models listed above. We included 3 out of 10 K-folds for each of the 10 models. Our 8 hour 30 minute submission inferred 27 models! (we removed 3 folds from 30)\n\nWeighted Box Fusion by @zfturbo from his GitHub [here][3] was the magic that combined all the model predictions together. Individual models had average CV around 700 and the WBF ensemble achieved CV 741. (Folds from same models were averaged before WBF).\n\n![](https://raw.githubusercontent.com/cdeotte/Kaggle_Images/main/Mar-2022/wbf.png)\n\nWeighted Box Fusion can do something that no other ensemble method can do. If one model has prediction string `8 9 10 11` and another model has `10 11 12 13`. Then weighted box fusion takes the average of the two starts, `(8 + 10)/2 = 9` and the average of the two ends, `(11 + 13)/2 = 12` resulting in `9 10 11 12`. Furthermore, WBF reads `submission.csv` files and doesn't care what tokenizer you used, so its easy to use. (Note we add an extra column to submission dataframe with span confidence).\n\nIf we averaged the token/word probabilities, or used a voting classifier, we would either get the union `8 9 10 11 12 13` or the intersection `10 11`. Neither of which we want. Also averaging two \"BIO\" predictions gives a new prediction with two different \"B\" which we do not want either.\n\n# Post Process\nChun Ming is the mastermind behind our team's strong PP. We applied the same PP to each model before WBF. Our PP code is posted [here][10] and Chun Ming will now describe it. Our PP significantly boosted CV LB!\n\nWe applied heavy post-processing to the word-level soft predictions each model made (after averaging token probabilities across folds and before the WBF ensembler). Overall CV was improved by ~.008. \n\nIn order of descending impact on CV: \n1. Repairing span predictions\n Since we trained using cross-entropy loss at the token level, the raw predictions would often result in broken spans. For example, given a chain of Lead token predictions, there might be a misprediction of an “Other” in the middle. We had a rule to convert that “Other” back to Lead. \n\n2. Discourse-specific rules\n We came up with common sense heuristics for the discourses. For example, for Lead, Position, and Concluding Statement - there should only be a maximum of one each for a text. We’d predict the most probable candidate for each or merge close duplicate spans. \n\n3. Adjusting lengths of predicted spans\n We adjusted lengths of spans based on their original predicted length. For example, for a predicted Evidence span that was less than 45 words long, we’d shift the start of the predicted span back by 9 words. These rules and the improvement in LB/CV suggest we were taking advantage of the evaluation metric only requiring a 50% overlap in prediction and label to be counted as correct.\n\nIt’s not sexy but sitting down and eye-balling model predictions and comparing them with ground truths using a tool like displacy was rewarding in helping us better understand the task, how our models were behaving, and how to improve model predictions. \n\n# Model Details\nSurprisingly many more models than LongFormer and BigBird could be trained with sequence lengths greater than 512. All our models were trained with sequence length 1536 and inferred at 1536 (except BigBird-base at 1024).\n\nThe model DeBERTa accepts any input size, so we just train with 1536 as is. \n\nThe model Funnel-transformer can accept any size after updating its config.\n\n    model = AutoModelForTokenClassification.from_pretrained(\n        'funnel-transformer/large', num_labels=15,\n        max_position_embeddings=1536)\n\nFor BigBird, we used full attention\n\n    model = AutoModelForTokenClassification.from_pretrained(\n        'google/bigbird-roberta-base', num_labels=15,\n        attention_type=\"original_full\")\n\nFor YOSO, we disabled `lsh_backward`\n\n    model = AutoModelForTokenClassification.from_pretrained(\n        'uw-madison/yoso-4096', num_labels=15,\n        lsh_backward=False)\n\n# Model Training\nThank you Nvidia for providing us some V100 32GB GPUs and A100 40GB GPUs. For each model, we trained 6 out of 10 KFolds and built our CV from the resultant 60% train data OOF. Each fold would take approximately 4 hours on 1xGPU and required between 3 and 5 epochs to maximize val score. \n\nFor two models, we used my train public notebooks [here][7] and [here][8]. For the other eight models, we used Hugging Face Trainer. Most models, used the following parameters. And we added @robikscube Kaggle metric [here][6] and our PP directly to the Trainer evaluation, so we could watch the Kaggle metric score every 500 steps and save the model weights with best Kaggle score.\n\nNotice how we use FP16, gradient_accumulation_steps, and gradient_checkpointing. With these settings, you can basically train any size model on any GPU including Kaggle's P100 16GB GPU.\n\n    from transformers import TrainingArguments, Trainer\n    args = TrainingArguments( NAME,\n                         PRETRAINED_MODEL,\n                         evaluation_strategy = 'steps',\n                         eval_steps = 500,\n                         dataloader_num_workers=8,\n                         warmup_ratio=0,\n                         lr_scheduler_type = 'linear',\n                         learning_rate = 2e-5,\n                         log_level = 'warning',\n                         fp16 = True,\n                         per_device_train_batch_size = 2,\n                         per_device_eval_batch_size = 2,\n                         gradient_accumulation_steps = 2,\n                         gradient_checkpointing = True,\n                         num_train_epochs = 5,\n                         save_strategy = 'no',\n                         save_total_limit = 1)\n\n    trainer = Trainer(model,\n                  args,\n                  train_dataset=train_dataset,\n                  eval_dataset=valid_dataset,\n                  compute_metrics=KaggleMetric(valid_df, valid_dataset),\n                  callbacks=[SaveBestModelCallback],\n                  data_collator=data_collator,\n                  tokenizer=tokenizer)\n\n# Inference Code with PP with WBF\nWe posted our final submission inference code on Kaggle [here][10]. It includes our post process and weighted box fusion implementation. Enjoy!\n\n# Training Code on GitHub\nOur training code is published on GitHub [here][11]\n\n[1]: https://github.com/ccdv-ai/convert_checkpoint_to_lsg\n[2]: https://www.kaggle.com/c/tensorflow-great-barrier-reef/discussion/307609\n[3]: https://github.com/ZFTurbo/Weighted-Boxes-Fusion\n[4]: https://www.kaggle.com/cdeotte/tensorflow-longformer-ner-cv-0-633\n[5]: https://www.kaggle.com/cdeotte/pytorch-bigbird-ner-cv-0-615\n[6]: https://www.kaggle.com/robikscube/student-writing-competition-twitch-stream\n[7]: https://www.kaggle.com/cdeotte/tensorflow-longformer-ner-cv-0-633\n[8]: https://www.kaggle.com/cdeotte/pytorch-bigbird-ner-cv-0-615\n[9]: https://www.kaggle.com/nbroad/deberta-v2-3-fast-tokenizer\n[10]: https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\n[11]: https://github.com/ubamba98/feedback-prize",
      "votes": 203
    },
    {
      "id": 1725276,
      "postDate": "2022-03-17T01:14:46.953Z",
      "content": "<table>\n<thead>\n<tr>\n<th>Hugging Face Model</th>\n<th>CV</th>\n<th>Public LB</th>\n<th>Private LB</th>\n<th>special</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>microsoft/deberta-large</td>\n<td>706</td>\n<td>710</td>\n<td>721</td>\n<td>trained with 100% train data</td>\n</tr>\n</tbody>\n</table>\n<p>How do you get CV when training on 100% of the data?</p>",
      "rawMarkdown": "|  Hugging Face Model| CV|Public LB |Private LB | special| \n| --- | --- | --- |--- |--- |\n| microsoft/deberta-large | 706 |\t710 | \t721\t| trained with 100% train data |\n\n\nHow do you get CV when training on 100% of the data?",
      "votes": 8,
      "replies": [
        {
          "id": 1725281,
          "postDate": "2022-03-17T01:21:33.547Z",
          "content": "<p>ha, good question. The \"CV score\" is the score when training with 10 K-Fold. First we train with 10 K-Fold, and make note of the learning rate and number of epochs. Second we trained a second time using 100% data. So actually it's two models. The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721</p>",
          "rawMarkdown": "ha, good question. The \"CV score\" is the score when training with 10 K-Fold. First we train with 10 K-Fold, and make note of the learning rate and number of epochs. Second we trained a second time using 100% data. So actually it's two models. The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721",
          "votes": 9
        },
        {
          "id": 1725283,
          "postDate": "2022-03-17T01:23:32.277Z",
          "content": "<p><a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a> thanks for all your great work at Hugging Face. The NLP library <code>transformers</code> and model repository are fantastic. We also used your code to convert deberta-v2 and v3 slow tokenizers to fast tokenizers. Thanks.</p>",
          "rawMarkdown": "@nbroad thanks for all your great work at Hugging Face. The NLP library `transformers` and model repository are fantastic. We also used your code to convert deberta-v2 and v3 slow tokenizers to fast tokenizers. Thanks.",
          "votes": 9
        },
        {
          "id": 1725639,
          "postDate": "2022-03-17T09:24:15.813Z",
          "content": "<p>I greatly appreciate the comment, even though my contributions to <code>transformers</code> are pretty small relative to others. </p>\n<p>I'm always happy to share what I learn through Hugging Face with the community here.  I think the deberta v2/3 fast tokenizers should be merged to the main branch soon so it won't be so awkward to use on Kaggle. </p>\n<p>I forgot to congratulate you! This is another fantastic approach and final rank 😊</p>",
          "rawMarkdown": "I greatly appreciate the comment, even though my contributions to `transformers` are pretty small relative to others. \n\nI'm always happy to share what I learn through Hugging Face with the community here.  I think the deberta v2/3 fast tokenizers should be merged to the main branch soon so it won't be so awkward to use on Kaggle. \n\nI forgot to congratulate you! This is another fantastic approach and final rank 😊",
          "votes": 4
        },
        {
          "id": 1725709,
          "postDate": "2022-03-17T11:00:46.857Z",
          "content": "<p><em>'''The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721'''</em></p>\n<p>so 706 is out of CV of 10 models(so 10 models are submitted each being one fold of 10), whereas 710 is from a single model (only a single model is submitted) trained from all the data??</p>\n<p>Big congrats again!!</p>",
          "rawMarkdown": "*'''The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721'''*\n\nso 706 is out of CV of 10 models(so 10 models are submitted each being one fold of 10), whereas 710 is from a single model (only a single model is submitted) trained from all the data??\n\nBig congrats again!!"
        },
        {
          "id": 1732556,
          "postDate": "2022-03-23T14:05:24.470Z",
          "content": "<blockquote>\n  <p>ha, good question. The \"CV score\" is the score when training with 10 K-Fold. First we train with 10 K-Fold, and make note of the learning rate and number of epochs. Second we trained a second time using 100% data. So actually it's two models. The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721</p>\n</blockquote>\n<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> Is this technique subjective to just the NLP area or you have used this approach for Computer vision and tabular data as well?</p>",
          "rawMarkdown": "> ha, good question. The \"CV score\" is the score when training with 10 K-Fold. First we train with 10 K-Fold, and make note of the learning rate and number of epochs. Second we trained a second time using 100% data. So actually it's two models. The first model was K-Fold and got CV 706. The second model used the same hyperparameters and trained on 100% data and got Public 710 Private 721\n\n@cdeotte Is this technique subjective to just the NLP area or you have used this approach for Computer vision and tabular data as well?"
        }
      ]
    },
    {
      "id": 1725294,
      "postDate": "2022-03-17T01:36:58.300Z",
      "content": "<p>Would you mind public all the training models? Because it's too hard for us to Reappearance it.<br>\nThanks!</p>",
      "rawMarkdown": "Would you mind public all the training models? Because it's too hard for us to Reappearance it.\nThanks!",
      "votes": 6,
      "replies": [
        {
          "id": 1725298,
          "postDate": "2022-03-17T01:40:08.153Z",
          "content": "<p>We published our inference code <a href=\"https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740\" target=\"_blank\">here</a>. And we made all trained models (i.e. Kaggle datasets) public.</p>",
          "rawMarkdown": "We published our inference code [here][1]. And we made all trained models (i.e. Kaggle datasets) public.\n\n[1]: https://www.kaggle.com/cdeotte/2nd-place-solution-cv741-public727-private740",
          "votes": 8
        },
        {
          "id": 1725338,
          "postDate": "2022-03-17T02:35:17.913Z",
          "content": "<p>Got it, cheers :)</p>",
          "rawMarkdown": "Got it, cheers :)",
          "votes": 1
        }
      ]
    },
    {
      "id": 1725135,
      "postDate": "2022-03-16T20:51:49.637Z",
      "content": "<p>Great work! The ensemble use WBF of each model only, not using per word soft logits/prob merge?</p>",
      "rawMarkdown": "Great work! The ensemble use WBF of each model only, not using per word soft logits/prob merge?",
      "votes": 3,
      "replies": [
        {
          "id": 1725137,
          "postDate": "2022-03-16T20:53:56.140Z",
          "content": "<p>For different folds but same architecture, we average the probabilities and for different architectures we use WBF.</p>",
          "rawMarkdown": "For different folds but same architecture, we average the probabilities and for different architectures we use WBF.",
          "votes": 3
        },
        {
          "id": 1725139,
          "postDate": "2022-03-16T20:55:54.330Z",
          "content": "<p>Cool! Thanks!</p>",
          "rawMarkdown": "Cool! Thanks!",
          "votes": 2
        }
      ]
    },
    {
      "id": 1725234,
      "postDate": "2022-03-17T00:14:50.640Z",
      "content": "<p>Nice solution! Congrats <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> and team.  I will try your WBF method in the next NLP competition ;)</p>",
      "rawMarkdown": "Nice solution! Congrats @cdeotte and team.  I will try your WBF method in the next NLP competition ;)",
      "votes": 4
    },
    {
      "id": 1735972,
      "postDate": "2022-03-26T18:56:51.920Z",
      "content": "<p>Congratulations, thanks for sharing this </p>",
      "rawMarkdown": "Congratulations, thanks for sharing this ",
      "votes": 1
    },
    {
      "id": 1735423,
      "postDate": "2022-03-26T08:27:41.333Z",
      "content": "<p>Congratulations on this solution <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> and team 🧐<br>\nWell explained as always 👍<br>\nKeep up the good work!</p>",
      "rawMarkdown": "Congratulations on this solution @cdeotte and team 🧐\nWell explained as always 👍\nKeep up the good work!",
      "votes": 1,
      "replies": [
        {
          "id": 1736048,
          "postDate": "2022-03-26T21:41:42.450Z",
          "content": "<p>Thanks FPiotro</p>",
          "rawMarkdown": "Thanks FPiotro"
        }
      ]
    },
    {
      "id": 1734398,
      "postDate": "2022-03-25T09:56:52.950Z",
      "content": "<p>congrats.. Great work, thanks for sharing </p>",
      "rawMarkdown": "congrats.. Great work, thanks for sharing ",
      "votes": 1
    },
    {
      "id": 1733310,
      "postDate": "2022-03-24T07:13:14.743Z",
      "content": "<p>Congrats and thanks for sharing!!!<br>\nDid post processing make a big difference to improve final score? Or an enough large model like deberta and with enough training time can bring a impressive result.</p>",
      "rawMarkdown": "Congrats and thanks for sharing!!!\nDid post processing make a big difference to improve final score? Or an enough large model like deberta and with enough training time can bring a impressive result.",
      "votes": 1,
      "replies": [
        {
          "id": 1735359,
          "postDate": "2022-03-26T06:29:45.980Z",
          "content": "<p>Post processing made a large difference. Probably around +0.010</p>",
          "rawMarkdown": "Post processing made a large difference. Probably around +0.010"
        }
      ]
    },
    {
      "id": 1733060,
      "postDate": "2022-03-24T01:18:38.210Z",
      "content": "<p>It is really a great code.</p>",
      "rawMarkdown": "It is really a great code.",
      "votes": 1,
      "replies": [
        {
          "id": 1733064,
          "postDate": "2022-03-24T01:25:14.227Z",
          "content": "<p>Thanks Jingyuan</p>",
          "rawMarkdown": "Thanks Jingyuan"
        }
      ]
    },
    {
      "id": 1732976,
      "postDate": "2022-03-23T22:46:32.777Z",
      "content": "<p>Wow..<br>\nCongratulations ~!! </p>",
      "rawMarkdown": "Wow..\nCongratulations ~!! ",
      "votes": 1
    },
    {
      "id": 1732589,
      "postDate": "2022-03-23T14:34:42.820Z",
      "content": "<p>Great work, thanks for sharing details. This post process is looking great. </p>",
      "rawMarkdown": "Great work, thanks for sharing details. This post process is looking great. ",
      "votes": 1
    },
    {
      "id": 1732005,
      "postDate": "2022-03-22T23:21:57.423Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a></p>",
      "rawMarkdown": "Congratulations @cdeotte",
      "votes": 1
    },
    {
      "id": 1727990,
      "postDate": "2022-03-18T14:02:03.570Z",
      "content": "<p>Great work. Thanks for sharing the code.</p>",
      "rawMarkdown": "Great work. Thanks for sharing the code.",
      "votes": 1
    },
    {
      "id": 1727879,
      "postDate": "2022-03-18T12:13:18.350Z",
      "content": "<blockquote>\n  <p>Adjusting lengths of predicted spans<br>\n  We adjusted lengths of spans based on their original predicted length. For example, for a predicted Evidence span that was less than 45 words long, we’d shift the start of the predicted span back by 9 words. These rules and the improvement in LB/CV suggest we were taking advantage of the evaluation metric only requiring a 50% overlap in prediction and label to be counted as correct.</p>\n</blockquote>\n<p><a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> ,<br>\nHow did you decide how many words to shift the predictions by?</p>",
      "rawMarkdown": ">Adjusting lengths of predicted spans\nWe adjusted lengths of spans based on their original predicted length. For example, for a predicted Evidence span that was less than 45 words long, we’d shift the start of the predicted span back by 9 words. These rules and the improvement in LB/CV suggest we were taking advantage of the evaluation metric only requiring a 50% overlap in prediction and label to be counted as correct.\n\n@leecming ,\nHow did you decide how many words to shift the predictions by?",
      "votes": 1,
      "replies": [
        {
          "id": 1727885,
          "postDate": "2022-03-18T12:19:54.667Z",
          "content": "<p>Optimized against CV.</p>\n<p>I was somewhat paranoid about these rules and pushed for our second sub to use a more conservative subset, excluding the length adjustments. Turns out it was unnecessary as CV/LB showed a strong correlation extending to private LB. </p>",
          "rawMarkdown": "Optimized against CV.\n\nI was somewhat paranoid about these rules and pushed for our second sub to use a more conservative subset, excluding the length adjustments. Turns out it was unnecessary as CV/LB showed a strong correlation extending to private LB. ",
          "votes": 2
        },
        {
          "id": 1727904,
          "postDate": "2022-03-18T12:35:22.790Z",
          "content": "<p>So did you just try a bunch of shifts (-1, +1, -2, +2, etc.) and see how that impacted the CV?</p>",
          "rawMarkdown": "So did you just try a bunch of shifts (-1, +1, -2, +2, etc.) and see how that impacted the CV?",
          "votes": 1
        },
        {
          "id": 1727915,
          "postDate": "2022-03-18T12:46:10.590Z",
          "content": "<p>Broadly yes - we had optimized CV code that used multiprocessing so we could test hyperparam changes very rapidly (&lt;10s per run for 7K OOF samples). I tried using Optuna but found my gut sense better at optimizing :)</p>\n<p>Ofc, in hindsight, this post-processing could have been potentially been done by a 2nd level ML model as a number of top teams did. </p>",
          "rawMarkdown": "Broadly yes - we had optimized CV code that used multiprocessing so we could test hyperparam changes very rapidly (<10s per run for 7K OOF samples). I tried using Optuna but found my gut sense better at optimizing :)\n\nOfc, in hindsight, this post-processing could have been potentially been done by a 2nd level ML model as a number of top teams did. ",
          "votes": 1
        }
      ]
    },
    {
      "id": 1726251,
      "postDate": "2022-03-17T19:43:30.263Z",
      "content": "<p>Great work. Thanks for sharing the code.</p>",
      "rawMarkdown": "Great work. Thanks for sharing the code.",
      "votes": 1
    },
    {
      "id": 1726184,
      "postDate": "2022-03-17T18:07:44.137Z",
      "content": "<p>Congrats Amazing Work</p>",
      "rawMarkdown": "Congrats Amazing Work",
      "votes": 1
    },
    {
      "id": 1725666,
      "postDate": "2022-03-17T09:55:23.617Z",
      "content": "<p>Thank you so much Chris. You've got a new follower to go through your work. ;) </p>",
      "rawMarkdown": "Thank you so much Chris. You've got a new follower to go through your work. ;) ",
      "votes": 1
    },
    {
      "id": 1725424,
      "postDate": "2022-03-17T04:49:03.590Z",
      "content": "<p>Really appreciate your team's efforts in explaining your thought process and approach - congrats on 2nd 🎉</p>",
      "rawMarkdown": "Really appreciate your team's efforts in explaining your thought process and approach - congrats on 2nd 🎉",
      "votes": 1
    },
    {
      "id": 1725128,
      "postDate": "2022-03-16T20:39:47.723Z",
      "content": "<p>Using WBF for ensembling spans is brilliant! Great work! </p>",
      "rawMarkdown": "Using WBF for ensembling spans is brilliant! Great work! ",
      "votes": 1
    },
    {
      "id": 1725120,
      "postDate": "2022-03-16T20:31:40.967Z",
      "content": "<p><a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> your last link does not point to the inference kernel?</p>",
      "rawMarkdown": "@cdeotte your last link does not point to the inference kernel?",
      "votes": 1,
      "replies": [
        {
          "id": 1725124,
          "postDate": "2022-03-16T20:35:47.477Z",
          "content": "<p>It should work now. It will display a quick save and we're running now too. We will also share the datasets later today. Congratulations CroDoc and team for you great finish and big jump in last few days!</p>",
          "rawMarkdown": "It should work now. It will display a quick save and we're running now too. We will also share the datasets later today. Congratulations CroDoc and team for you great finish and big jump in last few days!",
          "votes": 3
        },
        {
          "id": 1725132,
          "postDate": "2022-03-16T20:49:48.840Z",
          "content": "<p>It works now. Thank you Chris! It was a crazy ride till the end.</p>\n<p>Congrats to your team. Especially to <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a>. Yellow circle is on its way 😎</p>",
          "rawMarkdown": "It works now. Thank you Chris! It was a crazy ride till the end.\n\nCongrats to your team. Especially to @leecming. Yellow circle is on its way 😎",
          "votes": 2
        }
      ]
    },
    {
      "id": 1731824,
      "postDate": "2022-03-22T18:12:12.813Z",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> for making it into top 10 competitions ranking for 1st time!</p>\n<p>Best of luck continuing to rise!<br>\nIt's nice when the #1 contributor for kagglers of all stages does well.</p>",
      "rawMarkdown": "Congratulations @cdeotte for making it into top 10 competitions ranking for 1st time!\n\nBest of luck continuing to rise!\nIt's nice when the #1 contributor for kagglers of all stages does well.",
      "votes": 2,
      "replies": [
        {
          "id": 1733066,
          "postDate": "2022-03-24T01:28:43.840Z",
          "content": "<p>Thanks <a href=\"https://www.kaggle.com/jacob34\" target=\"_blank\">@jacob34</a> I'm excited to enter competitions top 10. My favorite thing on Kaggle is discussions and notebooks, but recently I've been working hard on competitions.</p>",
          "rawMarkdown": "Thanks @jacob34 I'm excited to enter competitions top 10. My favorite thing on Kaggle is discussions and notebooks, but recently I've been working hard on competitions.",
          "votes": 1
        }
      ]
    },
    {
      "id": 1725730,
      "postDate": "2022-03-17T11:26:40.857Z",
      "content": "<p>congrats and thanks , learn a lot from you.</p>",
      "rawMarkdown": "congrats and thanks , learn a lot from you.",
      "votes": 2
    },
    {
      "id": 1725705,
      "postDate": "2022-03-17T10:56:18.980Z",
      "content": "<p>Kudos to you and your team. Nicely done…<br>\nThanks for the detailed writeup as always 🖖</p>",
      "rawMarkdown": "Kudos to you and your team. Nicely done…\nThanks for the detailed writeup as always 🖖",
      "votes": 2
    },
    {
      "id": 1725691,
      "postDate": "2022-03-17T10:36:56.153Z",
      "content": "<p>amazing work, thx for ur selfless sharing</p>",
      "rawMarkdown": "amazing work, thx for ur selfless sharing",
      "votes": 2
    },
    {
      "id": 1725475,
      "postDate": "2022-03-17T06:19:49.223Z",
      "content": "<p>Congratulations!<br>\nFor deberta-v3-large I got worse CV than the longformer-large.<br>\nI trained 5 fold, each fold has CV around 0.680. I trained 5 fold using the same folds from abhishek here:<br>\n<a href=\"https://www.kaggle.com/abhishek/creating-folds-properly-hopefully-p\" target=\"_blank\">https://www.kaggle.com/abhishek/creating-folds-properly-hopefully-p</a><br>\nwith his training code here:<br>\n<a href=\"https://github.com/abhishekkrthakur/long-text-token-classification\" target=\"_blank\">https://github.com/abhishekkrthakur/long-text-token-classification</a><br>\nI also converted the deberta tokenizers using <a href=\"https://www.kaggle.com/nbroad\" target=\"_blank\">@nbroad</a>'s code.<br>\nI used max_len 1536, batch_size 2, and I tried learning rates 1e-5, 2e-6, 1e-6, 2e-7, using argument --epochs 10, and I would stop training after 3~5 epochs.</p>\n<p>Any idea why I got worse CV than yours? I am guessing it's either batch size, learning rate, or because I used 5 folds.</p>",
      "rawMarkdown": "Congratulations!\nFor deberta-v3-large I got worse CV than the longformer-large.\nI trained 5 fold, each fold has CV around 0.680. I trained 5 fold using the same folds from abhishek here:\nhttps://www.kaggle.com/abhishek/creating-folds-properly-hopefully-p\nwith his training code here:\nhttps://github.com/abhishekkrthakur/long-text-token-classification\nI also converted the deberta tokenizers using @nbroad's code.\nI used max_len 1536, batch_size 2, and I tried learning rates 1e-5, 2e-6, 1e-6, 2e-7, using argument --epochs 10, and I would stop training after 3~5 epochs.\n\nAny idea why I got worse CV than yours? I am guessing it's either batch size, learning rate, or because I used 5 folds.",
      "votes": 2,
      "replies": [
        {
          "id": 1725624,
          "postDate": "2022-03-17T09:07:35.947Z",
          "content": "<p>I guess it could be because of the offset mapping each tokenizer has different way of generating offsets (some include spaces and some don't) and it will effect your NER labels and predictions, especially for the B-tag as they are more rare.</p>",
          "rawMarkdown": "I guess it could be because of the offset mapping each tokenizer has different way of generating offsets (some include spaces and some don't) and it will effect your NER labels and predictions, especially for the B-tag as they are more rare.",
          "votes": 4
        }
      ]
    },
    {
      "id": 1725217,
      "postDate": "2022-03-16T23:21:56.723Z",
      "content": "<p>Congratz <a href=\"https://www.kaggle.com/cdeotte\" target=\"_blank\">@cdeotte</a> <a href=\"https://www.kaggle.com/leecming\" target=\"_blank\">@leecming</a> <a href=\"https://www.kaggle.com/ubamba98\" target=\"_blank\">@ubamba98</a> !<br>\nThat 2nd place is no surprise, I was looking forward to your solution :)</p>",
      "rawMarkdown": "Congratz @cdeotte @leecming @ubamba98 !\nThat 2nd place is no surprise, I was looking forward to your solution :)",
      "votes": 2
    },
    {
      "id": 1725142,
      "postDate": "2022-03-16T20:59:41.450Z",
      "content": "<p>Congrats Chris, you never fail to amaze :D</p>",
      "rawMarkdown": "Congrats Chris, you never fail to amaze :D",
      "votes": 2,
      "replies": [
        {
          "id": 1725144,
          "postDate": "2022-03-16T21:04:12.647Z",
          "content": "<p>Thanks! I could not have done it without my awesome teammates Chun Ming Lee and Udbhav Bamba</p>",
          "rawMarkdown": "Thanks! I could not have done it without my awesome teammates Chun Ming Lee and Udbhav Bamba",
          "votes": 2
        }
      ]
    },
    {
      "id": 1840542,
      "postDate": "2022-07-02T10:46:56.530Z",
      "content": "<p>Did you face any issues customizing trainer API? For one, I think it needs valid_batch_size = 1 else there seems to be an error in its code for the last batch. The other issue is in my case the predictions returned to the compute_metrics (via the EvalPrediction) is a blank array. Any suggestions would immensely help</p>",
      "rawMarkdown": "Did you face any issues customizing trainer API? For one, I think it needs valid_batch_size = 1 else there seems to be an error in its code for the last batch. The other issue is in my case the predictions returned to the compute_metrics (via the EvalPrediction) is a blank array. Any suggestions would immensely help"
    },
    {
      "id": 1765966,
      "postDate": "2022-04-24T04:04:11.947Z",
      "content": "<p>Congratulations, your sharing has helped me a lot. I have a question about how to get the best thresholds of different classes.</p>",
      "rawMarkdown": "Congratulations, your sharing has helped me a lot. I have a question about how to get the best thresholds of different classes.",
      "replies": [
        {
          "id": 1765970,
          "postDate": "2022-04-24T04:11:57.723Z",
          "content": "<p>You can choose them based on your validation </p>",
          "rawMarkdown": "You can choose them based on your validation ",
          "votes": 1
        }
      ]
    },
    {
      "id": 1735339,
      "postDate": "2022-03-26T06:10:08.957Z",
      "rawMarkdown": "",
      "votes": 1,
      "isDeleted": true
    },
    {
      "id": 1727668,
      "postDate": "2022-03-18T06:55:39.203Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 1734353,
      "postDate": "2022-03-25T08:44:40.327Z",
      "content": "<p>This is great, and thanks for sharing</p>",
      "rawMarkdown": "This is great, and thanks for sharing",
      "votes": 1
    },
    {
      "id": 1734264,
      "postDate": "2022-03-25T06:43:43.143Z",
      "content": "<p>Congrats and thanks for sharing.👌</p>",
      "rawMarkdown": "Congrats and thanks for sharing.👌",
      "votes": 1
    },
    {
      "id": 1734235,
      "postDate": "2022-03-25T05:51:49.607Z",
      "content": "<p>Thank you for sharing!</p>",
      "rawMarkdown": "Thank you for sharing!",
      "votes": 1
    },
    {
      "id": 1733106,
      "postDate": "2022-03-24T02:35:36.353Z",
      "content": "<p>Congrats and thanks for sharing.</p>",
      "rawMarkdown": "Congrats and thanks for sharing.",
      "votes": 1
    },
    {
      "id": 1725886,
      "postDate": "2022-03-17T13:50:16.643Z",
      "content": "<p>Thanks for your result, it's amazing!</p>",
      "rawMarkdown": "Thanks for your result, it's amazing!",
      "votes": 1
    },
    {
      "id": 1787055,
      "postDate": "2022-05-13T14:40:05.043Z",
      "content": "<p>Thanks for your insight!</p>",
      "rawMarkdown": "Thanks for your insight!"
    },
    {
      "id": 1727849,
      "postDate": "2022-03-18T11:40:40.370Z",
      "content": "<p>Amazing! Thanks a lot for sharing. </p>",
      "rawMarkdown": "Amazing! Thanks a lot for sharing. "
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T12:38:03Z",
  "competition_id": 31779,
  "competition_slug": "feedback-prize-2021",
  "team_id": 7929547,
  "solution_url": "/competitions/feedback-prize-2021/writeups/feedforward-2nd-place-weighted-box-fusion-and-post"
}