{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.13"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":106809},{"sourceType":"datasetVersion","sourceId":14326483},{"sourceType":"datasetVersion","sourceId":14338607},{"sourceType":"datasetVersion","sourceId":19238725}],"dockerImageVersionId":31430,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":17869.939104,"end_time":"2026-08-30T12:09:41.341003+00:00","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2026-08-30T07:11:51.401899+00:00","version":"2.7.0"},"widgets":{"application/vnd.jupyter.widget-state+json":{"state":{"01292c31cc214faeb5e8810a76a696ac":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"02b36d8a08224b59a69fa804df89e10d":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_46b1870e65184198b6b7d09645443160","placeholder":"​","style":"IPY_MODEL_72aef481a96e46f3af9452799ba7f4fe","tabbable":null,"tooltip":null,"value":" 7.03M/? [00:00&lt;00:00, 109MB/s]"}},"05eea5ebd3354638a9a8eb7a992b79b0":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_4cba99ba241a46cfac7296c78a7e348a","placeholder":"​","style":"IPY_MODEL_5e68d98af02d4e4396a13c957d7354cc","tabbable":null,"tooltip":null,"value":" 7.23k/? [00:00&lt;00:00, 612kB/s]"}},"060fddd674364302bf958b7dbe277638":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_08c3d854fe444ea5a824162276d81d25","IPY_MODEL_0e58dc2a93f9464aadf0ebf7a24b221e","IPY_MODEL_a9123d269e2e4d94b113cf75165c4b0e"],"layout":"IPY_MODEL_9ffe094ca3f846f4b581d5a52447bccf","tabbable":null,"tooltip":null}},"08c3d854fe444ea5a824162276d81d25":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_e74f34b02efd44808ea526f9656aa7e3","placeholder":"​","style":"IPY_MODEL_5de3fbc1ae59447a907a95e3efc8c446","tabbable":null,"tooltip":null,"value":"generation_config.json: 100%"}},"0945ad8363024dd49c289aec7f489d9a":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"096d59e6b4fe4989a50fa69bfc7d49c7":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"0b2d77a55e834c6fbee709a01adc7a48":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_93d4218a395e463a8e4316107b87ba1e","IPY_MODEL_aeefeefbad6f4eb4a8edeb0d1a2f93bb","IPY_MODEL_05eea5ebd3354638a9a8eb7a992b79b0"],"layout":"IPY_MODEL_effdc84317114ecf879f14ae8f48f051","tabbable":null,"tooltip":null}},"0e58dc2a93f9464aadf0ebf7a24b221e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_adc77fc3875f4319a0c862e31ceb4a3a","max":138,"min":0,"orientation":"horizontal","style":"IPY_MODEL_f23a1108a5034e5ea927e78def69ba78","tabbable":null,"tooltip":null,"value":138}},"118d5e0cadfa417ea2fe1b04ec266280":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_7a880c3d3bfe4e359ae446bd054edcb3","placeholder":"​","style":"IPY_MODEL_dff27212cc4b4d4b9764fb91fe583efc","tabbable":null,"tooltip":null,"value":"Download complete: 100%"}},"12591bc8ac7d44abbe9458652338b5cb":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_b3e2859f112f4dbb97721bd045fef18f","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_ddb39ec08b6847a4947079295d4a216c","tabbable":null,"tooltip":null,"value":1}},"1680fda280514f30a8b3f4d4a0978894":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_d1abfd605cca4a84851bc24d3f0aa020","placeholder":"​","style":"IPY_MODEL_01292c31cc214faeb5e8810a76a696ac","tabbable":null,"tooltip":null,"value":" 1.67M/? [00:00&lt;00:00, 57.3MB/s]"}},"191239b108ec4c7a9db1681c5ca318b0":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1d4429f07324401bb4c1fa571f68962d":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1e0d543c0f2c4761a8552240def561d2":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"1ff81c84d0d34c06be2b871a1bfe6315":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2b311fa27c8e413db140dd51a063c904":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"30789603f57544388a101173042d4d85":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"350eb1d9636c4412be477a3c9f11dd03":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_f33cf4287d804b21962fc5974e2a24eb","max":339,"min":0,"orientation":"horizontal","style":"IPY_MODEL_a68f4c07cd9747fabe9eb4102c4d9cfa","tabbable":null,"tooltip":null,"value":339}},"36bdee7ef04b4b89a5472703b53698d7":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3ae901f787de42b886c658d4a464e773":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_3da967e9c1c3457b9a4f1c4bf5c14c85","placeholder":"​","style":"IPY_MODEL_cecaceadee2e40efb26476ce3ac31d43","tabbable":null,"tooltip":null,"value":"Loading weights: 100%"}},"3b5aa7f6e7b446eeadac72d7c4875324":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"3d2e67be98b44f0bae17c3bd54fb6a6e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_3ae901f787de42b886c658d4a464e773","IPY_MODEL_350eb1d9636c4412be477a3c9f11dd03","IPY_MODEL_83b9b0323c00400b85a3e6a1f00b9a3c"],"layout":"IPY_MODEL_54c264845d794c20b3ccc9ebcbb193e6","tabbable":null,"tooltip":null}},"3d4eeb71abe848cb8e04ec47fb315596":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3da967e9c1c3457b9a4f1c4bf5c14c85":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4041932dc6c04aab98b6387cc90ecb15":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"407cc12663404432aeccc5cdcc70eda9":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_8f5fc463183e48a0bf70bddfe0b76966","placeholder":"​","style":"IPY_MODEL_f44d27d19de44ccdb50213f188d71a3b","tabbable":null,"tooltip":null,"value":" 686/686 [00:00&lt;00:00, 66.6kB/s]"}},"449b95b6c65846fb9d2291f47d03c80b":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"45acff2134e24d0e8187ff262629f4c4":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"46b1870e65184198b6b7d09645443160":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4938f51303f940989c8295f8997e219c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_1ff81c84d0d34c06be2b871a1bfe6315","placeholder":"​","style":"IPY_MODEL_096d59e6b4fe4989a50fa69bfc7d49c7","tabbable":null,"tooltip":null,"value":" 27.8k/? [00:00&lt;00:00, 2.43MB/s]"}},"4c86a13746844dddaeecf7b0c30fe2ad":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"4cba99ba241a46cfac7296c78a7e348a":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4e6d7e40102d4be29ad47640c6da97fa":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_6d2fd8145af34c57bfbb241ff5135fbf","max":686,"min":0,"orientation":"horizontal","style":"IPY_MODEL_5abc3671c5974c24988676c74aec0c29","tabbable":null,"tooltip":null,"value":686}},"500851c11da042e79946cabe1692c2b0":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_80d58400361f4811a241eed46b72a0a5","IPY_MODEL_4e6d7e40102d4be29ad47640c6da97fa","IPY_MODEL_407cc12663404432aeccc5cdcc70eda9"],"layout":"IPY_MODEL_2b311fa27c8e413db140dd51a063c904","tabbable":null,"tooltip":null}},"54c264845d794c20b3ccc9ebcbb193e6":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5abc3671c5974c24988676c74aec0c29":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"5c7280d1db9d4128a1a42602ff836e8c":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5d1f346ede9f429d94e65afb9dfacb76":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5de3fbc1ae59447a907a95e3efc8c446":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"5e68d98af02d4e4396a13c957d7354cc":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"6a8ede4e048740a7a5d4cb2e659b3674":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"6bb33c9307884865ab8341e78aeafa02":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_88a8071576dc4722998aa86056c17ed6","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_0945ad8363024dd49c289aec7f489d9a","tabbable":null,"tooltip":null,"value":1}},"6d2fd8145af34c57bfbb241ff5135fbf":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"72aef481a96e46f3af9452799ba7f4fe":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"73d91db394cc4363928934e1f530ebb3":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"757fa140e757443bbf83d4686741a232":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7a880c3d3bfe4e359ae446bd054edcb3":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7ad632c07f3444878d5d5326123a2378":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f439e5d1446a46b5a7714fdf80d73554","IPY_MODEL_e06e0c58afab4ee0933ce63cd14982c6","IPY_MODEL_02b36d8a08224b59a69fa804df89e10d"],"layout":"IPY_MODEL_45acff2134e24d0e8187ff262629f4c4","tabbable":null,"tooltip":null}},"7b7afb209d5f44d88c1e57318377f625":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7ec03852b9504358aca9e4334a7e2c58":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_7b7afb209d5f44d88c1e57318377f625","placeholder":"​","style":"IPY_MODEL_a2dc658efdb446928d5a11cef1c0a4d1","tabbable":null,"tooltip":null,"value":" 4/4 [01:10&lt;00:00, 70.87s/it]"}},"7f68bd8bd9fd425b8ec57d4862469fa3":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7fdfa09e3db144be84368b8e9d77bf15":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"80a4cc2883bf48ec9091db4fe9565024":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"80d58400361f4811a241eed46b72a0a5":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_8271259da27642e5beff094d97356a62","placeholder":"​","style":"IPY_MODEL_d9941db247234d4bbf83dc5fcb35e51e","tabbable":null,"tooltip":null,"value":"config.json: 100%"}},"8271259da27642e5beff094d97356a62":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"83b9b0323c00400b85a3e6a1f00b9a3c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_aa65eff740104be08b50401313e3d288","placeholder":"​","style":"IPY_MODEL_a6b4664f855744298810fdec58b04c5a","tabbable":null,"tooltip":null,"value":" 339/339 [01:31&lt;00:00, 25.99it/s, Materializing param=model.norm.weight]"}},"86cdd3977b1c4850ac704db54375b384":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_cc0fb4f947a04a6597e725153d16a8a6","IPY_MODEL_d74ed9d86a1b49fbbf7dfe9047b59fbd","IPY_MODEL_1680fda280514f30a8b3f4d4a0978894"],"layout":"IPY_MODEL_5c7280d1db9d4128a1a42602ff836e8c","tabbable":null,"tooltip":null}},"86db5afc38994ba7b43d131ad1720852":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_d86d59981f3340deb42229c185479afe","placeholder":"​","style":"IPY_MODEL_97294399543c412ba2f21a76182e91db","tabbable":null,"tooltip":null,"value":" 15.2G/15.2G [01:10&lt;00:00, 398MB/s]"}},"88a8071576dc4722998aa86056c17ed6":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"20px"}},"8d29aabd0b6549cfa5b0a9584f79855e":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"20px"}},"8f21c2d2350c4e5c870636de63ae4c61":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_36bdee7ef04b4b89a5472703b53698d7","placeholder":"​","style":"IPY_MODEL_7fdfa09e3db144be84368b8e9d77bf15","tabbable":null,"tooltip":null,"value":"model.safetensors.index.json: "}},"8f5fc463183e48a0bf70bddfe0b76966":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"93d4218a395e463a8e4316107b87ba1e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_9c784d65efbf4b4e9702b668c7e3863a","placeholder":"​","style":"IPY_MODEL_d7a61cd6e04649b8b55a824a6c03c246","tabbable":null,"tooltip":null,"value":"tokenizer_config.json: "}},"94a49286e62d467495f458a966620099":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_d1fa26a909184877932c4b9bd10b00ee","placeholder":"​","style":"IPY_MODEL_30789603f57544388a101173042d4d85","tabbable":null,"tooltip":null,"value":" 2.78M/? [00:00&lt;00:00, 64.7MB/s]"}},"97294399543c412ba2f21a76182e91db":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"998f4fbacfb44fe9b1268bc0157b20d4":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_8f21c2d2350c4e5c870636de63ae4c61","IPY_MODEL_fcaca91fd23a4a928e959e0c74c75264","IPY_MODEL_4938f51303f940989c8295f8997e219c"],"layout":"IPY_MODEL_73d91db394cc4363928934e1f530ebb3","tabbable":null,"tooltip":null}},"9c784d65efbf4b4e9702b668c7e3863a":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"9ffe094ca3f846f4b581d5a52447bccf":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"a2dc658efdb446928d5a11cef1c0a4d1":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"a68f4c07cd9747fabe9eb4102c4d9cfa":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"a6b4664f855744298810fdec58b04c5a":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"a9123d269e2e4d94b113cf75165c4b0e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_ccffc78383f84a339347a74f3aac50b5","placeholder":"​","style":"IPY_MODEL_80a4cc2883bf48ec9091db4fe9565024","tabbable":null,"tooltip":null,"value":" 138/138 [00:00&lt;00:00, 16.9kB/s]"}},"aa65eff740104be08b50401313e3d288":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"adc77fc3875f4319a0c862e31ceb4a3a":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"aeefeefbad6f4eb4a8edeb0d1a2f93bb":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_8d29aabd0b6549cfa5b0a9584f79855e","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_d7393215b2ac4e1d962a19caa8be28b6","tabbable":null,"tooltip":null,"value":1}},"b3e2859f112f4dbb97721bd045fef18f":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"20px"}},"b93c05f8c0714e5091add288f8239c15":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_757fa140e757443bbf83d4686741a232","placeholder":"​","style":"IPY_MODEL_449b95b6c65846fb9d2291f47d03c80b","tabbable":null,"tooltip":null,"value":"vocab.json: "}},"bb8ea1f78ef0483a9ff721cec8370104":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"20px"}},"c0b50da42a0e494a9aae322868e38281":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_5d1f346ede9f429d94e65afb9dfacb76","max":4,"min":0,"orientation":"horizontal","style":"IPY_MODEL_1e0d543c0f2c4761a8552240def561d2","tabbable":null,"tooltip":null,"value":4}},"c35f08bbf5254b41b855a7d2820a03d4":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c37a9632a45c4958a97cc75f774b7430":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"20px"}},"c57edc73f2a64398ae75d8001272f1d0":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"cc0fb4f947a04a6597e725153d16a8a6":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_191239b108ec4c7a9db1681c5ca318b0","placeholder":"​","style":"IPY_MODEL_c57edc73f2a64398ae75d8001272f1d0","tabbable":null,"tooltip":null,"value":"merges.txt: "}},"ccffc78383f84a339347a74f3aac50b5":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"cecaceadee2e40efb26476ce3ac31d43":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"d1abfd605cca4a84851bc24d3f0aa020":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d1fa26a909184877932c4b9bd10b00ee":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d7393215b2ac4e1d962a19caa8be28b6":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"d74ed9d86a1b49fbbf7dfe9047b59fbd":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_c37a9632a45c4958a97cc75f774b7430","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_4c86a13746844dddaeecf7b0c30fe2ad","tabbable":null,"tooltip":null,"value":1}},"d7a61cd6e04649b8b55a824a6c03c246":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"d86d59981f3340deb42229c185479afe":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d88f37396128402e8093ed753e78c078":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"20px"}},"d9941db247234d4bbf83dc5fcb35e51e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"ddb39ec08b6847a4947079295d4a216c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"de1ce4bd049340eeb9ac0552b7a6706f":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f2ddd69126694e6fa11aaeac001d9497","IPY_MODEL_c0b50da42a0e494a9aae322868e38281","IPY_MODEL_7ec03852b9504358aca9e4334a7e2c58"],"layout":"IPY_MODEL_1d4429f07324401bb4c1fa571f68962d","tabbable":null,"tooltip":null}},"dff27212cc4b4d4b9764fb91fe583efc":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"e06e0c58afab4ee0933ce63cd14982c6":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_d88f37396128402e8093ed753e78c078","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_e0de74766476440b9e4eeaa9159a81b3","tabbable":null,"tooltip":null,"value":1}},"e0de74766476440b9e4eeaa9159a81b3":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"e207373f633f42c5abbe930e6722a785":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_118d5e0cadfa417ea2fe1b04ec266280","IPY_MODEL_12591bc8ac7d44abbe9458652338b5cb","IPY_MODEL_86db5afc38994ba7b43d131ad1720852"],"layout":"IPY_MODEL_3d4eeb71abe848cb8e04ec47fb315596","tabbable":null,"tooltip":null}},"e6d027ec0eba48f292f2d77cfcc3b0de":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"e74f34b02efd44808ea526f9656aa7e3":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"effdc84317114ecf879f14ae8f48f051":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f23a1108a5034e5ea927e78def69ba78":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"f2ddd69126694e6fa11aaeac001d9497":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_c35f08bbf5254b41b855a7d2820a03d4","placeholder":"​","style":"IPY_MODEL_3b5aa7f6e7b446eeadac72d7c4875324","tabbable":null,"tooltip":null,"value":"Fetching 4 files: 100%"}},"f33cf4287d804b21962fc5974e2a24eb":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f439e5d1446a46b5a7714fdf80d73554":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_7f68bd8bd9fd425b8ec57d4862469fa3","placeholder":"​","style":"IPY_MODEL_6a8ede4e048740a7a5d4cb2e659b3674","tabbable":null,"tooltip":null,"value":"tokenizer.json: "}},"f44d27d19de44ccdb50213f188d71a3b":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"f6a47c5c86c1455b8538a8a6c468cc9b":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_b93c05f8c0714e5091add288f8239c15","IPY_MODEL_6bb33c9307884865ab8341e78aeafa02","IPY_MODEL_94a49286e62d467495f458a966620099"],"layout":"IPY_MODEL_e6d027ec0eba48f292f2d77cfcc3b0de","tabbable":null,"tooltip":null}},"fcaca91fd23a4a928e959e0c74c75264":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_bb8ea1f78ef0483a9ff721cec8370104","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_4041932dc6c04aab98b6387cc90ecb15","tabbable":null,"tooltip":null,"value":1}}},"version_major":2,"version_minor":0}}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"e22fc1a4","cell_type":"markdown","source":"# BLOCK 1 · SETUP, CONFIGURATION & UTILITIES","metadata":{"papermill":{"duration":0.024683,"end_time":"2026-08-30T07:11:54.08032+00:00","exception":false,"start_time":"2026-08-30T07:11:54.055637+00:00","status":"completed"},"tags":[]}},{"id":"6b90eb8f","cell_type":"code","source":"!pip install transformers accelerate bitsandbytes scipy jiwer -q","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:11:54.124922Z","iopub.status.busy":"2026-08-30T07:11:54.124599Z","iopub.status.idle":"2026-08-30T07:12:02.048252Z","shell.execute_reply":"2026-08-30T07:12:02.047322Z"},"papermill":{"duration":7.94826,"end_time":"2026-08-30T07:12:02.050119+00:00","exception":false,"start_time":"2026-08-30T07:11:54.101859+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"97d221a4","cell_type":"code","source":"\"\"\"\n============================================================================\nICCIT · Brain-to-Text '25 — Hybrid acoustic model + KenLM + Qwen2.5-7B rescoring\n============================================================================\nSingle-file, error-free reimplementation of the original notebook.\n\nWHAT IS DIFFERENT FROM THE NOTEBOOK (by request):\n  * TRAINING CODE IS PRESENT BUT SKIPPED. `SKIP_TRAINING = True`, so the model\n    + training functions are all defined and ready, but no epochs run. Flip it\n    to False (and provide the data) to actually train from scratch.\n  * BEST HYPERPARAMETERS ARE PINNED AS DEFAULTS. The expensive lm_weight/lambda\n    sweeps are OFF (`RUN_HYPERPARAM_SWEEPS = False`); instead the single best\n    combo found by the notebook's own sweep is hard-set:\n        lm_weight        = 4.5\n        LLM_FUSION_WEIGHT = 0.75   (fusion lambda)\n        rescoring LLM     = Qwen/Qwen2.5-7B (4-bit nf4)\n        beam=250, nbest=30, gate percentiles 1 / 75, margin-adaptive fusion\n    -> validation WER 7.62% / CER 5.31% / PER 12.12%.\n  * Only the numeric pipeline (metrics + submission) is kept; the many\n    near-identical paper-plot cells are dropped to stay compact and runnable.\n\nREQUIREMENTS (Kaggle, internet ON for the LLM + flashlight-text):\n    pip install transformers accelerate bitsandbytes scipy jiwer editdistance\n    pip install h5py torchaudio flashlight-text\n============================================================================\n\"\"\"\n\n# ============================================================================\n# BLOCK 1 · SETUP, CONFIGURATION & UTILITIES\n# ============================================================================\nimport os\nimport gc\nimport re\nimport sys\nimport json\nimport random\nimport subprocess\nimport importlib\nfrom glob import glob\nfrom pathlib import Path\n\nimport numpy as np\nimport pandas as pd\nimport h5py\nfrom tqdm import tqdm\nimport editdistance\nimport jiwer\nfrom scipy.ndimage import gaussian_filter1d\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.nn.utils.rnn import pad_sequence, pack_padded_sequence, pad_packed_sequence\n\ntry:\n    import kagglehub\nexcept ImportError:\n    kagglehub = None\n\n\n# --- AMP compatibility shim (avoids the deprecated torch.cuda.amp API) ------\ntry:\n    from torch.amp import autocast as _amp_autocast, GradScaler as _AmpGradScaler\n\n    def amp_autocast(enabled=True):\n        return _amp_autocast('cuda', enabled=enabled)\n\n    def make_grad_scaler(enabled=True):\n        return _AmpGradScaler('cuda', enabled=enabled)\nexcept Exception:  # older torch\n    from torch.cuda.amp import autocast as _cuda_autocast, GradScaler as _CudaGradScaler\n\n    def amp_autocast(enabled=True):\n        return _cuda_autocast(enabled=enabled)\n\n    def make_grad_scaler(enabled=True):\n        return _CudaGradScaler(enabled=enabled)\n\n\ndef resolve_competition_path(local_path, competition_slug):\n    \"\"\"Use the local Kaggle mount if present, otherwise fetch via kagglehub.\"\"\"\n    if os.path.exists(local_path):\n        return local_path\n    if kagglehub is not None:\n        return os.path.join(kagglehub.competition_download(competition_slug),\n                            \"t15_copyTask_neuralData/hdf5_data_final\")\n    raise FileNotFoundError(f\"{local_path} not found and kagglehub unavailable.\")\n\n\n# 40-way phoneme inventory (index 0 = CTC blank, last entry = word boundary).\n# These IDs are exactly what's stored in each trial's `seq_class_ids`.\nPHONEME_VOCAB = [\n    'BLANK', 'AA', 'AE', 'AH', 'AO', 'AW', 'AY', 'B', 'CH', 'D', 'DH',\n    'EH', 'ER', 'EY', 'F', 'G', 'HH', 'IH', 'IY', 'JH', 'K', 'L', 'M', 'N',\n    'NG', 'OW', 'OY', 'P', 'R', 'S', 'SH', 'T', 'TH', 'UH', 'UW', 'V', 'W',\n    'Y', 'Z', 'ZH', ' | ',\n]\n\nCONFIG = {\n    'data_dir': resolve_competition_path(\n        '/kaggle/input/competitions/brain-to-text-25/t15_copyTask_neuralData/hdf5_data_final',\n        'brain-to-text-25',\n    ),\n    'device': 'cuda' if torch.cuda.is_available() else 'cpu',\n    'batch_size': 16,\n    'num_epochs': 82,\n\n    # --- Model architecture (BEST) ---\n    'd_model': 384,\n    'n_heads': 6,\n    'n_layers': 4,\n    'd_ff': 1536,\n    'patch_size': 3,\n    'lstm_hidden': 256,\n    'lstm_layers': 2,\n    'n_classes': len(PHONEME_VOCAB),   # 40\n\n    # --- Regularization & adaptation (BEST) ---\n    'dropout': 0.4,\n    'head_dim': 256,\n    'attn_dropout': 0.5,\n    'drop_path_rate': 0.2,\n    'smooth_kernel_std': 2.0,\n    'smooth_kernel_size': 100,\n    'drift_lambda': 0.01,\n\n    # --- Optimizer (BEST) ---\n    'learning_rate': 5e-4,\n    'weight_decay': 1e-4,\n    'use_augmentation': True,\n\n    # --- Memory / stability ---\n    'use_amp': True,\n    'grad_clip': 5.0,\n\n    # --- Checkpointing ---\n    'resume_from_checkpoint': None,\n    'checkpoint_dir': '/kaggle/working',\n\n    # --- LLM rescoring gate (BEST) ---\n    'llm_gate_percentile': 1,          # skip only the most clearly incoherent trials\n    'llm_gate_margin_percentile': 75,  # let the LLM rescore more \"confident\" cases too\n    'llm_fusion_weight': 0.75,          # BEST fusion lambda (pinned)\n}\n\n# --- Skip switches ----------------------------------------------------------\n# Training is DEFINED below but not RUN. Set False to train from scratch.\nSKIP_TRAINING = True\nPRETRAINED_CKPT_DATASET = 'shohan3125/brain-to-text-checkpoint'\n\n# The per-run lm_weight/lambda grid search (BLOCK 5.6) is controlled by this\n# single flag - set it here, nowhere else. True = actually run the sweep;\n# False = skip BLOCK 5.6 and use the pinned defaults above.\nRUN_HYPERPARAM_SWEEPS = True\n\nos.makedirs(CONFIG['checkpoint_dir'], exist_ok=True)\nfigures_dir = os.path.join(CONFIG['checkpoint_dir'], 'figures')\nos.makedirs(figures_dir, exist_ok=True)\n\nprint(f\"Device: {CONFIG['device']}\")\nprint(f\"PyTorch version: {torch.__version__}\")\nprint(f\"SKIP_TRAINING: {SKIP_TRAINING} | RUN_HYPERPARAM_SWEEPS: {RUN_HYPERPARAM_SWEEPS}\")\nprint(f\"Phoneme classes (incl. blank): {CONFIG['n_classes']}\")\n\n\n# --- Helper: Stochastic Depth ----------------------------------------------\ndef drop_path(x, drop_prob: float = 0., training: bool = False, scale_by_keep: bool = True):\n    if drop_prob == 0. or not training:\n        return x\n    keep_prob = 1 - drop_prob\n    shape = (x.shape[0],) + (1,) * (x.ndim - 1)\n    random_tensor = x.new_empty(shape).bernoulli_(keep_prob)\n    if keep_prob > 0.0 and scale_by_keep:\n        random_tensor.div_(keep_prob)\n    return x * random_tensor\n\n\n# --- Helper: Global Session Mapper -----------------------------------------\ndef get_session2idx(data_dir):\n    \"\"\"Scans data directory to find all unique sessions chronologically.\"\"\"\n    paths = glob(f'{data_dir}/**/data_*.hdf5', recursive=True)\n    sessions = sorted(list(set([Path(p).parent.name for p in paths])))\n    return {s: i for i, s in enumerate(sessions)}\n\n\n# --- Helper: Kaggle dataset resolver ---------------------------------------\ndef resolve_kaggle_dataset(slug, local_dirname=None):\n    \"\"\"Prefer an already-attached dataset under /kaggle/input, fall back to\n    kagglehub.dataset_download() only if nothing is found locally.\"\"\"\n    if local_dirname is None:\n        local_dirname = slug.split('/')[-1]\n    owner = slug.split('/')[0] if '/' in slug else None\n\n    candidates = [f'/kaggle/input/{local_dirname}']\n    if owner:\n        candidates.append(f'/kaggle/input/datasets/{owner}/{local_dirname}')\n\n    if os.path.isdir('/kaggle/input'):\n        for root, dirs, _ in os.walk('/kaggle/input'):\n            for d in dirs:\n                if local_dirname.lower() in d.lower() or d.lower() in local_dirname.lower():\n                    candidates.append(os.path.join(root, d))\n\n    for path in candidates:\n        if os.path.exists(path):\n            return path\n    try:\n        import kagglehub as _kh\n        return _kh.dataset_download(slug)\n    except Exception as e:\n        raise FileNotFoundError(\n            f\"Could not find dataset '{slug}' under /kaggle/input (tried {candidates}) \"\n            f\"and kagglehub.dataset_download() also failed: {e}\\n\"\n            f\"Fix: attach it via '+ Add Input' in the notebook editor, then re-run.\"\n        ) from e\n\n\ndef find_file(root_dir, filename_pattern):\n    \"\"\"Recursively find a file under root_dir matching filename_pattern.\"\"\"\n    matches = sorted(glob(os.path.join(root_dir, '**', filename_pattern), recursive=True))\n    if not matches:\n        raise FileNotFoundError(f\"No file matching '{filename_pattern}' found under {root_dir}\")\n    return matches[0]","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:02.101071Z","iopub.status.busy":"2026-08-30T07:12:02.100532Z","iopub.status.idle":"2026-08-30T07:12:10.181448Z","shell.execute_reply":"2026-08-30T07:12:10.180539Z"},"papermill":{"duration":8.110847,"end_time":"2026-08-30T07:12:10.183264+00:00","exception":false,"start_time":"2026-08-30T07:12:02.072417+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0417fb8e","cell_type":"markdown","source":"# BLOCK 2 · DATA AUGMENTATION, LOADING & DATASET  (phoneme targets + global norm)\n","metadata":{"papermill":{"duration":0.021391,"end_time":"2026-08-30T07:12:10.226158+00:00","exception":false,"start_time":"2026-08-30T07:12:10.204767+00:00","status":"completed"},"tags":[]}},{"id":"0c65328c","cell_type":"code","source":"# ============================================================================\n# BLOCK 2 · DATA AUGMENTATION, LOADING & DATASET  (phoneme targets + global norm)\n# ============================================================================\nclass NeuralAugmentation:\n    def __init__(self, p=0.5):\n        self.p = p\n\n    def __call__(self, neural):\n        if random.random() > self.p:\n            return neural\n        if random.random() < 0.3:\n            neural = self.time_warp(neural)\n        if random.random() < 0.3:\n            noise_level = random.uniform(0.01, 0.05)\n            neural = neural + torch.randn_like(neural) * noise_level\n        if random.random() < 0.2:\n            n_channels = neural.shape[1]\n            n_drop = int(n_channels * 0.1)\n            drop_indices = random.sample(range(n_channels), n_drop)\n            neural[:, drop_indices] = 0\n        return neural\n\n    def time_warp(self, neural):\n        seq_len = len(neural)\n        warp_factor = random.uniform(0.9, 1.1)\n        new_len = int(seq_len * warp_factor)\n        if new_len < 10:\n            return neural\n        indices = torch.linspace(0, seq_len - 1, new_len)\n        indices_floor = indices.long()\n        indices_ceil = torch.clamp(indices_floor + 1, max=seq_len - 1)\n        alpha = (indices - indices_floor.float()).unsqueeze(1)\n        warped = (1 - alpha) * neural[indices_floor] + alpha * neural[indices_ceil]\n        final_indices = torch.linspace(0, new_len - 1, seq_len).long()\n        return warped[final_indices]\n\n\ndef load_split(data_dir, split='train'):\n    pattern = f'{data_dir}/**/data_{split}.hdf5'\n    files = sorted(glob(pattern, recursive=True))\n\n    print(f\"\\nLoading {split} split...\")\n    all_data = {k: [] for k in ['neural', 'n_steps', 'sentence', 'phonemes',\n                                 'phoneme_len', 'session', 'block', 'trial']}\n    for filepath in tqdm(files):\n        session_name = Path(filepath).parent.name\n        with h5py.File(filepath, 'r') as f:\n            for trial_key in f.keys():\n                trial = f[trial_key]\n                all_data['neural'].append(trial['input_features'][:])\n                all_data['n_steps'].append(trial.attrs['n_time_steps'])\n                all_data['session'].append(session_name)\n                all_data['block'].append(trial.attrs['block_num'])\n                all_data['trial'].append(trial.attrs['trial_num'])\n\n                sentence = trial.attrs.get('sentence_label')\n                all_data['sentence'].append(\n                    sentence.decode('utf-8') if isinstance(sentence, bytes) else sentence)\n\n                phon = trial['seq_class_ids'][:] if 'seq_class_ids' in trial else np.array([], dtype=np.int64)\n                phon_len = int(trial.attrs['seq_len']) if 'seq_len' in trial.attrs else len(phon)\n                all_data['phonemes'].append(phon)\n                all_data['phoneme_len'].append(phon_len)\n    print(f\"Loaded {len(all_data['neural'])} samples\")\n    return all_data\n\n\ndef compute_channel_stats(data):\n    \"\"\"Streaming (Welford) per-channel mean/std over every TRAIN timestep,\n    computed once and reused unchanged for val/test.\"\"\"\n    n_channels = data['neural'][0].shape[1]\n    count = 0\n    mean = np.zeros(n_channels, dtype=np.float64)\n    M2 = np.zeros(n_channels, dtype=np.float64)\n    for feat, n_steps in zip(data['neural'], data['n_steps']):\n        x = feat[:n_steps].astype(np.float64)\n        for row in x:\n            count += 1\n            delta = row - mean\n            mean += delta / count\n            M2 += delta * (row - mean)\n    std = np.sqrt(M2 / max(count - 1, 1))\n    std[std < 1e-6] = 1e-6\n    return torch.tensor(mean, dtype=torch.float32), torch.tensor(std, dtype=torch.float32)\n\n\nclass BrainToTextDataset(Dataset):\n    def __init__(self, data, session2idx, feat_mean, feat_std, augment=False, clip=5.0):\n        self.neural = data['neural']\n        self.n_steps = data['n_steps']\n        self.sentences = data['sentence']\n        self.sessions = data['session']\n        self.phonemes = data['phonemes']\n        self.phoneme_len = data['phoneme_len']\n        self.session2idx = session2idx\n        self.feat_mean = feat_mean\n        self.feat_std = feat_std\n        self.clip = clip\n        self.augment = augment\n        self.augmentation = NeuralAugmentation(p=0.5) if augment else None\n\n    def __len__(self):\n        return len(self.neural)\n\n    def __getitem__(self, idx):\n        neural = self.neural[idx][:self.n_steps[idx]]\n        neural = torch.FloatTensor(neural)\n\n        # Global, split-independent normalization.\n        neural = (neural - self.feat_mean) / self.feat_std\n        neural = torch.clamp(neural, -self.clip, self.clip)\n\n        if self.augment and self.augmentation:\n            neural = self.augmentation(neural)\n\n        target = torch.LongTensor(self.phonemes[idx])\n        target_length = self.phoneme_len[idx]\n\n        return {\n            'neural': neural,\n            'target': target,\n            'length': len(neural),\n            'target_length': target_length,\n            'sentence': self.sentences[idx] if self.sentences[idx] else \"\",\n            'day_idx': self.session2idx[self.sessions[idx]],\n        }\n\n\ndef collate_fn(batch):\n    batch = sorted(batch, key=lambda x: x['length'], reverse=True)\n    neurals = pad_sequence([item['neural'] for item in batch], batch_first=True)\n    targets = pad_sequence([item['target'] for item in batch], batch_first=True)\n    return {\n        'neural': neurals,\n        'target': targets,\n        'lengths': torch.LongTensor([item['length'] for item in batch]),\n        'target_lengths': torch.LongTensor([item['target_length'] for item in batch]),\n        'sentences': [item['sentence'] for item in batch],\n        'day_idx': torch.LongTensor([item['day_idx'] for item in batch]),\n    }","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:10.271118Z","iopub.status.busy":"2026-08-30T07:12:10.270596Z","iopub.status.idle":"2026-08-30T07:12:10.290062Z","shell.execute_reply":"2026-08-30T07:12:10.289446Z"},"papermill":{"duration":0.043994,"end_time":"2026-08-30T07:12:10.291531+00:00","exception":false,"start_time":"2026-08-30T07:12:10.247537+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ea3252f6","cell_type":"markdown","source":"# BLOCK 3 · HYBRID MODEL  (CNN -> BiLSTM -> patch-Transformer, day-adaptive input)\n","metadata":{"papermill":{"duration":0.022441,"end_time":"2026-08-30T07:12:10.335226+00:00","exception":false,"start_time":"2026-08-30T07:12:10.312785+00:00","status":"completed"},"tags":[]}},{"id":"6c513bc8","cell_type":"code","source":"# ============================================================================\n# BLOCK 3 · HYBRID MODEL  (CNN -> BiLSTM -> patch-Transformer, day-adaptive input)\n# ============================================================================\nclass RoPE(nn.Module):\n    def __init__(self, head_dim, max_seq_len=2048):\n        super().__init__()\n        half_dim = head_dim // 2\n        freq = 1.0 / (10000 ** (torch.arange(0, half_dim, 2).float() / half_dim))\n        t = torch.arange(max_seq_len).float().unsqueeze(1)\n        angles = t * freq.unsqueeze(0)\n        cos = torch.cos(angles).repeat_interleave(2, dim=1)\n        sin = torch.sin(angles).repeat_interleave(2, dim=1)\n        self.register_buffer(\"cos\", cos.unsqueeze(0))\n        self.register_buffer(\"sin\", sin.unsqueeze(0))\n\n    def forward(self, x, seq_len):\n        cos = self.cos[:, :seq_len, :].to(x.device)\n        sin = self.sin[:, :seq_len, :].to(x.device)\n        x1, x2 = x.chunk(2, -1)\n        return torch.cat([x1 * cos - x2 * sin, x1 * sin + x2 * cos], -1)\n\n\nclass WideAttention(nn.Module):\n    def __init__(self, d_model, n_heads, head_dim, dropout):\n        super().__init__()\n        self.n_heads = n_heads\n        self.head_dim = head_dim\n        self.inner_dim = n_heads * head_dim\n        self.scale = head_dim ** -0.5\n\n        self.qkv = nn.Linear(d_model, self.inner_dim * 3, bias=False)\n        self.out = nn.Linear(self.inner_dim, d_model)\n        self.dropout = nn.Dropout(dropout)\n        self.rope = RoPE(head_dim)\n\n    def forward(self, x, mask=None):\n        B, T, C = x.shape\n        qkv = self.qkv(x).reshape(B, T, 3, self.n_heads, self.head_dim).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]\n\n        q = self.rope(q, T)\n        k = self.rope(k, T)\n\n        attn = (q @ k.transpose(-2, -1)) * self.scale\n        if mask is not None:\n            attn = attn.masked_fill(mask == 0, float('-inf'))\n\n        attn = self.dropout(F.softmax(attn, -1))\n        out = (attn @ v).transpose(1, 2).reshape(B, T, -1)\n        return self.out(out)\n\n\nclass TransformerBlock(nn.Module):\n    def __init__(self, d_model, n_heads, d_ff, dropout, head_dim, attn_dropout):\n        super().__init__()\n        self.norm1 = nn.LayerNorm(d_model)\n        self.attn = WideAttention(d_model, n_heads, head_dim, attn_dropout)\n        self.norm2 = nn.LayerNorm(d_model)\n        self.ffn = nn.Sequential(\n            nn.Linear(d_model, d_ff),\n            nn.GELU(),\n            nn.Dropout(dropout),\n            nn.Linear(d_ff, d_model),\n            nn.Dropout(dropout),\n        )\n\n    def forward(self, x, mask=None, drop_path_rate=0.0):\n        x = x + drop_path(self.attn(self.norm1(x), mask), drop_path_rate, self.training)\n        x = x + drop_path(self.ffn(self.norm2(x)), drop_path_rate, self.training)\n        return x\n\n\nclass HybridLSTMTransformerCTC(nn.Module):\n    def __init__(self, n_days, input_size=512, d_model=384, n_heads=6, n_layers=4,\n                 d_ff=1536, patch_size=3, vocab_size=50, dropout=0.4, head_dim=256,\n                 attn_dropout=0.5, lstm_hidden=256, lstm_layers=2, smooth_std=2.0,\n                 smooth_size=100, drop_path_rate=0.2):\n        super().__init__()\n        self.patch_size = patch_size\n        self.n_days = n_days\n\n        # Gaussian smoothing kernel (fixed).\n        inp = np.zeros(smooth_size, dtype=np.float32)\n        inp[smooth_size // 2] = 1\n        gaussKernel = gaussian_filter1d(inp, smooth_std)\n        valid_idx = np.argwhere(gaussKernel > 0.01)\n        gaussKernel = gaussKernel[valid_idx]\n        gaussKernel = np.squeeze(gaussKernel / np.sum(gaussKernel))\n        self.register_buffer(\"gauss_kernel\", torch.tensor(gaussKernel, dtype=torch.float32).view(1, 1, -1))\n\n        # Day-specific linear transform.\n        self.day_weights = nn.ParameterList([nn.Parameter(torch.eye(input_size)) for _ in range(n_days)])\n        self.day_biases = nn.ParameterList([nn.Parameter(torch.zeros(1, input_size)) for _ in range(n_days)])\n        self.day_activation = nn.Softsign()\n\n        self.cnn = nn.Sequential(\n            nn.Conv1d(input_size, 256, kernel_size=3, padding=1),\n            nn.BatchNorm1d(256), nn.ReLU(), nn.Dropout(dropout * 0.5),\n            nn.Conv1d(256, 256, kernel_size=3, padding=1),\n            nn.BatchNorm1d(256), nn.ReLU(), nn.Dropout(dropout * 0.5),\n        )\n\n        self.lstm = nn.LSTM(\n            256, lstm_hidden, lstm_layers, batch_first=True, bidirectional=True,\n            dropout=dropout if lstm_layers > 1 else 0,\n        )\n\n        lstm_output_dim = lstm_hidden * 2\n        self.patch_embed = nn.Sequential(\n            nn.LayerNorm(lstm_output_dim * patch_size),\n            nn.Linear(lstm_output_dim * patch_size, d_model),\n            nn.LayerNorm(d_model), nn.Dropout(dropout),\n        )\n\n        self.blocks = nn.ModuleList([\n            TransformerBlock(d_model, n_heads, d_ff, dropout, head_dim, attn_dropout)\n            for _ in range(n_layers)\n        ])\n\n        self.drop_path_rates = [x.item() for x in torch.linspace(0, drop_path_rate, n_layers)]\n\n        self.norm = nn.LayerNorm(d_model)\n        self.head = nn.Linear(d_model, vocab_size)\n\n    def forward(self, x, lengths, day_idx):\n        B, T, C = x.shape\n\n        # 1. Day-specific weighting.\n        W = torch.stack([self.day_weights[i] for i in day_idx], dim=0)\n        b = torch.cat([self.day_biases[i] for i in day_idx], dim=0).unsqueeze(1)\n        x = torch.einsum(\"btd,bdk->btk\", x, W) + b\n        x = self.day_activation(x)\n\n        # 2. Gaussian smoothing via grouped Conv1D.\n        x = x.permute(0, 2, 1)  # [B, C, T]\n        kernel = self.gauss_kernel.repeat(C, 1, 1).to(x.device)\n        x = F.conv1d(x, kernel, padding='same', groups=C)\n\n        # 3. CNN.\n        x = self.cnn(x)\n        x = x.permute(0, 2, 1)  # [B, T, C]\n\n        # 4. LSTM.\n        x_packed = pack_padded_sequence(x, lengths.cpu(), batch_first=True, enforce_sorted=True)\n        lstm_out, _ = self.lstm(x_packed)\n        lstm_out, _ = pad_packed_sequence(lstm_out, batch_first=True)\n\n        # 5. Patching.\n        T_lstm = lstm_out.shape[1]\n        n_patches = T_lstm // self.patch_size\n\n        if n_patches == 0:\n            n_patches = 1\n            x = lstm_out.mean(dim=1, keepdim=True)\n            x = self.patch_embed(x.reshape(B, 1, -1))\n            patch_lens = torch.ones(B, dtype=torch.long, device=x.device)\n        else:\n            x = lstm_out[:, :n_patches * self.patch_size].reshape(B, n_patches, -1)\n            x = self.patch_embed(x)\n            patch_lens = torch.clamp((lengths // self.patch_size).to(x.device), min=1)\n\n        # 6. Transformer.\n        mask = (torch.arange(n_patches, device=x.device)[None, :] < patch_lens[:, None])\n        mask = mask[:, None, None, :]\n\n        for i, block in enumerate(self.blocks):\n            x = block(x, mask, drop_path_rate=self.drop_path_rates[i])\n\n        # 7. Output projection.\n        logits = self.head(self.norm(x))\n        log_probs = torch.log_softmax(logits, dim=-1)\n\n        return log_probs.transpose(0, 1), patch_lens","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:10.380448Z","iopub.status.busy":"2026-08-30T07:12:10.380121Z","iopub.status.idle":"2026-08-30T07:12:10.404897Z","shell.execute_reply":"2026-08-30T07:12:10.40426Z"},"papermill":{"duration":0.049535,"end_time":"2026-08-30T07:12:10.406304+00:00","exception":false,"start_time":"2026-08-30T07:12:10.356769+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"d3c7c45e","cell_type":"markdown","source":"# BLOCK 4 · TRAINING & VALIDATION FUNCTIONS  (defined; RUN ONLY IF NOT SKIPPING)\n","metadata":{"papermill":{"duration":0.022417,"end_time":"2026-08-30T07:12:10.450146+00:00","exception":false,"start_time":"2026-08-30T07:12:10.427729+00:00","status":"completed"},"tags":[]}},{"id":"ead69173","cell_type":"code","source":"# ============================================================================\n# BLOCK 4 · TRAINING & VALIDATION FUNCTIONS  (defined; RUN ONLY IF NOT SKIPPING)\n# ============================================================================\nimport matplotlib.pyplot as plt\n\n\ndef greedy_decode_phonemes(log_probs, output_lengths):\n    \"\"\"CTC greedy decode -> list of phoneme-id sequences (blanks/dupes collapsed).\"\"\"\n    _, max_indices = log_probs.max(dim=-1)  # [T, B]\n    decoded = []\n    for b in range(max_indices.size(1)):\n        seq = max_indices[:output_lengths[b], b].cpu().numpy()\n        out, prev = [], None\n        for token in seq:\n            if token != 0 and token != prev:\n                out.append(int(token))\n            prev = token\n        decoded.append(out)\n    return decoded\n\n\ndef phoneme_ids_to_str(phoneme_ids):\n    \"\"\"Phoneme ids -> whitespace-joined phoneme symbols, e.g. [7,11,32]->'B EH T'.\"\"\"\n    return ' '.join(PHONEME_VOCAB[p] for p in phoneme_ids)\n\n\ndef build_lexicon_reverse(lexicon_path):\n    \"\"\"Parse lexicon.txt into a phoneme-tuple -> word map (first occurrence wins).\"\"\"\n    reverse = {}\n    with open(lexicon_path, 'r') as f:\n        for line in f:\n            line = line.strip()\n            if not line:\n                continue\n            parts = line.split('\\t')\n            if len(parts) == 2:\n                word, phon_str = parts[0], parts[1]\n                phonemes = [p for p in phon_str.rstrip(' |').split(' ') if p]\n            else:\n                parts = line.split()\n                if len(parts) < 2:\n                    continue\n                word, phonemes = parts[0], parts[1:]\n            key = tuple(phonemes)\n            if key not in reverse:\n                reverse[key] = word\n    return reverse\n\n\ndef phoneme_ids_to_words(phoneme_ids, lexicon_reverse):\n    \"\"\"Fast LM-free phoneme->word decode (train-time WER only).\"\"\"\n    sil_id = len(PHONEME_VOCAB) - 1\n    words, current = [], []\n    for pid in phoneme_ids:\n        if pid == sil_id:\n            if current:\n                key = tuple(PHONEME_VOCAB[p] for p in current)\n                words.append(lexicon_reverse.get(key, '<unk>'))\n                current = []\n        else:\n            current.append(pid)\n    if current:\n        key = tuple(PHONEME_VOCAB[p] for p in current)\n        words.append(lexicon_reverse.get(key, '<unk>'))\n    return ' '.join(words)\n\n\ndef validate_model(model, val_loader, device, lexicon_reverse):\n    \"\"\"Compute WER (phoneme->word via lexicon) and PER (raw CTC ids) per epoch.\"\"\"\n    model.eval()\n    total_word_edits, total_words = 0, 0\n    total_phon_edits, total_phons = 0, 0\n    with torch.no_grad():\n        for batch in val_loader:\n            neural = batch['neural'].to(device)\n            lengths = batch['lengths']\n            day_idx = batch['day_idx'].to(device)\n            sentences = batch['sentences']\n            targets = batch['target']\n            target_lengths = batch['target_lengths']\n\n            log_probs, output_lengths = model(neural, lengths, day_idx)\n            decoded_phonemes = greedy_decode_phonemes(log_probs, output_lengths)\n\n            for b, phon_ids in enumerate(decoded_phonemes):\n                ref_phon_ids = targets[b, :target_lengths[b]].tolist()\n                if len(ref_phon_ids) > 0:\n                    total_phon_edits += editdistance.eval(phon_ids, ref_phon_ids)\n                    total_phons += len(ref_phon_ids)\n\n                ref = sentences[b]\n                if not ref or not ref.strip():\n                    continue\n                hyp = phoneme_ids_to_words(phon_ids, lexicon_reverse)\n                ref_words, hyp_words = ref.split(), hyp.split()\n                total_word_edits += editdistance.eval(hyp_words, ref_words)\n                total_words += max(len(ref_words), 1)\n\n    wer = 100.0 * total_word_edits / max(total_words, 1)\n    per = 100.0 * total_phon_edits / max(total_phons, 1)\n    return wer, per\n\n\ndef average_state_dicts(state_dicts):\n    \"\"\"SWA-style weight averaging across checkpoints.\"\"\"\n    avg = {k: torch.zeros_like(v, dtype=torch.float32) for k, v in state_dicts[0].items()}\n    for sd in state_dicts:\n        for k, v in sd.items():\n            avg[k] += v.float()\n    for k in avg:\n        avg[k] /= len(state_dicts)\n    return avg\n\n\ndef train_model(train_loader, val_loader, config, n_days, lexicon_reverse):\n    model = HybridLSTMTransformerCTC(\n        n_days=n_days,\n        input_size=512, d_model=config['d_model'], n_heads=config['n_heads'],\n        n_layers=config['n_layers'], d_ff=config['d_ff'], patch_size=config['patch_size'],\n        vocab_size=config['n_classes'], dropout=config['dropout'], head_dim=config['head_dim'],\n        attn_dropout=config['attn_dropout'], lstm_hidden=config['lstm_hidden'],\n        lstm_layers=config['lstm_layers'], smooth_std=config['smooth_kernel_std'],\n        smooth_size=config['smooth_kernel_size'], drop_path_rate=config['drop_path_rate'],\n    ).to(config['device'])\n\n    criterion = nn.CTCLoss(blank=0, zero_infinity=True)\n    optimizer = optim.AdamW(model.parameters(), lr=config['learning_rate'],\n                            weight_decay=config['weight_decay'])\n    scaler = make_grad_scaler(enabled=config['use_amp'])\n\n    start_epoch = 0\n    if config.get('resume_from_checkpoint'):\n        print(f\"Resuming from {config['resume_from_checkpoint']}...\")\n        checkpoint = torch.load(config['resume_from_checkpoint'], map_location=config['device'])\n        model.load_state_dict(checkpoint['model_state_dict'])\n        optimizer.load_state_dict(checkpoint['optimizer_state_dict'])\n        start_epoch = checkpoint.get('epoch', -1) + 1\n        print(f\"Resumed at epoch {start_epoch}.\")\n\n    scheduler = optim.lr_scheduler.OneCycleLR(\n        optimizer, max_lr=config['learning_rate'], epochs=config['num_epochs'],\n        steps_per_epoch=len(train_loader), pct_start=0.1,\n        last_epoch=(start_epoch * len(train_loader) - 1) if start_epoch else -1,\n    )\n\n    epoch_losses, epoch_wers, epoch_pers = [], [], []\n    best_wer = float('inf')\n    patience, no_improve = 10, 0\n    top_checkpoints = []  # (wer, state_dict) for end-of-training SWA\n\n    for epoch in range(start_epoch, config['num_epochs']):\n        model.train()\n        train_loss = 0\n\n        for batch in tqdm(train_loader, desc=f'Epoch {epoch + 1}/{config[\"num_epochs\"]}'):\n            neural = batch['neural'].to(config['device'])\n            target = batch['target'].to(config['device'])\n            lengths = batch['lengths']\n            target_lengths = batch['target_lengths']\n            day_idx = batch['day_idx'].to(config['device'])\n\n            optimizer.zero_grad()\n            with amp_autocast(enabled=config['use_amp']):\n                log_probs, output_lengths = model(neural, lengths, day_idx)\n                ctc_loss = criterion(log_probs.float(), target, output_lengths, target_lengths)\n\n                drift_loss = 0.0\n                if config['drift_lambda'] > 0 and n_days > 1:\n                    for d in range(1, n_days):\n                        w_diff = model.day_weights[d] - model.day_weights[d - 1]\n                        b_diff = model.day_biases[d] - model.day_biases[d - 1]\n                        drift_loss += (torch.sum(w_diff ** 2) + torch.sum(b_diff ** 2))\n                    drift_loss = drift_loss / (n_days - 1)\n\n                loss = ctc_loss + (config['drift_lambda'] * drift_loss)\n\n            scaler.scale(loss).backward()\n            scaler.unscale_(optimizer)\n            torch.nn.utils.clip_grad_norm_(model.parameters(), config['grad_clip'])\n            scaler.step(optimizer)\n            scaler.update()\n            scheduler.step()\n            train_loss += loss.item()\n\n        avg_loss = train_loss / len(train_loader)\n        epoch_losses.append(avg_loss)\n        val_wer, val_per = validate_model(model, val_loader, config['device'], lexicon_reverse)\n        epoch_wers.append(val_wer)\n        epoch_pers.append(val_per)\n\n        print(f\"Epoch {epoch + 1}: Loss={avg_loss:.4f}, WER={val_wer:.2f}%, PER={val_per:.2f}%\")\n\n        ckpt = {\n            'model_state_dict': model.state_dict(),\n            'optimizer_state_dict': optimizer.state_dict(),\n            'epoch': epoch,\n            'config': config,\n        }\n        torch.save(ckpt, os.path.join(config['checkpoint_dir'], 'latest_model.pt'))\n\n        if val_wer < best_wer:\n            best_wer = val_wer\n            no_improve = 0\n            torch.save({**ckpt, 'wer': best_wer, 'per': val_per},\n                       os.path.join(config['checkpoint_dir'], 'best_model.pt'))\n        else:\n            no_improve += 1\n\n        top_checkpoints.append((val_wer, {k: v.cpu().clone() for k, v in model.state_dict().items()}))\n        top_checkpoints = sorted(top_checkpoints, key=lambda x: x[0])[:3]\n\n        if no_improve >= patience:\n            print(f\"\\nEarly stopping after {epoch + 1} epochs\")\n            break\n\n    if len(top_checkpoints) > 1:\n        swa_state = average_state_dicts([sd for _, sd in top_checkpoints])\n        torch.save({'model_state_dict': swa_state, 'config': config},\n                   os.path.join(config['checkpoint_dir'], 'swa_model.pt'))\n        print(f\"Saved SWA average of top {len(top_checkpoints)} checkpoints -> swa_model.pt\")\n\n    with open(os.path.join(config['checkpoint_dir'], 'training_history.json'), 'w') as f:\n        json.dump({'loss': epoch_losses, 'wer': epoch_wers, 'per': epoch_pers}, f, indent=2)\n\n    epochs_range = range(1, len(epoch_losses) + 1)\n    for series, ylabel, title, color, fname in [\n        (epoch_losses, 'CTC Loss', 'Training Loss over Epochs', 'tab:blue', 'training_loss.png'),\n        (epoch_wers, 'Word Error Rate (%)', 'Validation WER over Epochs', 'tab:red', 'training_wer.png'),\n        (epoch_pers, 'Phoneme Error Rate (%)', 'Validation PER over Epochs', 'tab:green', 'training_per.png'),\n    ]:\n        fig, ax = plt.subplots(figsize=(8, 5))\n        ax.plot(epochs_range, series, color=color, marker='o', markersize=3)\n        ax.set_xlabel('Epoch'); ax.set_ylabel(ylabel); ax.set_title(title)\n        ax.grid(True, alpha=0.3)\n        fig.tight_layout()\n        fig.savefig(os.path.join(figures_dir, fname), dpi=300, bbox_inches='tight')\n        plt.close(fig)\n\n    return model, best_wer, epoch_losses, epoch_wers, epoch_pers\n\n\n# ---- Training driver (SKIPPED by default) ----------------------------------\nif SKIP_TRAINING:\n    print(\"SKIP_TRAINING=True -> not loading the train split or running epochs. \"\n          \"Jump to Block 5 (reload checkpoint + evaluate).\")\nelse:\n    print(\"Scanning sessions...\")\n    session2idx = get_session2idx(CONFIG['data_dir'])\n    n_days = len(session2idx)\n    print(f\"Found {n_days} recording sessions/days.\")\n\n    train_data = load_split(CONFIG['data_dir'], 'train')\n    val_data = load_split(CONFIG['data_dir'], 'val')\n\n    print(\"Computing global per-channel normalization stats from TRAIN only...\")\n    feat_mean, feat_std = compute_channel_stats(train_data)\n    torch.save({'mean': feat_mean, 'std': feat_std},\n               os.path.join(CONFIG['checkpoint_dir'], 'norm_stats.pt'))\n\n    train_dataset = BrainToTextDataset(train_data, session2idx, feat_mean, feat_std,\n                                       augment=CONFIG['use_augmentation'])\n    val_dataset = BrainToTextDataset(val_data, session2idx, feat_mean, feat_std, augment=False)\n\n    train_loader = DataLoader(train_dataset, batch_size=CONFIG['batch_size'], shuffle=True,\n                              collate_fn=collate_fn, num_workers=2, pin_memory=True)\n    val_loader = DataLoader(val_dataset, batch_size=CONFIG['batch_size'], shuffle=False,\n                            collate_fn=collate_fn, num_workers=2, pin_memory=True)\n\n    print(\"Loading phoneme lexicon for end-to-end WER...\")\n    lexicon_ds = resolve_kaggle_dataset('heyyousum/quality-english-dataset-for-ngram-model-v2')\n    lexicon_reverse = build_lexicon_reverse(os.path.join(lexicon_ds, 'lexicon.txt'))\n    print(f\"Lexicon reverse-map: {len(lexicon_reverse)} unique phoneme sequences.\")\n\n    model, best_wer, epoch_losses, epoch_wers, epoch_pers = train_model(\n        train_loader, val_loader, CONFIG, n_days, lexicon_reverse)\n    print(f\"Training finished. Best validation WER: {best_wer:.2f}%\")","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:10.49725Z","iopub.status.busy":"2026-08-30T07:12:10.496892Z","iopub.status.idle":"2026-08-30T07:12:10.532191Z","shell.execute_reply":"2026-08-30T07:12:10.531047Z"},"papermill":{"duration":0.060802,"end_time":"2026-08-30T07:12:10.533802+00:00","exception":false,"start_time":"2026-08-30T07:12:10.473+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2499bc79","cell_type":"markdown","source":"# BLOCK 5","metadata":{"papermill":{"duration":0.022845,"end_time":"2026-08-30T07:12:10.57913+00:00","exception":false,"start_time":"2026-08-30T07:12:10.556285+00:00","status":"completed"},"tags":[]}},{"id":"787793d7","cell_type":"markdown","source":"## BLOCK 5.1 · RELOAD BEST MODEL & BUILD VALIDATION SET\n","metadata":{"papermill":{"duration":0.02273,"end_time":"2026-08-30T07:12:10.625253+00:00","exception":false,"start_time":"2026-08-30T07:12:10.602523+00:00","status":"completed"},"tags":[]}},{"id":"4a66a530","cell_type":"code","source":"# ============================================================================\n# BLOCK 5.1 · RELOAD BEST MODEL & BUILD VALIDATION SET\n# ==========a==================================================================\nprint('\\nRebuilding session2idx / validation dataset / model...')\nsession2idx = get_session2idx(CONFIG['data_dir'])\nn_days = len(session2idx)\n\nckpt_search_dir = CONFIG['checkpoint_dir']\nif PRETRAINED_CKPT_DATASET:\n    ckpt_search_dir = resolve_kaggle_dataset(PRETRAINED_CKPT_DATASET)\n    print(f\"Checkpoint source: {ckpt_search_dir}\")\n\nnorm_stats = torch.load(find_file(ckpt_search_dir, 'norm_stats.pt'))\nfeat_mean, feat_std = norm_stats['mean'], norm_stats['std']\n\nval_data = load_split(CONFIG['data_dir'], 'val')\nval_dataset = BrainToTextDataset(val_data, session2idx, feat_mean, feat_std, augment=False)\nval_loader = DataLoader(val_dataset, batch_size=CONFIG['batch_size'], shuffle=False,\n                        collate_fn=collate_fn, num_workers=2)\n\n# Prefer the SWA-averaged checkpoint, else best_model.pt.\nCKPT_CANDIDATES = [\n    os.path.join(ckpt_search_dir, 'swa_model.pt'),\n    os.path.join(ckpt_search_dir, 'best_model.pt'),\n]\nCKPT_PATH = next((p for p in CKPT_CANDIDATES if os.path.exists(p)), None)\nassert CKPT_PATH is not None, (\n    f\"No checkpoint found under {ckpt_search_dir} (tried {CKPT_CANDIDATES}). \"\n    f\"Set PRETRAINED_CKPT_DATASET to its attached slug, or train with SKIP_TRAINING=False.\"\n)\nprint(f\"Loading checkpoint from: {CKPT_PATH}\")\ncheckpoint = torch.load(CKPT_PATH, map_location=CONFIG['device'])\n\nmodel = HybridLSTMTransformerCTC(\n    n_days=n_days, input_size=512, vocab_size=CONFIG['n_classes'],\n    d_model=CONFIG['d_model'], n_heads=CONFIG['n_heads'], n_layers=CONFIG['n_layers'],\n    d_ff=CONFIG['d_ff'], patch_size=CONFIG['patch_size'],\n    lstm_hidden=CONFIG['lstm_hidden'], lstm_layers=CONFIG['lstm_layers'],\n    dropout=CONFIG['dropout'], head_dim=CONFIG['head_dim'], attn_dropout=CONFIG['attn_dropout'],\n    smooth_std=CONFIG['smooth_kernel_std'], smooth_size=CONFIG['smooth_kernel_size'],\n    drop_path_rate=CONFIG['drop_path_rate'],\n).to(CONFIG['device'])\n\nmodel.load_state_dict(checkpoint['model_state_dict'])\nmodel.eval()\nprint(\"Model ready (validation set only).\")","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:10.672202Z","iopub.status.busy":"2026-08-30T07:12:10.671819Z","iopub.status.idle":"2026-08-30T07:12:38.883531Z","shell.execute_reply":"2026-08-30T07:12:38.882871Z"},"papermill":{"duration":28.237615,"end_time":"2026-08-30T07:12:38.886029+00:00","exception":false,"start_time":"2026-08-30T07:12:10.648414+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"cd0d3cd1","cell_type":"markdown","source":"## BLOCK 5.2 · ATTACH PHONEME LEXICON + N-GRAM LM\n","metadata":{"papermill":{"duration":0.025207,"end_time":"2026-08-30T07:12:38.937652+00:00","exception":false,"start_time":"2026-08-30T07:12:38.912445+00:00","status":"completed"},"tags":[]}},{"id":"c2297098","cell_type":"code","source":"# ============================================================================\n# BLOCK 5.2 · ATTACH PHONEME LEXICON + N-GRAM LM\n# ============================================================================\nlexicon_ds = resolve_kaggle_dataset('heyyousum/quality-english-dataset-for-ngram-model-v2')\nkenlm_ds = resolve_kaggle_dataset('heyyousum/custom-4-gram-wiki-news-switchboard-updated-v3')\n\nlexicon_path = find_file(lexicon_ds, 'lexicon.txt')\ntokens_path = find_file(lexicon_ds, 'tokens.txt')\nkenlm_binary_path = find_file(kenlm_ds, '*.bin')\n\nprint('Lexicon:', lexicon_path)\nprint('Tokens:', tokens_path)\nprint('KenLM binary:', kenlm_binary_path)\n\n# Safety check: tokens.txt order MUST match PHONEME_VOCAB or WER silently breaks.\nwith open(tokens_path) as f:\n    _file_tokens = [line.rstrip('\\n') for line in f]\nprint(f\"tokens.txt has {len(_file_tokens)} entries, PHONEME_VOCAB has {len(PHONEME_VOCAB)}\")\n_mismatches = 0\nfor i in range(max(len(_file_tokens), len(PHONEME_VOCAB))):\n    a = _file_tokens[i] if i < len(_file_tokens) else '<missing>'\n    b = PHONEME_VOCAB[i] if i < len(PHONEME_VOCAB) else '<missing>'\n    if a.strip() != b.strip():\n        _mismatches += 1\n        print(f\"  [{i:2d}] tokens.txt={a!r:12s}  PHONEME_VOCAB={b!r:12s}  <-- MISMATCH\")\nprint(\"OK: tokens.txt matches PHONEME_VOCAB.\" if _mismatches == 0\n      else f\"WARNING: {_mismatches} mismatch(es); fix before trusting WER.\")","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:38.989936Z","iopub.status.busy":"2026-08-30T07:12:38.989506Z","iopub.status.idle":"2026-08-30T07:12:39.05154Z","shell.execute_reply":"2026-08-30T07:12:39.050488Z"},"papermill":{"duration":0.088437,"end_time":"2026-08-30T07:12:39.053282+00:00","exception":false,"start_time":"2026-08-30T07:12:38.964845+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2852c301","cell_type":"markdown","source":"## BLOCK 5.3 · BUILD BEAM-SEARCH DECODER  (BEST: lm_weight = 4.5)\n","metadata":{"papermill":{"duration":0.023006,"end_time":"2026-08-30T07:12:39.100773+00:00","exception":false,"start_time":"2026-08-30T07:12:39.077767+00:00","status":"completed"},"tags":[]}},{"id":"f2a9226a","cell_type":"code","source":"# ============================================================================\n# BLOCK 5.3 · BUILD BEAM-SEARCH DECODER  (BEST: lm_weight = 4.5)\n# ============================================================================\ndef _ensure_flashlight():\n    try:\n        import flashlight.lib.text.decoder  # noqa: F401\n        return True\n    except Exception:\n        pass\n    print(\"flashlight not importable - installing flashlight-text ...\")\n    subprocess.run([sys.executable, \"-m\", \"pip\", \"install\", \"flashlight-text\"], check=False)\n    importlib.invalidate_caches()\n    try:\n        import flashlight.lib.text.decoder  # noqa: F401\n        return True\n    except Exception:\n        return False\n\n\nif not _ensure_flashlight():\n    raise RuntimeError(\n        \"flashlight-text could not be imported after install. On Kaggle this usually \"\n        \"means Internet is OFF for the notebook, or a stale import cache (Restart & Run All \"\n        \"after the install succeeds).\"\n    )\n\nfrom torchaudio.models.decoder import ctc_decoder\n\nBEAM_WIDTH = 250\nNBEST = 30\nLM_WEIGHT = 4.5   # BEST (pinned from the sweep; WER was still improving at the grid edge)\n\n\ndef build_decoder(lm_weight=LM_WEIGHT, beam_size=BEAM_WIDTH, nbest=NBEST):\n    return ctc_decoder(\n        lexicon=lexicon_path,\n        tokens=tokens_path,\n        lm=kenlm_binary_path,\n        nbest=nbest,\n        beam_size=beam_size,\n        lm_weight=lm_weight,\n        word_score=0.0,\n        blank_token='BLANK',\n        sil_token='|',\n    )\n\n\ndecoder = build_decoder()\nprint(f\"Decoder ready (beam_size={BEAM_WIDTH}, nbest={NBEST}, lm_weight={LM_WEIGHT}).\")\n\n# ============================================================================\n# LOAD 4-BIT QUANTIZED LLM  (Qwen2.5-7B; fluency rescoring by SCORE FUSION)\n# ============================================================================\nfrom transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig\n\nLLM_CANDIDATES = {\"qwen2.5-7b\": \"Qwen/Qwen2.5-7B\"}   # BEST / only benchmarked model\nLLM_KEY = \"qwen2.5-7b\"\nLLM_NAME = LLM_CANDIDATES[LLM_KEY]\n\nllm_model = None\ntokenizer = None\n\n\ndef load_llm(model_name):\n    \"\"\"(Re)load a 4-bit quantized causal LM for scoring; frees the previous one.\"\"\"\n    global llm_model, tokenizer\n    if llm_model is not None:\n        del llm_model\n        llm_model = None\n        gc.collect()\n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n    print(f\"Loading rescoring LLM ({model_name}) in 4-bit...\")\n    bnb_config = BitsAndBytesConfig(\n        load_in_4bit=True,\n        bnb_4bit_compute_dtype=torch.float16,\n        bnb_4bit_quant_type=\"nf4\",\n        bnb_4bit_use_double_quant=True,\n    )\n    tok = AutoTokenizer.from_pretrained(model_name)\n    if tok.pad_token is None:\n        tok.pad_token = tok.eos_token\n    mdl = AutoModelForCausalLM.from_pretrained(\n        model_name, quantization_config=bnb_config, device_map=\"auto\")\n    mdl.eval()\n    tokenizer = tok\n    llm_model = mdl\n    return mdl, tok\n\n\nllm_model, tokenizer = load_llm(LLM_NAME)\n\n\n# --- Verbatim-aware conditioning prefixes ----------------------------------\nVERBATIM_PREFIX = (\n    \"The following is a raw, word-for-word transcript of someone speaking out \"\n    \"loud. It is unedited and may contain repetitions, false starts, filler \"\n    \"words, or unusual phrasing exactly as spoken:\\n\"\n)\nVERBATIM_PREFIX_ALT = (\n    \"The following is an exact, unedited transcript of spontaneous, \"\n    \"possibly ungrammatical speech. Do not correct or normalize it:\\n\"\n)\n\n\ndef compute_llm_scores(sentences, batch_size=16, prefix=VERBATIM_PREFIX):\n    \"\"\"Length-normalized conditional log-likelihood P(candidate | prefix).\n    The prefix is fed but excluded from the score (its label positions masked).\"\"\"\n    prefix_ids = tokenizer(prefix, add_special_tokens=False)[\"input_ids\"] if prefix else []\n    n_prefix = len(prefix_ids)\n    pad_id = tokenizer.pad_token_id if tokenizer.pad_token_id is not None else tokenizer.eos_token_id\n\n    scores = []\n    for i in range(0, len(sentences), batch_size):\n        chunk = [s if s.strip() else \"<empty>\" for s in sentences[i:i + batch_size]]\n        seqs = []\n        for s in chunk:\n            cand_ids = tokenizer(s, add_special_tokens=False)[\"input_ids\"]\n            if len(cand_ids) == 0:\n                cand_ids = [tokenizer.eos_token_id]\n            seqs.append(prefix_ids + cand_ids)\n\n        maxlen = max(len(x) for x in seqs)\n        input_ids = torch.full((len(seqs), maxlen), pad_id, dtype=torch.long)\n        attn = torch.zeros((len(seqs), maxlen), dtype=torch.long)\n        score_mask = torch.zeros((len(seqs), maxlen), dtype=torch.float)\n        for r, ids in enumerate(seqs):\n            L = len(ids)\n            input_ids[r, :L] = torch.tensor(ids, dtype=torch.long)\n            attn[r, :L] = 1\n            score_mask[r, n_prefix:L] = 1.0\n\n        input_ids = input_ids.to(llm_model.device)\n        attn = attn.to(llm_model.device)\n        score_mask = score_mask.to(llm_model.device)\n\n        with torch.no_grad():\n            logits = llm_model(input_ids=input_ids, attention_mask=attn).logits\n\n        shift_logits = logits[:, :-1, :]\n        shift_labels = input_ids[:, 1:]\n        shift_smask = score_mask[:, 1:]\n        nll = F.cross_entropy(\n            shift_logits.reshape(-1, shift_logits.size(-1)),\n            shift_labels.reshape(-1),\n            reduction=\"none\",\n        ).view(shift_labels.shape)\n        token_counts = shift_smask.sum(dim=1).clamp(min=1)\n        per_seq_nll = (nll * shift_smask).sum(dim=1) / token_counts\n        scores.extend((-per_seq_nll).tolist())\n    return scores\n\n\nprint(\"LLM ready for rescoring (verbatim-conditioned scoring + score fusion).\")\n\n\n# --- Confidence gating + score-fusion machinery ----------------------------\nLLM_GATE_THRESHOLD = None\nLLM_GATE_MARGIN_THRESHOLD = None\nLLM_FUSION_WEIGHT = CONFIG['llm_fusion_weight']   # BEST base fusion lambda = 0.5\n\n# Kept for compatibility; unused when RUN_HYPERPARAM_SWEEPS is False.\nLAMBDA_GRID = [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5]\n\ndef normalized_ngram_score(hyp):\n    return hyp.score / max(len(hyp.words), 1)\n\n\ndef top1_margin(nbest_result):\n    if len(nbest_result) < 2:\n        return float('inf')\n    return normalized_ngram_score(nbest_result[0]) - normalized_ngram_score(nbest_result[1])\n\n\ndef _standardize(vals):\n    v = np.asarray(vals, dtype=np.float64)\n    sd = v.std()\n    if sd < 1e-8:\n        return np.zeros_like(v)\n    return (v - v.mean()) / sd\n\n\ndef fuse_pick(nbest_result, llm_scores, lam):\n    \"\"\"Index maximizing standardize(decoder) + lam * standardize(llm).\n    lam == 0 (or missing scores) reproduces the decoder top-1 exactly.\"\"\"\n    dec = [normalized_ngram_score(h) for h in nbest_result]\n    if lam == 0 or not llm_scores or len(llm_scores) != len(dec):\n        return int(np.argmax(dec))\n    combined = _standardize(dec) + lam * _standardize(llm_scores)\n    return int(np.argmax(combined))\n\n\ndef adaptive_lambda(nbest_result, base_lambda=None):\n    \"\"\"Per-utterance fusion weight, scaled down as decoder confidence grows.\"\"\"\n    base_lambda = LLM_FUSION_WEIGHT if base_lambda is None else base_lambda\n    if base_lambda == 0:\n        return 0.0\n    if LLM_GATE_MARGIN_THRESHOLD in (None, 0) or not np.isfinite(LLM_GATE_MARGIN_THRESHOLD):\n        return base_lambda\n    margin = top1_margin(nbest_result)\n    if not np.isfinite(margin):\n        return 0.0\n    scale = 1.0 - min(margin / LLM_GATE_MARGIN_THRESHOLD, 1.0)\n    return base_lambda * scale\n\n\ndef calibrate_llm_gate_threshold(decoder_results, percentile=None, margin_percentile=None):\n    \"\"\"Set both gate thresholds from this set's own score distribution.\"\"\"\n    global LLM_GATE_THRESHOLD, LLM_GATE_MARGIN_THRESHOLD\n    percentile = CONFIG['llm_gate_percentile'] if percentile is None else percentile\n    margin_percentile = CONFIG['llm_gate_margin_percentile'] if margin_percentile is None else margin_percentile\n\n    top1_scores = [normalized_ngram_score(r[0]) for r in decoder_results if r]\n    LLM_GATE_THRESHOLD = float(np.percentile(top1_scores, percentile))\n\n    margins = [top1_margin(r) for r in decoder_results if r and np.isfinite(top1_margin(r))]\n    LLM_GATE_MARGIN_THRESHOLD = float(np.percentile(margins, margin_percentile)) if margins else float('inf')\n\n    print(f\"LLM gate calibrated on {len(top1_scores)} utterances:\\n\"\n          f\"  low-score cutoff ({percentile}th pct): {LLM_GATE_THRESHOLD:.4f}\\n\"\n          f\"  margin cutoff ({margin_percentile}th pct): {LLM_GATE_MARGIN_THRESHOLD:.4f}\")\n    return LLM_GATE_THRESHOLD, LLM_GATE_MARGIN_THRESHOLD\n\n\ndef _is_gated(nbest_result):\n    if not nbest_result:\n        return True\n    low_score = LLM_GATE_THRESHOLD is not None and normalized_ngram_score(nbest_result[0]) < LLM_GATE_THRESHOLD\n    confident = LLM_GATE_MARGIN_THRESHOLD is not None and top1_margin(nbest_result) > LLM_GATE_MARGIN_THRESHOLD\n    return bool(low_score or confident)\n\n\ndef gated_rescore(nbest_result, lam=None, prefix=VERBATIM_PREFIX):\n    \"\"\"Final transcript for one utterance: decoder top-1 if gated, else fused.\"\"\"\n    if not nbest_result:\n        return \"\"\n    hyps = [\" \".join(h.words) if h.words else \"\" for h in nbest_result]\n    if not any(hyps):\n        return \"\"\n    if _is_gated(nbest_result):\n        return hyps[0]\n    lam = adaptive_lambda(nbest_result) if lam is None else lam\n    if lam == 0:\n        return hyps[0]\n    llm_scores = compute_llm_scores(hyps, batch_size=len(hyps), prefix=prefix)\n    return hyps[fuse_pick(nbest_result, llm_scores, lam)]","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:12:39.151119Z","iopub.status.busy":"2026-08-30T07:12:39.150506Z","iopub.status.idle":"2026-08-30T07:18:28.847771Z","shell.execute_reply":"2026-08-30T07:18:28.846803Z"},"papermill":{"duration":349.724839,"end_time":"2026-08-30T07:18:28.849629+00:00","exception":false,"start_time":"2026-08-30T07:12:39.12479+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"71d05543","cell_type":"markdown","source":"## BLOCK 5.4 · WER / CER / PER ON VALIDATION  (official normalization)\n","metadata":{"papermill":{"duration":0.027763,"end_time":"2026-08-30T07:18:28.90365+00:00","exception":false,"start_time":"2026-08-30T07:18:28.875887+00:00","status":"completed"},"tags":[]}},{"id":"8f3dc803","cell_type":"code","source":"# ============================================================================\n# BLOCK 5.4 · WER / CER / PER ON VALIDATION  (official normalization)\n# ============================================================================\ndef normalize_text(sentence):\n    \"\"\"Official brain-to-text '25 normalization (keeps apostrophes/hyphens).\"\"\"\n    sentence = re.sub(r'[^a-zA-Z\\- \\']', '', sentence)\n    sentence = sentence.replace('- ', ' ').lower()\n    sentence = sentence.replace('--', '').lower()\n    sentence = sentence.replace(\" '\", \"'\").lower()\n    sentence = sentence.strip()\n    sentence = ' '.join([w for w in sentence.split() if w != ''])\n    return sentence\n\n\ndef corpus_wer(refs, hyps):\n    return jiwer.wer([normalize_text(r) for r in refs], [normalize_text(h) for h in hyps])\n\n\ndef corpus_cer(refs, hyps):\n    return jiwer.cer([normalize_text(r) for r in refs], [normalize_text(h) for h in hyps])\n\n\ndef utterance_wer(ref, hyp):\n    return jiwer.wer(normalize_text(ref), normalize_text(hyp))\n\n\ndef utterance_cer(ref, hyp):\n    return jiwer.cer(normalize_text(ref), normalize_text(hyp))\n\n\ndef extract_emissions_from_loader(model, loader, device):\n    model.eval()\n    all_emissions, all_lengths, all_refs, all_days = [], [], [], []\n    with torch.no_grad():\n        for batch in tqdm(loader, desc='Extracting Val Emissions'):\n            neural = batch['neural'].to(device)\n            lengths = batch['lengths']\n            day_idx = batch['day_idx'].to(device)\n            with amp_autocast(enabled=CONFIG['use_amp']):\n                log_probs, output_lengths = model(neural, lengths, day_idx)\n            log_probs = log_probs.transpose(0, 1).float().cpu()  # [B, T, V]\n            all_emissions.append(log_probs)\n            all_lengths.append(output_lengths.cpu())\n            all_refs.extend(batch['sentences'])\n            all_days.extend(day_idx.cpu().tolist())\n\n    max_T = max(e.shape[1] for e in all_emissions)\n    padded = [F.pad(e, (0, 0, 0, max_T - e.shape[1])) for e in all_emissions]\n    return torch.cat(padded, dim=0), torch.cat(all_lengths, dim=0), all_refs, all_days\n\n\nval_emissions, val_lengths, val_refs, val_days = extract_emissions_from_loader(\n    model, val_loader, CONFIG['device'])\n\nprint(\"Decoding validation set (top-1 beam, no LLM) ...\")\nval_hyps = []\nDECODE_BATCH = 16\nfor i in tqdm(range(0, len(val_emissions), DECODE_BATCH), desc=\"Val beam search\"):\n    results = decoder(val_emissions[i:i + DECODE_BATCH], val_lengths[i:i + DECODE_BATCH])\n    for sample_result in results:\n        top = sample_result[0] if sample_result else None\n        val_hyps.append(\" \".join(top.words) if top and top.words else \"\")\n\npairs = [(r, h) for r, h in zip(val_refs, val_hyps) if r and r.strip()]\nrefs_clean = [r for r, h in pairs]\nhyps_clean = [h if h.strip() else \"<empty>\" for r, h in pairs]\n\noverall_wer = corpus_wer(refs_clean, hyps_clean)\noverall_cer = corpus_cer(refs_clean, hyps_clean)\nprint(f\"\\nValidation WER (beam + n-gram, no LLM): {overall_wer * 100:.2f}%\")\nprint(f\"Validation CER (beam + n-gram, no LLM): {overall_cer * 100:.2f}%\")\n\n# PER: straight CTC-greedy vs. ground-truth phonemes (independent of the LLM).\nprint(\"\\nComputing PER (CTC-greedy vs. ground-truth phoneme ids)...\")\nper_day_edits, per_day_counts = {d: 0 for d in set(val_days)}, {d: 0 for d in set(val_days)}\ntotal_phon_edits, total_phon_count = 0, 0\nper_per_utt = []\nmodel.eval()\nwith torch.no_grad():\n    for batch in tqdm(val_loader, desc=\"Greedy PER\"):\n        neural = batch['neural'].to(CONFIG['device'])\n        lengths = batch['lengths']\n        day_idx_batch = batch['day_idx']\n        sentences = batch['sentences']\n        targets = batch['target']\n        target_lengths = batch['target_lengths']\n        with amp_autocast(enabled=CONFIG['use_amp']):\n            log_probs, output_lengths = model(neural, lengths, day_idx_batch.to(CONFIG['device']))\n        decoded_phonemes = greedy_decode_phonemes(log_probs, output_lengths)\n        for b, phon_ids in enumerate(decoded_phonemes):\n            ref_phon_ids = targets[b, :target_lengths[b]].tolist()\n            if len(ref_phon_ids) == 0:\n                continue\n            edits = editdistance.eval(phon_ids, ref_phon_ids)\n            d = int(day_idx_batch[b])\n            per_day_edits[d] += edits\n            per_day_counts[d] += len(ref_phon_ids)\n            total_phon_edits += edits\n            total_phon_count += len(ref_phon_ids)\n            if sentences[b] and sentences[b].strip():\n                per_per_utt.append(100.0 * edits / max(len(ref_phon_ids), 1))\n\noverall_per = total_phon_edits / max(total_phon_count, 1)\nprint(f\"Validation PER (CTC-greedy): {overall_per * 100:.2f}%\")","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:18:28.955592Z","iopub.status.busy":"2026-08-30T07:18:28.954999Z","iopub.status.idle":"2026-08-30T07:22:04.899799Z","shell.execute_reply":"2026-08-30T07:22:04.898839Z"},"papermill":{"duration":215.97235,"end_time":"2026-08-30T07:22:04.901481+00:00","exception":false,"start_time":"2026-08-30T07:18:28.929131+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"cd7be9bc","cell_type":"markdown","source":"## BLOCK 5.5 · FULL PIPELINE VALIDATION  (beam + n-gram + margin-adaptive LLM)\n","metadata":{"papermill":{"duration":0.038714,"end_time":"2026-08-30T07:22:04.978468+00:00","exception":false,"start_time":"2026-08-30T07:22:04.939754+00:00","status":"completed"},"tags":[]}},{"id":"ebc5f0a4","cell_type":"code","source":"# ============================================================================\n# BLOCK 5.5 · FULL PIPELINE VALIDATION  (beam + n-gram + margin-adaptive LLM)\n# ============================================================================\nprint(f\"\\nDecoding validation set (n-best beam, lm_weight={LM_WEIGHT}) + margin-adaptive \"\n      f\"verbatim-conditioned LLM fusion (base LLM_FUSION_WEIGHT={LLM_FUSION_WEIGHT})...\")\n\nval_decoder_results = []\nfor i in tqdm(range(0, len(val_emissions), DECODE_BATCH), desc=\"Val beam search (n-best)\"):\n    val_decoder_results.extend(decoder(val_emissions[i:i + DECODE_BATCH],\n                                       val_lengths[i:i + DECODE_BATCH]))\n\ncalibrate_llm_gate_threshold(val_decoder_results)\n\nval_hyps_cache, val_llm_scores_cache = [], []\nn_gated_low_score, n_gated_confident = 0, 0\nfor sample_result in tqdm(val_decoder_results, desc=\"LLM scoring (non-gated only)\"):\n    if not sample_result:\n        val_hyps_cache.append([\"\"])\n        val_llm_scores_cache.append(None)\n        continue\n    hyps = [\" \".join(h.words) if h.words else \"\" for h in sample_result]\n    val_hyps_cache.append(hyps)\n    low_score = normalized_ngram_score(sample_result[0]) < LLM_GATE_THRESHOLD\n    confident = (not low_score) and top1_margin(sample_result) > LLM_GATE_MARGIN_THRESHOLD\n    if low_score:\n        n_gated_low_score += 1\n    elif confident:\n        n_gated_confident += 1\n    if (not any(hyps)) or _is_gated(sample_result):\n        val_llm_scores_cache.append(None)\n    else:\n        val_llm_scores_cache.append(compute_llm_scores(hyps, batch_size=len(hyps)))\n\nn_gated_total = n_gated_low_score + n_gated_confident\nprint(f\"Skipped LLM on {n_gated_total}/{len(val_decoder_results)} \"\n      f\"({100 * n_gated_total / max(len(val_decoder_results), 1):.1f}%): \"\n      f\"{n_gated_low_score} low-score, {n_gated_confident} high-confidence.\")\n\n\ndef _predict_adaptive(decoder_results, hyps_cache, llm_scores_cache, base_lambda=None):\n    preds, lambdas_used = [], []\n    for res, hyps, llm_s in zip(decoder_results, hyps_cache, llm_scores_cache):\n        if not res or not any(hyps):\n            preds.append(\"\")\n            continue\n        if llm_s is None:\n            preds.append(hyps[0])\n            continue\n        lam = adaptive_lambda(res, base_lambda=base_lambda)\n        lambdas_used.append(lam)\n        preds.append(hyps[0] if lam == 0 else hyps[fuse_pick(res, llm_s, lam)])\n    return preds, lambdas_used\n\n\nval_preds, val_lambdas_used = _predict_adaptive(\n    val_decoder_results, val_hyps_cache, val_llm_scores_cache)\n_pairs = [(r, h) for r, h in zip(val_refs, val_preds) if r and r.strip()]\n_refs_c = [r for r, _ in _pairs]\n_hyps_c = [h if h.strip() else \"<empty>\" for _, h in _pairs]\nfull_pipeline_wer = corpus_wer(_refs_c, _hyps_c)\nfull_pipeline_cer = corpus_cer(_refs_c, _hyps_c)\n\nprint(f\"\\nMean adaptive lambda applied: {np.mean(val_lambdas_used) if val_lambdas_used else 0:.3f} \"\n      f\"(base={LLM_FUSION_WEIGHT})\")\nprint(f\"Validation WER - full pipeline (+adaptive LLM fusion): {full_pipeline_wer * 100:.2f}%\")\nprint(f\"Validation CER - full pipeline: {full_pipeline_cer * 100:.2f}%\")\nprint(f\"(beam + n-gram only was WER={overall_wer * 100:.2f}%, CER={overall_cer * 100:.2f}%)\")\nprint(f\"PER (CTC-greedy, unaffected): {overall_per * 100:.2f}%\")\n\nwith open(os.path.join(CONFIG['checkpoint_dir'], 'val_wer.json'), 'w') as f:\n    json.dump({\n        'wer_beam_ngram_only': overall_wer,\n        'cer_beam_ngram_only': overall_cer,\n        'wer_full_pipeline': full_pipeline_wer,\n        'cer_full_pipeline': full_pipeline_cer,\n        'per_greedy': overall_per,\n        'lm_weight': LM_WEIGHT,\n        'llm_fusion_weight_base': LLM_FUSION_WEIGHT,\n        'mean_adaptive_lambda': float(np.mean(val_lambdas_used)) if val_lambdas_used else None,\n    }, f, indent=2)\n\n\n# ---- Optional per-day tables + summary chart -------------------------------\nidx2session = {v: k for k, v in session2idx.items()}\nclean_days = [d for r, d in zip(val_refs, val_days) if r and r.strip()]\nday_refs, day_hyps = {}, {}\nfor r, h, d in zip(refs_clean, hyps_clean, clean_days):\n    day_refs.setdefault(d, []).append(r)\n    day_hyps.setdefault(d, []).append(h)\ndays_sorted = sorted(day_refs.keys())\nsession_names = [idx2session[d] for d in days_sorted]\nwer_by_day = [corpus_wer(day_refs[d], day_hyps[d]) * 100 for d in days_sorted]\ncer_by_day = [corpus_cer(day_refs[d], day_hyps[d]) * 100 for d in days_sorted]\nper_by_day = [100.0 * per_day_edits[d] / per_day_counts[d] if per_day_counts.get(d, 0) > 0 else np.nan\n              for d in days_sorted]\n\nfig, ax = plt.subplots(figsize=(9, 6))\ngroup_labels = ['WER\\n(Beam+NGram)', 'WER\\n(+LLM)', 'CER\\n(Beam+NGram)', 'CER\\n(+LLM)', 'PER\\n(CTC)']\nvalues = [overall_wer * 100, full_pipeline_wer * 100,\n          overall_cer * 100, full_pipeline_cer * 100, overall_per * 100]\nbars = ax.bar(group_labels, values,\n              color=['tab:purple', 'tab:pink', 'tab:blue', 'tab:cyan', 'tab:green'])\nfor bar, val in zip(bars, values):\n    ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(), f'{val:.1f}%',\n            ha='center', va='bottom')\nax.set_ylabel('Error Rate (%)')\nax.set_title('Final Validation Error Rates: WER vs CER vs PER')\nax.grid(True, axis='y', alpha=0.3)\nfig.tight_layout()\nfig.savefig(os.path.join(figures_dir, 'metrics_summary.png'), dpi=300, bbox_inches='tight')\nplt.close(fig)\n\nprint(\"\\nFinal validation numbers:\")\nprint(f\"  WER  beam+ngram : {overall_wer * 100:.2f}%   +LLM : {full_pipeline_wer * 100:.2f}%\")\nprint(f\"  CER  beam+ngram : {overall_cer * 100:.2f}%   +LLM : {full_pipeline_cer * 100:.2f}%\")\nprint(f\"  PER  CTC-greedy : {overall_per * 100:.2f}%\")","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:22:05.175907Z","iopub.status.busy":"2026-08-30T07:22:05.17549Z","iopub.status.idle":"2026-08-30T07:50:29.018785Z","shell.execute_reply":"2026-08-30T07:50:29.017802Z"},"papermill":{"duration":1703.882791,"end_time":"2026-08-30T07:50:29.020493+00:00","exception":false,"start_time":"2026-08-30T07:22:05.137702+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e4e7b014","cell_type":"markdown","source":"# BLOCK 5.6 · HYPERPARAMETER GRID SEARCH  (LM_WEIGHT × LAMBDA / FUSION WEIGHT — ARRAYS, NOT FIXED VALUES)\n","metadata":{"papermill":{"duration":0.077389,"end_time":"2026-08-30T07:50:29.180764+00:00","exception":false,"start_time":"2026-08-30T07:50:29.103375+00:00","status":"completed"},"tags":[]}},{"id":"ac0f8698","cell_type":"code","source":"# ============================================================================\n# BLOCK 5.6 · HYPERPARAMETER GRID SEARCH  (joint LM_WEIGHT x LAMBDA_GRID)\n# ============================================================================\n# For every lm_weight in LM_WEIGHT_GRID: rebuild the beam/n-gram decoder, get\n# its n-best output + LLM scores ONCE, then cheaply evaluate every lambda in\n# LAMBDA_GRID via fuse_pick (no LLM recompute needed per-lambda). This gives\n# a true joint (lm_weight, lambda) grid without redoing the expensive decode\n# or LLM-scoring pass for every lambda value.\n#\n# Produces the 3 summary plots at the end:\n#   1) WER vs. n-gram LM weight (best lambda re-tuned at each lm_weight)\n#   2) WER vs. CER before/after LLM fusion (bar chart)\n#   3) WER / CER vs. LLM fusion weight (lambda), at the best lm_weight found\n# ============================================================================\nimport itertools\nimport time\n\nassert RUN_HYPERPARAM_SWEEPS, (\n    \"RUN_HYPERPARAM_SWEEPS is False (set in BLOCK 1 / CONFIG cell). \"\n    \"This cell is the sweep itself, so flip RUN_HYPERPARAM_SWEEPS = True \"\n    \"in BLOCK 1 and re-run from there before running this cell.\"\n)\n\nLM_WEIGHT_GRID = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0]\nLAMBDA_GRID = np.round(np.arange(0.0, 2.5 + 1e-9, 0.25), 2).tolist()          # [0.0, 0.25, ..., 2.5]\n\nassert 'val_emissions' in globals(), \"Run BLOCK 5.4 first (need val_emissions/val_lengths/val_refs/val_days).\"\n\nprint(f\"LM_WEIGHT_GRID ({len(LM_WEIGHT_GRID)} values): {LM_WEIGHT_GRID}\")\nprint(f\"LAMBDA_GRID ({len(LAMBDA_GRID)} values): {LAMBDA_GRID}\")\n\n\ndef decode_nbest_and_cache(dec, batch_size=16):\n    \"\"\"Full n-best decode + gate calibration + LLM-score caching for one decoder.\n    Returns (decoder_results, hyps_cache, llm_scores_cache).\"\"\"\n    decoder_results = []\n    for i in range(0, len(val_emissions), batch_size):\n        decoder_results.extend(dec(val_emissions[i:i + batch_size], val_lengths[i:i + batch_size]))\n    calibrate_llm_gate_threshold(decoder_results)\n\n    hyps_cache, llm_scores_cache = [], []\n    for sample_result in decoder_results:\n        if not sample_result:\n            hyps_cache.append([\"\"])\n            llm_scores_cache.append(None)\n            continue\n        hyps = [\" \".join(h.words) if h.words else \"\" for h in sample_result]\n        hyps_cache.append(hyps)\n        llm_scores_cache.append(\n            None if (not any(hyps)) or _is_gated(sample_result)\n            else compute_llm_scores(hyps, batch_size=len(hyps))\n        )\n    return decoder_results, hyps_cache, llm_scores_cache\n\n\ndef wer_cer_for_lambda(decoder_results, hyps_cache, llm_scores_cache, lam):\n    preds, _ = _predict_adaptive(decoder_results, hyps_cache, llm_scores_cache, base_lambda=lam)\n    pairs = [(r, h) for r, h in zip(val_refs, preds) if r and r.strip()]\n    refs_c = [r for r, _ in pairs]\n    hyps_c = [h if h.strip() else \"<empty>\" for _, h in pairs]\n    return corpus_wer(refs_c, hyps_c), corpus_cer(refs_c, hyps_c)\n\n\n# ---------------------------------------------------------------------------\n# Joint grid search: one decode+LLM-cache pass per lm_weight, then a cheap\n# lambda sweep on top of it.\n# ---------------------------------------------------------------------------\nprint(\"\\n=== Joint LM_WEIGHT x LAMBDA_GRID sweep ===\")\ngrid_rows = []\nbest_by_lm_weight_cache = {}  # lm_weight -> (decoder_results, hyps_cache, llm_scores_cache)\nt0 = time.time()\nfor lw in tqdm(LM_WEIGHT_GRID, desc=\"LM_WEIGHT outer loop\"):\n    dec_i = build_decoder(lm_weight=lw)\n    decoder_results, hyps_cache, llm_scores_cache = decode_nbest_and_cache(dec_i, DECODE_BATCH)\n    best_by_lm_weight_cache[lw] = (decoder_results, hyps_cache, llm_scores_cache)\n    for lam in LAMBDA_GRID:\n        wer_i, cer_i = wer_cer_for_lambda(decoder_results, hyps_cache, llm_scores_cache, lam)\n        grid_rows.append({'lm_weight': lw, 'lambda': lam, 'wer': wer_i, 'cer': cer_i})\n    del dec_i\nprint(f\"Joint sweep took {time.time() - t0:.1f}s ({len(grid_rows)} (lm_weight, lambda) combos)\")\n\ngrid_df = pd.DataFrame(grid_rows)\ngrid_df.to_csv(os.path.join(CONFIG['checkpoint_dir'], 'hparam_grid_full.csv'), index=False)\n\n# Global best (lm_weight, lambda) combo.\nbest_row = grid_df.loc[grid_df['wer'].idxmin()]\nBEST_LM_WEIGHT = float(best_row['lm_weight'])\nBEST_LAMBDA = float(best_row['lambda'])\nprint(f\"\\nBest combo: lm_weight={BEST_LM_WEIGHT}, lambda={BEST_LAMBDA} \"\n      f\"-> WER={best_row['wer'] * 100:.2f}%, CER={best_row['cer'] * 100:.2f}%\")\n\n# Per-lm_weight best (lambda re-tuned at each point) - for chart 1.\nper_lmweight_best = grid_df.loc[grid_df.groupby('lm_weight')['wer'].idxmin()].sort_values('lm_weight')\n\n# Lambda sweep AT the best lm_weight - for chart 3.\nlambda_at_best = grid_df[grid_df['lm_weight'] == BEST_LM_WEIGHT].sort_values('lambda').reset_index(drop=True)\n\n# Baseline (beam+n-gram only, i.e. lambda=0) at the best lm_weight - for chart 2.\nbaseline_row = lambda_at_best[lambda_at_best['lambda'] == 0.0].iloc[0]\n\nLM_WEIGHT = BEST_LM_WEIGHT\nLLM_FUSION_WEIGHT = BEST_LAMBDA\nCONFIG['llm_fusion_weight'] = BEST_LAMBDA\ndecoder = build_decoder(lm_weight=LM_WEIGHT)  # leave the live decoder set to the winning combo\n\nwith open(os.path.join(CONFIG['checkpoint_dir'], 'best_hparams.json'), 'w') as f:\n    json.dump({\n        'best_lm_weight': BEST_LM_WEIGHT,\n        'best_lambda': BEST_LAMBDA,\n        'wer_beam_ngram_only': float(baseline_row['wer']),\n        'cer_beam_ngram_only': float(baseline_row['cer']),\n        'wer_full_pipeline': float(best_row['wer']),\n        'cer_full_pipeline': float(best_row['cer']),\n    }, f, indent=2)\nprint(\"Saved: hparam_grid_full.csv, best_hparams.json\")\n\n# ============================================================================\n# PLOT 1 · WER vs. n-gram LM weight (fusion lambda re-tuned at each point)\n# ============================================================================\nfig1, ax1 = plt.subplots(figsize=(9, 6))\nx1 = per_lmweight_best['lm_weight'].tolist()\ny1 = (per_lmweight_best['wer'] * 100).tolist()\nax1.plot(x1, y1, color='tab:purple', marker='o', markersize=8, linewidth=2, zorder=3)\nfor x, y in zip(x1, y1):\n    ax1.annotate(f'{y:.2f}', (x, y), textcoords='offset points', xytext=(0, 10),\n                 ha='center', fontsize=9, color='dimgray')\nbest_wer_pct = float(best_row['wer']) * 100\nax1.scatter([BEST_LM_WEIGHT], [best_wer_pct], color='firebrick', s=180, zorder=5,\n            label=f'Best found (lm_weight={BEST_LM_WEIGHT:g})')\nax1.axhline(best_wer_pct, color='firebrick', linestyle='--', linewidth=1, alpha=0.6)\nax1.set_xlabel('n-gram lm_weight')\nax1.set_ylabel('Validation WER (%)')\nax1.set_title('WER vs. n-gram LM weight\\n(fusion lambda re-tuned at each point)')\nax1.legend(loc='upper right', frameon=False)\nax1.grid(alpha=0.3)\nfig1.tight_layout()\nfig1.savefig(os.path.join(figures_dir, 'lmweight_sweep.png'), dpi=300, bbox_inches='tight')\nplt.show()\n\n# ============================================================================\n# PLOT 2 · WER vs. CER before/after LLM fusion\n# ============================================================================\nfig2, ax2 = plt.subplots(figsize=(8, 6))\ncategories = ['Beam+N-gram\\n(no LLM)', '+Adaptive LLM\\nfusion (final)']\nwer_vals = [float(baseline_row['wer']) * 100, float(best_row['wer']) * 100]\ncer_vals = [float(baseline_row['cer']) * 100, float(best_row['cer']) * 100]\nbar_w = 0.35\nxpos = np.arange(len(categories))\nbars_wer = ax2.bar(xpos - bar_w / 2, wer_vals, bar_w, color='tab:purple', label='WER')\nbars_cer = ax2.bar(xpos + bar_w / 2, cer_vals, bar_w, color='tab:blue', label='CER')\nfor bars in (bars_wer, bars_cer):\n    for bar in bars:\n        h = bar.get_height()\n        ax2.text(bar.get_x() + bar.get_width() / 2, h, f'{h:.2f}%',\n                 ha='center', va='bottom', fontsize=10)\nax2.set_xticks(xpos)\nax2.set_xticklabels(categories)\nax2.set_ylabel('Error rate (%)')\nax2.set_title('WER vs. CER before/after LLM fusion')\nax2.legend(frameon=True)\nax2.grid(alpha=0.3, axis='y')\nfig2.tight_layout()\nfig2.savefig(os.path.join(figures_dir, 'wer_cer_before_after.png'), dpi=300, bbox_inches='tight')\nplt.show()\n\n# ============================================================================\n# PLOT 3 · WER / CER vs. LLM fusion weight (lambda), at the best lm_weight\n# ============================================================================\nfig3, ax3 = plt.subplots(figsize=(9, 6))\nx3 = lambda_at_best['lambda'].tolist()\nwer3 = (lambda_at_best['wer'] * 100).tolist()\ncer3 = (lambda_at_best['cer'] * 100).tolist()\nax3.plot(x3, wer3, color='tab:purple', marker='o', markersize=7, linewidth=2, label='WER%')\nax3.plot(x3, cer3, color='tab:blue', marker='s', markersize=7, linewidth=2, label='CER%')\nbest_idx = int(np.argmin(wer3))\nax3.scatter([x3[best_idx]], [wer3[best_idx]], color='firebrick', s=140, zorder=5)\nax3.set_xlabel('LLM fusion weight (\\u03bb)')\nax3.set_ylabel('Error rate (%)')\nax3.set_title('WER / CER vs. LLM fusion weight (\\u03bb)')\nax3.legend(frameon=True)\nax3.grid(alpha=0.3)\nfig3.tight_layout()\nfig3.savefig(os.path.join(figures_dir, 'lambda_sweep.png'), dpi=300, bbox_inches='tight')\nplt.show()\n\nprint(f\"\\n>>> Final: LM_WEIGHT={BEST_LM_WEIGHT}, LLM_FUSION_WEIGHT={BEST_LAMBDA} \"\n      f\"(WER={best_row['wer'] * 100:.2f}%, CER={best_row['cer'] * 100:.2f}%). \"\n      f\"`decoder` global is already rebuilt with this lm_weight.\")\n","metadata":{"execution":{"iopub.execute_input":"2026-08-30T07:50:29.331561Z","iopub.status.busy":"2026-08-30T07:50:29.331104Z","iopub.status.idle":"2026-08-30T11:35:01.335901Z","shell.execute_reply":"2026-08-30T11:35:01.334959Z"},"papermill":{"duration":13472.081773,"end_time":"2026-08-30T11:35:01.337818+00:00","exception":false,"start_time":"2026-08-30T07:50:29.256045+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ba0bcacb","cell_type":"markdown","source":"# BLOCK 6 · [OPTIONAL] GENERATE KAGGLE SUBMISSION FROM THE TEST SET\n","metadata":{"papermill":{"duration":0.082385,"end_time":"2026-08-30T11:35:01.510263+00:00","exception":false,"start_time":"2026-08-30T11:35:01.427878+00:00","status":"completed"},"tags":[]}},{"id":"090633d0","cell_type":"code","source":"# ============================================================================\n# BLOCK 6 · [OPTIONAL] GENERATE KAGGLE SUBMISSION FROM THE TEST SET\n# ============================================================================\nGENERATE_SUBMISSION = True   # set False to stop after validation\n\n\ndef block_load_test_data(data_dir, session2idx, feat_mean, feat_std, clip=5.0):\n    files = sorted(glob(f'{data_dir}/**/data_test.hdf5', recursive=True))\n    all_samples, sample_id = [], 0\n    for filepath in tqdm(files, desc=\"Loading Test HDF5\"):\n        session = Path(filepath).parent.name\n        with h5py.File(filepath, 'r') as f:\n            trial_keys = [k for k in f.keys() if 'trial' in k.lower()]\n            entries = []\n            for trial_key in trial_keys:\n                trial = f[trial_key]\n                if 'input_features' not in trial:\n                    continue\n                entries.append((int(trial.attrs.get('block_num', 0)),\n                                int(trial.attrs.get('trial_num', 0)), trial_key))\n            entries.sort(key=lambda e: (e[0], e[1]))\n            for block_num, trial_num, trial_key in entries:\n                trial = f[trial_key]\n                features = trial['input_features'][:trial.attrs['n_time_steps']]\n                features = torch.FloatTensor(features)\n                features = (features - feat_mean) / feat_std\n                features = torch.clamp(features, -clip, clip)\n                all_samples.append({\n                    'id': sample_id, 'session': session, 'day_idx': session2idx[session],\n                    'block_num': block_num, 'trial_num': trial_num,\n                    'trial_key': trial_key, 'features': features,\n                })\n                sample_id += 1\n    return all_samples\n\n\ndef extract_emissions(model, samples, device):\n    model.eval()\n    all_emissions, all_lengths, all_ids = [], [], []\n    with torch.no_grad():\n        for i in tqdm(range(0, len(samples), 32), desc='Extracting Test Emissions'):\n            batch = samples[i:i + 32]\n            features = [s['features'] for s in batch]\n            lengths = torch.LongTensor([len(f) for f in features])\n            day_idx = torch.LongTensor([s['day_idx'] for s in batch]).to(device)\n            features_padded = torch.nn.utils.rnn.pad_sequence(features, batch_first=True).to(device)\n            sorted_lengths, sorted_idx = lengths.sort(descending=True)\n            with amp_autocast(enabled=CONFIG['use_amp']):\n                log_probs, output_lengths = model(\n                    features_padded[sorted_idx], sorted_lengths, day_idx[sorted_idx])\n            log_probs = log_probs.transpose(0, 1).float().cpu()\n\n            unsorted = torch.empty_like(log_probs)\n            unsorted_lengths = torch.empty_like(output_lengths.cpu())\n            unsorted[sorted_idx] = log_probs\n            unsorted_lengths[sorted_idx] = output_lengths.cpu()\n            all_emissions.append(unsorted)\n            all_lengths.append(unsorted_lengths)\n            all_ids.extend([s['id'] for s in batch])\n\n    max_T = max(e.shape[1] for e in all_emissions)\n    all_emissions = [F.pad(e, (0, 0, 0, max_T - e.shape[1])) for e in all_emissions]\n    return torch.cat(all_emissions, dim=0), torch.cat(all_lengths, dim=0), all_ids\n\n\nif GENERATE_SUBMISSION:\n    print(\"\\nLoading test set...\")\n    test_samples = block_load_test_data(CONFIG['data_dir'], session2idx, feat_mean, feat_std)\n    print(f\"Test samples: {len(test_samples)}\")\n\n    test_emissions, test_lengths, test_ids = extract_emissions(model, test_samples, CONFIG['device'])\n\n    print(\"Running batched beam search on test set...\")\n    test_decoder_results = []\n    for i in tqdm(range(0, len(test_emissions), DECODE_BATCH), desc=\"Beam search\"):\n        test_decoder_results.extend(decoder(test_emissions[i:i + DECODE_BATCH],\n                                             test_lengths[i:i + DECODE_BATCH]))\n\n    # Reuse the validation-calibrated gate thresholds; fall back only if missing.\n    if LLM_GATE_THRESHOLD is None or LLM_GATE_MARGIN_THRESHOLD is None:\n        print(\"WARNING: no validation-calibrated gate thresholds - calibrating on test scores.\")\n        calibrate_llm_gate_threshold(test_decoder_results)\n\n    print(f\"Score-fusion LLM rescoring with LLM_FUSION_WEIGHT={LLM_FUSION_WEIGHT}...\")\n    FINAL_PREDICTIONS = []\n    n_gated_low_score, n_gated_confident = 0, 0\n    for sample_result in tqdm(test_decoder_results, desc=\"Gated LLM rescoring\"):\n        if sample_result:\n            if normalized_ngram_score(sample_result[0]) < LLM_GATE_THRESHOLD:\n                n_gated_low_score += 1\n            elif top1_margin(sample_result) > LLM_GATE_MARGIN_THRESHOLD:\n                n_gated_confident += 1\n        FINAL_PREDICTIONS.append(gated_rescore(sample_result))\n\n    n_gated_total = n_gated_low_score + n_gated_confident\n    print(f\"Skipped LLM on {n_gated_total}/{len(test_decoder_results)} \"\n          f\"({100 * n_gated_total / max(len(test_decoder_results), 1):.1f}%): \"\n          f\"{n_gated_low_score} low-score, {n_gated_confident} high-confidence.\")\n\n    # Match whatever columns sample_submission.csv expects.\n    sample_sub_path = None\n    for pattern in [os.path.join(os.path.dirname(CONFIG['data_dir']), '**', 'sample_submission.csv'),\n                    '/kaggle/input/**/sample_submission.csv']:\n        matches = glob(pattern, recursive=True)\n        if matches:\n            sample_sub_path = matches[0]\n            break\n\n    if sample_sub_path:\n        sample_df = pd.read_csv(sample_sub_path)\n        id_col, text_col = sample_df.columns[0], sample_df.columns[1]\n        print(f\"Using columns '{id_col}', '{text_col}' from {sample_sub_path}\")\n    else:\n        id_col, text_col = 'id', 'text'\n        print(\"No sample_submission.csv found - defaulting to 'id','text'.\")\n\n    df = pd.DataFrame({id_col: test_ids, text_col: FINAL_PREDICTIONS})\n    df = df.sort_values(id_col).reset_index(drop=True)\n    df[id_col] = range(len(df))\n    df.to_csv('submission.csv', index=False)\n    print('\\nFinished! Predictions written to submission.csv')\n    print(df.head(10).to_string(index=False))","metadata":{"execution":{"iopub.execute_input":"2026-08-30T11:35:01.67944Z","iopub.status.busy":"2026-08-30T11:35:01.679093Z","iopub.status.idle":"2026-08-30T12:09:03.582783Z","shell.execute_reply":"2026-08-30T12:09:03.581789Z"},"papermill":{"duration":2041.990378,"end_time":"2026-08-30T12:09:03.584531+00:00","exception":false,"start_time":"2026-08-30T11:35:01.594153+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"64389cc4","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128183,"end_time":"2026-08-30T12:09:03.854523+00:00","exception":false,"start_time":"2026-08-30T12:09:03.72634+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2cbdc155","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127755,"end_time":"2026-08-30T12:09:04.109279+00:00","exception":false,"start_time":"2026-08-30T12:09:03.981524+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5eec49dc","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127461,"end_time":"2026-08-30T12:09:04.36695+00:00","exception":false,"start_time":"2026-08-30T12:09:04.239489+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7499c98d","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128555,"end_time":"2026-08-30T12:09:04.625021+00:00","exception":false,"start_time":"2026-08-30T12:09:04.496466+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"8f9bff24","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127853,"end_time":"2026-08-30T12:09:04.880911+00:00","exception":false,"start_time":"2026-08-30T12:09:04.753058+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"467b8d00","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131244,"end_time":"2026-08-30T12:09:05.138624+00:00","exception":false,"start_time":"2026-08-30T12:09:05.00738+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c4f52063","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128719,"end_time":"2026-08-30T12:09:05.481672+00:00","exception":false,"start_time":"2026-08-30T12:09:05.352953+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"220553f4","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126326,"end_time":"2026-08-30T12:09:05.73826+00:00","exception":false,"start_time":"2026-08-30T12:09:05.611934+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f7d3a424","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127416,"end_time":"2026-08-30T12:09:05.999435+00:00","exception":false,"start_time":"2026-08-30T12:09:05.872019+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0c455d65","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128298,"end_time":"2026-08-30T12:09:06.28285+00:00","exception":false,"start_time":"2026-08-30T12:09:06.154552+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"1ddd1864","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132885,"end_time":"2026-08-30T12:09:06.545774+00:00","exception":false,"start_time":"2026-08-30T12:09:06.412889+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"76add55c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128833,"end_time":"2026-08-30T12:09:06.802126+00:00","exception":false,"start_time":"2026-08-30T12:09:06.673293+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"abcb8edc","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.12904,"end_time":"2026-08-30T12:09:07.061206+00:00","exception":false,"start_time":"2026-08-30T12:09:06.932166+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"63046f60","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132802,"end_time":"2026-08-30T12:09:07.324656+00:00","exception":false,"start_time":"2026-08-30T12:09:07.191854+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"805531fb","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.222288,"end_time":"2026-08-30T12:09:07.677984+00:00","exception":false,"start_time":"2026-08-30T12:09:07.455696+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"3b170800","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.1272,"end_time":"2026-08-30T12:09:07.932349+00:00","exception":false,"start_time":"2026-08-30T12:09:07.805149+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"dee97084","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129259,"end_time":"2026-08-30T12:09:08.188081+00:00","exception":false,"start_time":"2026-08-30T12:09:08.058822+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f23a7385","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.125876,"end_time":"2026-08-30T12:09:08.440223+00:00","exception":false,"start_time":"2026-08-30T12:09:08.314347+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0137e82a","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127187,"end_time":"2026-08-30T12:09:08.698145+00:00","exception":false,"start_time":"2026-08-30T12:09:08.570958+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"be83925c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127402,"end_time":"2026-08-30T12:09:08.953027+00:00","exception":false,"start_time":"2026-08-30T12:09:08.825625+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"27452371","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130593,"end_time":"2026-08-30T12:09:09.209005+00:00","exception":false,"start_time":"2026-08-30T12:09:09.078412+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2c08d36a","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128708,"end_time":"2026-08-30T12:09:09.466363+00:00","exception":false,"start_time":"2026-08-30T12:09:09.337655+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2608b21f","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131859,"end_time":"2026-08-30T12:09:09.729352+00:00","exception":false,"start_time":"2026-08-30T12:09:09.597493+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"4a6337ff","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.12668,"end_time":"2026-08-30T12:09:09.983477+00:00","exception":false,"start_time":"2026-08-30T12:09:09.856797+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ab8ba535","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128745,"end_time":"2026-08-30T12:09:10.240569+00:00","exception":false,"start_time":"2026-08-30T12:09:10.111824+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"075c2274","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.133713,"end_time":"2026-08-30T12:09:10.59367+00:00","exception":false,"start_time":"2026-08-30T12:09:10.459957+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"788e0feb","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129764,"end_time":"2026-08-30T12:09:10.857193+00:00","exception":false,"start_time":"2026-08-30T12:09:10.727429+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"20dbeb32","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127387,"end_time":"2026-08-30T12:09:11.113209+00:00","exception":false,"start_time":"2026-08-30T12:09:10.985822+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"b025b5a8","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127716,"end_time":"2026-08-30T12:09:11.371106+00:00","exception":false,"start_time":"2026-08-30T12:09:11.24339+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"158110b3","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129225,"end_time":"2026-08-30T12:09:11.627341+00:00","exception":false,"start_time":"2026-08-30T12:09:11.498116+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ac792b83","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129074,"end_time":"2026-08-30T12:09:11.887887+00:00","exception":false,"start_time":"2026-08-30T12:09:11.758813+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"3521ca1a","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130588,"end_time":"2026-08-30T12:09:12.148511+00:00","exception":false,"start_time":"2026-08-30T12:09:12.017923+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"cb5e168d","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126308,"end_time":"2026-08-30T12:09:12.403505+00:00","exception":false,"start_time":"2026-08-30T12:09:12.277197+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0b6b37ed","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.13299,"end_time":"2026-08-30T12:09:12.751666+00:00","exception":false,"start_time":"2026-08-30T12:09:12.618676+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"49317292","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.125067,"end_time":"2026-08-30T12:09:13.00566+00:00","exception":false,"start_time":"2026-08-30T12:09:12.880593+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f9132688","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129516,"end_time":"2026-08-30T12:09:13.263155+00:00","exception":false,"start_time":"2026-08-30T12:09:13.133639+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"395adabb","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.13118,"end_time":"2026-08-30T12:09:13.522418+00:00","exception":false,"start_time":"2026-08-30T12:09:13.391238+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7ca5463a","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129952,"end_time":"2026-08-30T12:09:13.78008+00:00","exception":false,"start_time":"2026-08-30T12:09:13.650128+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"1917e1a7","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.124916,"end_time":"2026-08-30T12:09:14.031282+00:00","exception":false,"start_time":"2026-08-30T12:09:13.906366+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"83a8139e","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129429,"end_time":"2026-08-30T12:09:14.288098+00:00","exception":false,"start_time":"2026-08-30T12:09:14.158669+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5fe6a4a7","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129818,"end_time":"2026-08-30T12:09:14.545332+00:00","exception":false,"start_time":"2026-08-30T12:09:14.415514+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"63dff68c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131336,"end_time":"2026-08-30T12:09:14.802563+00:00","exception":false,"start_time":"2026-08-30T12:09:14.671227+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e2e2f78a","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127154,"end_time":"2026-08-30T12:09:15.057321+00:00","exception":false,"start_time":"2026-08-30T12:09:14.930167+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"4d3fc5b3","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.211951,"end_time":"2026-08-30T12:09:15.397282+00:00","exception":false,"start_time":"2026-08-30T12:09:15.185331+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"924d7d2d","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128603,"end_time":"2026-08-30T12:09:15.653766+00:00","exception":false,"start_time":"2026-08-30T12:09:15.525163+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"d184a17e","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.12596,"end_time":"2026-08-30T12:09:15.914797+00:00","exception":false,"start_time":"2026-08-30T12:09:15.788837+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c0e0256c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.135572,"end_time":"2026-08-30T12:09:16.198123+00:00","exception":false,"start_time":"2026-08-30T12:09:16.062551+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"3009ac8c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128055,"end_time":"2026-08-30T12:09:16.455069+00:00","exception":false,"start_time":"2026-08-30T12:09:16.327014+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"4db5efc4","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127754,"end_time":"2026-08-30T12:09:16.712121+00:00","exception":false,"start_time":"2026-08-30T12:09:16.584367+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"49e89869","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127695,"end_time":"2026-08-30T12:09:16.969451+00:00","exception":false,"start_time":"2026-08-30T12:09:16.841756+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"fa1f1288","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127074,"end_time":"2026-08-30T12:09:17.22355+00:00","exception":false,"start_time":"2026-08-30T12:09:17.096476+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"4dd57fa2","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.216382,"end_time":"2026-08-30T12:09:17.570362+00:00","exception":false,"start_time":"2026-08-30T12:09:17.35398+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"3630a2d7","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131881,"end_time":"2026-08-30T12:09:17.830058+00:00","exception":false,"start_time":"2026-08-30T12:09:17.698177+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"3734e791","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126758,"end_time":"2026-08-30T12:09:18.084385+00:00","exception":false,"start_time":"2026-08-30T12:09:17.957627+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"eee866fb","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129763,"end_time":"2026-08-30T12:09:18.344248+00:00","exception":false,"start_time":"2026-08-30T12:09:18.214485+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f0a1e314","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.137919,"end_time":"2026-08-30T12:09:18.609247+00:00","exception":false,"start_time":"2026-08-30T12:09:18.471328+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ada3541b","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131097,"end_time":"2026-08-30T12:09:18.871224+00:00","exception":false,"start_time":"2026-08-30T12:09:18.740127+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"142c93ee","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130676,"end_time":"2026-08-30T12:09:19.130638+00:00","exception":false,"start_time":"2026-08-30T12:09:18.999962+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"289df417","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131387,"end_time":"2026-08-30T12:09:19.402799+00:00","exception":false,"start_time":"2026-08-30T12:09:19.271412+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"b008e858","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.136551,"end_time":"2026-08-30T12:09:19.671244+00:00","exception":false,"start_time":"2026-08-30T12:09:19.534693+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"59abf9a1","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129932,"end_time":"2026-08-30T12:09:19.948339+00:00","exception":false,"start_time":"2026-08-30T12:09:19.818407+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c5a4aac2","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132184,"end_time":"2026-08-30T12:09:20.208763+00:00","exception":false,"start_time":"2026-08-30T12:09:20.076579+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"b69ef3ef","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132952,"end_time":"2026-08-30T12:09:20.558131+00:00","exception":false,"start_time":"2026-08-30T12:09:20.425179+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5d7e6ef4","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127332,"end_time":"2026-08-30T12:09:20.813408+00:00","exception":false,"start_time":"2026-08-30T12:09:20.686076+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"a4dbe631","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128613,"end_time":"2026-08-30T12:09:21.072129+00:00","exception":false,"start_time":"2026-08-30T12:09:20.943516+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c70c3e69","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128741,"end_time":"2026-08-30T12:09:21.330007+00:00","exception":false,"start_time":"2026-08-30T12:09:21.201266+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c097515b","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129981,"end_time":"2026-08-30T12:09:21.589591+00:00","exception":false,"start_time":"2026-08-30T12:09:21.45961+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e1439362","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127929,"end_time":"2026-08-30T12:09:21.844269+00:00","exception":false,"start_time":"2026-08-30T12:09:21.71634+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"1ad83d5c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126895,"end_time":"2026-08-30T12:09:22.101526+00:00","exception":false,"start_time":"2026-08-30T12:09:21.974631+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"6e885283","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127365,"end_time":"2026-08-30T12:09:22.358833+00:00","exception":false,"start_time":"2026-08-30T12:09:22.231468+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"9e1e463b","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127861,"end_time":"2026-08-30T12:09:22.706388+00:00","exception":false,"start_time":"2026-08-30T12:09:22.578527+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7c477b87","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128226,"end_time":"2026-08-30T12:09:22.966539+00:00","exception":false,"start_time":"2026-08-30T12:09:22.838313+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"4962b1e1","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132642,"end_time":"2026-08-30T12:09:23.23436+00:00","exception":false,"start_time":"2026-08-30T12:09:23.101718+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"421185db","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128716,"end_time":"2026-08-30T12:09:23.491853+00:00","exception":false,"start_time":"2026-08-30T12:09:23.363137+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ff9ae853","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.125196,"end_time":"2026-08-30T12:09:23.747053+00:00","exception":false,"start_time":"2026-08-30T12:09:23.621857+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"98edbcc7","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.1255,"end_time":"2026-08-30T12:09:23.99986+00:00","exception":false,"start_time":"2026-08-30T12:09:23.87436+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c334eae0","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126728,"end_time":"2026-08-30T12:09:24.251759+00:00","exception":false,"start_time":"2026-08-30T12:09:24.125031+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e620b1f2","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128923,"end_time":"2026-08-30T12:09:24.509999+00:00","exception":false,"start_time":"2026-08-30T12:09:24.381076+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"1b37b411","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127024,"end_time":"2026-08-30T12:09:24.765821+00:00","exception":false,"start_time":"2026-08-30T12:09:24.638797+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c4ff2fff","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127337,"end_time":"2026-08-30T12:09:25.020377+00:00","exception":false,"start_time":"2026-08-30T12:09:24.89304+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"173911de","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.210884,"end_time":"2026-08-30T12:09:25.357278+00:00","exception":false,"start_time":"2026-08-30T12:09:25.146394+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"39868903","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130628,"end_time":"2026-08-30T12:09:25.616631+00:00","exception":false,"start_time":"2026-08-30T12:09:25.486003+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f3e9210c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132324,"end_time":"2026-08-30T12:09:25.874783+00:00","exception":false,"start_time":"2026-08-30T12:09:25.742459+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0ca043f0","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.157593,"end_time":"2026-08-30T12:09:26.161913+00:00","exception":false,"start_time":"2026-08-30T12:09:26.00432+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"788ceb1c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129967,"end_time":"2026-08-30T12:09:26.42088+00:00","exception":false,"start_time":"2026-08-30T12:09:26.290913+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7046264e","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127847,"end_time":"2026-08-30T12:09:26.678985+00:00","exception":false,"start_time":"2026-08-30T12:09:26.551138+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0e045865","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130327,"end_time":"2026-08-30T12:09:26.940888+00:00","exception":false,"start_time":"2026-08-30T12:09:26.810561+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5e8069cf","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.137204,"end_time":"2026-08-30T12:09:27.208299+00:00","exception":false,"start_time":"2026-08-30T12:09:27.071095+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f3767d72","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.225171,"end_time":"2026-08-30T12:09:27.563695+00:00","exception":false,"start_time":"2026-08-30T12:09:27.338524+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7e2ac6ea","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127908,"end_time":"2026-08-30T12:09:27.82027+00:00","exception":false,"start_time":"2026-08-30T12:09:27.692362+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5b5927a6","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128144,"end_time":"2026-08-30T12:09:28.078597+00:00","exception":false,"start_time":"2026-08-30T12:09:27.950453+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"8c6afd61","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126359,"end_time":"2026-08-30T12:09:28.333772+00:00","exception":false,"start_time":"2026-08-30T12:09:28.207413+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c9a4656e","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131132,"end_time":"2026-08-30T12:09:28.594187+00:00","exception":false,"start_time":"2026-08-30T12:09:28.463055+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2d590b88","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131825,"end_time":"2026-08-30T12:09:28.852461+00:00","exception":false,"start_time":"2026-08-30T12:09:28.720636+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5d6dc78b","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127274,"end_time":"2026-08-30T12:09:29.106779+00:00","exception":false,"start_time":"2026-08-30T12:09:28.979505+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"9c1236aa","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126091,"end_time":"2026-08-30T12:09:29.359888+00:00","exception":false,"start_time":"2026-08-30T12:09:29.233797+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"31c7c8e7","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132222,"end_time":"2026-08-30T12:09:29.623879+00:00","exception":false,"start_time":"2026-08-30T12:09:29.491657+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0c240f29","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.14482,"end_time":"2026-08-30T12:09:29.902958+00:00","exception":false,"start_time":"2026-08-30T12:09:29.758138+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e9e64b12","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129995,"end_time":"2026-08-30T12:09:30.164503+00:00","exception":false,"start_time":"2026-08-30T12:09:30.034508+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"809bca2e","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.134012,"end_time":"2026-08-30T12:09:30.518609+00:00","exception":false,"start_time":"2026-08-30T12:09:30.384597+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"059b3b04","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126615,"end_time":"2026-08-30T12:09:30.776056+00:00","exception":false,"start_time":"2026-08-30T12:09:30.649441+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7b84bb80","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129486,"end_time":"2026-08-30T12:09:31.034261+00:00","exception":false,"start_time":"2026-08-30T12:09:30.904775+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"93fcf187","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130315,"end_time":"2026-08-30T12:09:31.294038+00:00","exception":false,"start_time":"2026-08-30T12:09:31.163723+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e302347b","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.132197,"end_time":"2026-08-30T12:09:31.555553+00:00","exception":false,"start_time":"2026-08-30T12:09:31.423356+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5b5240ba","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126445,"end_time":"2026-08-30T12:09:31.81449+00:00","exception":false,"start_time":"2026-08-30T12:09:31.688045+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ea330612","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128491,"end_time":"2026-08-30T12:09:32.069938+00:00","exception":false,"start_time":"2026-08-30T12:09:31.941447+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"b09a1597","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127096,"end_time":"2026-08-30T12:09:32.325607+00:00","exception":false,"start_time":"2026-08-30T12:09:32.198511+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"01df2460","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.131485,"end_time":"2026-08-30T12:09:32.673022+00:00","exception":false,"start_time":"2026-08-30T12:09:32.541537+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"529185b6","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126424,"end_time":"2026-08-30T12:09:32.927086+00:00","exception":false,"start_time":"2026-08-30T12:09:32.800662+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"cf204a6e","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129358,"end_time":"2026-08-30T12:09:33.196554+00:00","exception":false,"start_time":"2026-08-30T12:09:33.067196+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"22646385","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128952,"end_time":"2026-08-30T12:09:33.451517+00:00","exception":false,"start_time":"2026-08-30T12:09:33.322565+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"4d1d8d31","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.126749,"end_time":"2026-08-30T12:09:33.712964+00:00","exception":false,"start_time":"2026-08-30T12:09:33.586215+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"dcdec8e1","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130372,"end_time":"2026-08-30T12:09:33.975192+00:00","exception":false,"start_time":"2026-08-30T12:09:33.84482+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"8c14ab53","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127885,"end_time":"2026-08-30T12:09:34.230686+00:00","exception":false,"start_time":"2026-08-30T12:09:34.102801+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e8ac7f63","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.133513,"end_time":"2026-08-30T12:09:34.493891+00:00","exception":false,"start_time":"2026-08-30T12:09:34.360378+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"074d65ba","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127047,"end_time":"2026-08-30T12:09:34.751848+00:00","exception":false,"start_time":"2026-08-30T12:09:34.624801+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"8989cfd5","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.127805,"end_time":"2026-08-30T12:09:35.007664+00:00","exception":false,"start_time":"2026-08-30T12:09:34.879859+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"180605c9","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.211467,"end_time":"2026-08-30T12:09:35.345841+00:00","exception":false,"start_time":"2026-08-30T12:09:35.134374+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e0a3b6cc","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128707,"end_time":"2026-08-30T12:09:35.602045+00:00","exception":false,"start_time":"2026-08-30T12:09:35.473338+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c78da7a7","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.135672,"end_time":"2026-08-30T12:09:35.863905+00:00","exception":false,"start_time":"2026-08-30T12:09:35.728233+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"1d7700ef","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.162381,"end_time":"2026-08-30T12:09:36.155753+00:00","exception":false,"start_time":"2026-08-30T12:09:35.993372+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"85d9592c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129069,"end_time":"2026-08-30T12:09:36.413577+00:00","exception":false,"start_time":"2026-08-30T12:09:36.284508+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"36b941b0","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.128845,"end_time":"2026-08-30T12:09:36.673843+00:00","exception":false,"start_time":"2026-08-30T12:09:36.544998+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"09beb13b","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130522,"end_time":"2026-08-30T12:09:36.931148+00:00","exception":false,"start_time":"2026-08-30T12:09:36.800626+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f689c96c","cell_type":"code","source":"","metadata":{"papermill":{"duration":0.129509,"end_time":"2026-08-30T12:09:37.18815+00:00","exception":false,"start_time":"2026-08-30T12:09:37.058641+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}