From d625d56188ce561a9ea5c3b69d45262cfdee1dbf Mon Sep 17 00:00:00 2001 From: BLADIER Tatiana <tatiana.bladier@lis-lab.fr> Date: Thu, 15 May 2025 14:46:30 +0200 Subject: [PATCH] add tree depth calculation --- .../tania-some-other-metrics-checkpoint.ipynb | 178 +++- .../transform-checkpoint.py | 459 ++++++++++ .../__pycache__/transform.cpython-311.pyc | Bin 0 -> 24881 bytes .../.ipynb_checkpoints/__init__-checkpoint.py | 106 +++ .../.ipynb_checkpoints/parser-checkpoint.py | 620 ++++++++++++++ tania_scripts/supar/__init__.py | 106 +++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3404 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 5116 bytes .../supar/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3349 bytes .../supar/__pycache__/model.cpython-310.pyc | Bin 0 -> 6512 bytes .../supar/__pycache__/model.cpython-311.pyc | Bin 0 -> 14276 bytes .../supar/__pycache__/parser.cpython-310.pyc | Bin 0 -> 20095 bytes .../supar/__pycache__/parser.cpython-311.pyc | Bin 0 -> 38217 bytes .../vector_quantize.cpython-310.pyc | Bin 0 -> 3635 bytes tania_scripts/supar/cmds/__init__.py | 0 .../cmds/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 144 bytes .../cmds/__pycache__/run.cpython-310.pyc | Bin 0 -> 2736 bytes tania_scripts/supar/cmds/const/aj.py | 38 + tania_scripts/supar/cmds/const/crf.py | 39 + tania_scripts/supar/cmds/const/sl.py | 44 + tania_scripts/supar/cmds/const/tt.py | 41 + tania_scripts/supar/cmds/const/vi.py | 42 + .../dep/__pycache__/biaffine.cpython-310.pyc | Bin 0 -> 2259 bytes .../dep/__pycache__/eager.cpython-310.pyc | Bin 0 -> 2194 bytes .../cmds/dep/__pycache__/sl.cpython-310.pyc | Bin 0 -> 2281 bytes tania_scripts/supar/cmds/dep/biaffine.py | 45 + tania_scripts/supar/cmds/dep/crf.py | 46 + tania_scripts/supar/cmds/dep/crf2o.py | 46 + tania_scripts/supar/cmds/dep/eager.py | 44 + tania_scripts/supar/cmds/dep/sl.py | 46 + tania_scripts/supar/cmds/dep/vi.py | 46 + tania_scripts/supar/cmds/run.py | 65 ++ tania_scripts/supar/cmds/sdp/biaffine.py | 41 + tania_scripts/supar/cmds/sdp/vi.py | 42 + tania_scripts/supar/codelin/__init__.py | 34 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1419 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2143 bytes .../abstract_encoding.cpython-310.pyc | Bin 0 -> 1801 bytes .../abstract_encoding.cpython-311.pyc | Bin 0 -> 2197 bytes .../supar/codelin/encs/abstract_encoding.py | 37 + .../supar/codelin/encs/constituent.py | 115 +++ .../supar/codelin/encs/dependency.py | 129 +++ .../supar/codelin/encs/enc_const/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 423 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 515 bytes .../naive_absolute.cpython-310.pyc | Bin 0 -> 3375 bytes .../naive_absolute.cpython-311.pyc | Bin 0 -> 6958 bytes .../__pycache__/naive_dynamic.cpython-310.pyc | Bin 0 -> 3661 bytes .../__pycache__/naive_dynamic.cpython-311.pyc | Bin 0 -> 7604 bytes .../naive_incremental.cpython-310.pyc | Bin 0 -> 3908 bytes .../naive_incremental.cpython-311.pyc | Bin 0 -> 7608 bytes .../naive_relative.cpython-310.pyc | Bin 0 -> 3289 bytes .../naive_relative.cpython-311.pyc | Bin 0 -> 6884 bytes .../codelin/encs/enc_const/naive_absolute.py | 144 ++++ .../codelin/encs/enc_const/naive_dynamic.py | 166 ++++ .../encs/enc_const/naive_incremental.py | 160 ++++ .../codelin/encs/enc_const/naive_relative.py | 152 ++++ .../supar/codelin/encs/enc_deps/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 454 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 562 bytes .../__pycache__/brk2p_based.cpython-310.pyc | Bin 0 -> 4874 bytes .../__pycache__/brk2p_based.cpython-311.pyc | Bin 0 -> 9802 bytes .../__pycache__/brk_based.cpython-310.pyc | Bin 0 -> 2420 bytes .../__pycache__/brk_based.cpython-311.pyc | Bin 0 -> 4630 bytes .../naive_absolute.cpython-310.pyc | Bin 0 -> 1873 bytes .../naive_absolute.cpython-311.pyc | Bin 0 -> 3173 bytes .../naive_relative.cpython-310.pyc | Bin 0 -> 1960 bytes .../naive_relative.cpython-311.pyc | Bin 0 -> 3406 bytes .../__pycache__/pos_based.cpython-310.pyc | Bin 0 -> 2476 bytes .../__pycache__/pos_based.cpython-311.pyc | Bin 0 -> 4493 bytes .../codelin/encs/enc_deps/brk2p_based.py | 215 +++++ .../supar/codelin/encs/enc_deps/brk_based.py | 87 ++ .../codelin/encs/enc_deps/naive_absolute.py | 42 + .../codelin/encs/enc_deps/naive_relative.py | 48 ++ .../supar/codelin/encs/enc_deps/pos_based.py | 89 ++ .../supar/codelin/models/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 163 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 193 bytes .../__pycache__/const_label.cpython-310.pyc | Bin 0 -> 1556 bytes .../__pycache__/const_label.cpython-311.pyc | Bin 0 -> 2538 bytes .../__pycache__/const_tree.cpython-310.pyc | Bin 0 -> 12187 bytes .../__pycache__/const_tree.cpython-311.pyc | Bin 0 -> 21102 bytes .../__pycache__/deps_label.cpython-310.pyc | Bin 0 -> 973 bytes .../__pycache__/deps_label.cpython-311.pyc | Bin 0 -> 1396 bytes .../__pycache__/deps_tree.cpython-310.pyc | Bin 0 -> 13060 bytes .../__pycache__/deps_tree.cpython-311.pyc | Bin 0 -> 21064 bytes .../linearized_tree.cpython-310.pyc | Bin 0 -> 5132 bytes .../linearized_tree.cpython-311.pyc | Bin 0 -> 9798 bytes .../supar/codelin/models/const_label.py | 38 + .../supar/codelin/models/const_tree.py | 414 +++++++++ .../supar/codelin/models/deps_label.py | 18 + .../supar/codelin/models/deps_tree.py | 371 +++++++++ .../supar/codelin/models/linearized_tree.py | 179 ++++ tania_scripts/supar/codelin/utils/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 162 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 192 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 1112 bytes .../__pycache__/constants.cpython-311.pyc | Bin 0 -> 1260 bytes .../supar/codelin/utils/constants.py | 54 ++ .../supar/codelin/utils/extract_feats.py | 41 + tania_scripts/supar/model.py | 249 ++++++ .../.ipynb_checkpoints/__init__-checkpoint.py | 22 + tania_scripts/supar/models/__init__.py | 22 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 742 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1043 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 731 bytes tania_scripts/supar/models/const/__init__.py | 14 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 758 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 966 bytes .../const/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 653 bytes .../.ipynb_checkpoints/__init__-checkpoint.py | 6 + .../aj/.ipynb_checkpoints/model-checkpoint.py | 786 ++++++++++++++++++ .../.ipynb_checkpoints/parser-checkpoint.py | 534 ++++++++++++ .../transform-checkpoint.py | 459 ++++++++++ .../supar/models/const/aj/__init__.py | 6 + .../aj/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 415 bytes .../aj/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 515 bytes .../aj/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 308 bytes .../aj/__pycache__/model.cpython-310.pyc | Bin 0 -> 22080 bytes .../aj/__pycache__/model.cpython-311.pyc | Bin 0 -> 47523 bytes .../const/aj/__pycache__/model.cpython-39.pyc | Bin 0 -> 13878 bytes .../aj/__pycache__/parser.cpython-310.pyc | Bin 0 -> 14431 bytes .../aj/__pycache__/parser.cpython-311.pyc | Bin 0 -> 32140 bytes .../aj/__pycache__/transform.cpython-310.pyc | Bin 0 -> 17396 bytes .../aj/__pycache__/transform.cpython-311.pyc | Bin 0 -> 24903 bytes tania_scripts/supar/models/const/aj/model.py | 786 ++++++++++++++++++ tania_scripts/supar/models/const/aj/parser.py | 534 ++++++++++++ .../supar/models/const/aj/transform.py | 459 ++++++++++ .../supar/models/const/crf/__init__.py | 6 + .../crf/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 287 bytes .../crf/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 365 bytes .../crf/__pycache__/model.cpython-310.pyc | Bin 0 -> 9776 bytes .../crf/__pycache__/model.cpython-311.pyc | Bin 0 -> 12210 bytes .../crf/__pycache__/parser.cpython-310.pyc | Bin 0 -> 8295 bytes .../crf/__pycache__/parser.cpython-311.pyc | Bin 0 -> 15580 bytes .../crf/__pycache__/transform.cpython-310.pyc | Bin 0 -> 19620 bytes .../crf/__pycache__/transform.cpython-311.pyc | Bin 0 -> 26740 bytes tania_scripts/supar/models/const/crf/model.py | 221 +++++ .../supar/models/const/crf/parser.py | 205 +++++ .../supar/models/const/crf/transform.py | 494 +++++++++++ .../supar/models/const/sl/__init__.py | 4 + .../sl/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 282 bytes .../sl/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 358 bytes .../sl/__pycache__/model.cpython-310.pyc | Bin 0 -> 3360 bytes .../sl/__pycache__/model.cpython-311.pyc | Bin 0 -> 5671 bytes .../sl/__pycache__/parser.cpython-310.pyc | Bin 0 -> 8808 bytes .../sl/__pycache__/parser.cpython-311.pyc | Bin 0 -> 18487 bytes .../sl/__pycache__/transform.cpython-310.pyc | Bin 0 -> 3612 bytes .../sl/__pycache__/transform.cpython-311.pyc | Bin 0 -> 6748 bytes tania_scripts/supar/models/const/sl/model.py | 102 +++ tania_scripts/supar/models/const/sl/parser.py | 219 +++++ .../supar/models/const/sl/transform.py | 94 +++ .../supar/models/const/tt/__init__.py | 6 + .../tt/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 304 bytes .../tt/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 382 bytes .../tt/__pycache__/model.cpython-310.pyc | Bin 0 -> 10462 bytes .../tt/__pycache__/model.cpython-311.pyc | Bin 0 -> 15368 bytes .../tt/__pycache__/parser.cpython-310.pyc | Bin 0 -> 8248 bytes .../tt/__pycache__/parser.cpython-311.pyc | Bin 0 -> 15371 bytes .../tt/__pycache__/transform.cpython-310.pyc | Bin 0 -> 11481 bytes .../tt/__pycache__/transform.cpython-311.pyc | Bin 0 -> 17156 bytes tania_scripts/supar/models/const/tt/model.py | 265 ++++++ tania_scripts/supar/models/const/tt/parser.py | 205 +++++ .../supar/models/const/tt/transform.py | 301 +++++++ .../supar/models/const/vi/__init__.py | 6 + .../vi/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 284 bytes .../vi/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 362 bytes .../vi/__pycache__/model.cpython-310.pyc | Bin 0 -> 10359 bytes .../vi/__pycache__/model.cpython-311.pyc | Bin 0 -> 13244 bytes .../vi/__pycache__/parser.cpython-310.pyc | Bin 0 -> 4769 bytes .../vi/__pycache__/parser.cpython-311.pyc | Bin 0 -> 8761 bytes tania_scripts/supar/models/const/vi/model.py | 237 ++++++ tania_scripts/supar/models/const/vi/parser.py | 108 +++ tania_scripts/supar/models/dep/__init__.py | 15 + .../dep/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 723 bytes .../dep/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 902 bytes .../supar/models/dep/biaffine/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 305 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 374 bytes .../__pycache__/model.cpython-310.pyc | Bin 0 -> 10021 bytes .../__pycache__/model.cpython-311.pyc | Bin 0 -> 12885 bytes .../__pycache__/parser.cpython-310.pyc | Bin 0 -> 8024 bytes .../__pycache__/parser.cpython-311.pyc | Bin 0 -> 14692 bytes .../__pycache__/transform.cpython-310.pyc | Bin 0 -> 16984 bytes .../__pycache__/transform.cpython-311.pyc | Bin 0 -> 24798 bytes .../supar/models/dep/biaffine/model.py | 234 ++++++ .../supar/models/dep/biaffine/parser.py | 213 +++++ .../supar/models/dep/biaffine/transform.py | 379 +++++++++ .../supar/models/dep/crf/__init__.py | 6 + .../crf/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 290 bytes .../crf/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 359 bytes .../dep/crf/__pycache__/model.cpython-310.pyc | Bin 0 -> 6656 bytes .../dep/crf/__pycache__/model.cpython-311.pyc | Bin 0 -> 7412 bytes .../crf/__pycache__/parser.cpython-310.pyc | Bin 0 -> 4987 bytes .../crf/__pycache__/parser.cpython-311.pyc | Bin 0 -> 8854 bytes tania_scripts/supar/models/dep/crf/model.py | 134 +++ tania_scripts/supar/models/dep/crf/parser.py | 131 +++ .../supar/models/dep/crf2o/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 296 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 365 bytes .../crf2o/__pycache__/model.cpython-310.pyc | Bin 0 -> 11378 bytes .../crf2o/__pycache__/model.cpython-311.pyc | Bin 0 -> 15100 bytes .../crf2o/__pycache__/parser.cpython-310.pyc | Bin 0 -> 8249 bytes .../crf2o/__pycache__/parser.cpython-311.pyc | Bin 0 -> 15194 bytes tania_scripts/supar/models/dep/crf2o/model.py | 263 ++++++ .../supar/models/dep/crf2o/parser.py | 216 +++++ .../supar/models/dep/eager/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 273 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 333 bytes .../eager/__pycache__/model.cpython-310.pyc | Bin 0 -> 6877 bytes .../eager/__pycache__/model.cpython-311.pyc | Bin 0 -> 11595 bytes .../eager/__pycache__/parser.cpython-310.pyc | Bin 0 -> 14058 bytes .../eager/__pycache__/parser.cpython-311.pyc | Bin 0 -> 29283 bytes .../__pycache__/transform.cpython-310.pyc | Bin 0 -> 7792 bytes .../__pycache__/transform.cpython-311.pyc | Bin 0 -> 13871 bytes tania_scripts/supar/models/dep/eager/model.py | 198 +++++ .../supar/models/dep/eager/oracle/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 172 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 202 bytes .../__pycache__/arceager.cpython-310.pyc | Bin 0 -> 7330 bytes .../__pycache__/arceager.cpython-311.pyc | Bin 0 -> 15872 bytes .../oracle/__pycache__/buffer.cpython-310.pyc | Bin 0 -> 1286 bytes .../oracle/__pycache__/buffer.cpython-311.pyc | Bin 0 -> 1846 bytes .../__pycache__/dependency.cpython-310.pyc | Bin 0 -> 1544 bytes .../__pycache__/dependency.cpython-311.pyc | Bin 0 -> 2377 bytes .../oracle/__pycache__/node.cpython-310.pyc | Bin 0 -> 2800 bytes .../oracle/__pycache__/node.cpython-311.pyc | Bin 0 -> 5581 bytes .../oracle/__pycache__/stack.cpython-310.pyc | Bin 0 -> 1180 bytes .../oracle/__pycache__/stack.cpython-311.pyc | Bin 0 -> 1703 bytes .../supar/models/dep/eager/oracle/arceager.py | 219 +++++ .../supar/models/dep/eager/oracle/buffer.py | 24 + .../models/dep/eager/oracle/dependency.py | 30 + .../supar/models/dep/eager/oracle/node.py | 74 ++ .../supar/models/dep/eager/oracle/stack.py | 24 + .../supar/models/dep/eager/parser.py | 380 +++++++++ .../supar/models/dep/eager/transform.py | 176 ++++ tania_scripts/supar/models/dep/sl/__init__.py | 2 + .../sl/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 258 bytes .../sl/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 318 bytes .../dep/sl/__pycache__/model.cpython-310.pyc | Bin 0 -> 5672 bytes .../dep/sl/__pycache__/model.cpython-311.pyc | Bin 0 -> 9943 bytes .../dep/sl/__pycache__/parser.cpython-310.pyc | Bin 0 -> 12083 bytes .../dep/sl/__pycache__/parser.cpython-311.pyc | Bin 0 -> 25291 bytes .../sl/__pycache__/transform.cpython-310.pyc | Bin 0 -> 3766 bytes .../sl/__pycache__/transform.cpython-311.pyc | Bin 0 -> 7098 bytes tania_scripts/supar/models/dep/sl/model.py | 154 ++++ tania_scripts/supar/models/dep/sl/parser.py | 323 +++++++ .../supar/models/dep/sl/transform.py | 102 +++ tania_scripts/supar/models/dep/vi/__init__.py | 6 + .../vi/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 287 bytes .../vi/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 356 bytes .../dep/vi/__pycache__/model.cpython-310.pyc | Bin 0 -> 10828 bytes .../dep/vi/__pycache__/model.cpython-311.pyc | Bin 0 -> 14278 bytes .../dep/vi/__pycache__/parser.cpython-310.pyc | Bin 0 -> 4732 bytes .../dep/vi/__pycache__/parser.cpython-311.pyc | Bin 0 -> 8333 bytes tania_scripts/supar/models/dep/vi/model.py | 253 ++++++ tania_scripts/supar/models/dep/vi/parser.py | 124 +++ tania_scripts/supar/models/sdp/__init__.py | 7 + .../sdp/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 396 bytes .../sdp/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 487 bytes .../supar/models/sdp/biaffine/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 321 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 390 bytes .../__pycache__/model.cpython-310.pyc | Bin 0 -> 9519 bytes .../__pycache__/model.cpython-311.pyc | Bin 0 -> 11764 bytes .../__pycache__/parser.cpython-310.pyc | Bin 0 -> 8024 bytes .../__pycache__/parser.cpython-311.pyc | Bin 0 -> 14949 bytes .../supar/models/sdp/biaffine/model.py | 222 +++++ .../supar/models/sdp/biaffine/parser.py | 202 +++++ tania_scripts/supar/models/sdp/vi/__init__.py | 6 + .../vi/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 303 bytes .../vi/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 372 bytes .../sdp/vi/__pycache__/model.cpython-310.pyc | Bin 0 -> 19591 bytes .../sdp/vi/__pycache__/model.cpython-311.pyc | Bin 0 -> 24854 bytes .../sdp/vi/__pycache__/parser.cpython-310.pyc | Bin 0 -> 4845 bytes .../sdp/vi/__pycache__/parser.cpython-311.pyc | Bin 0 -> 8540 bytes tania_scripts/supar/models/sdp/vi/model.py | 471 +++++++++++ tania_scripts/supar/models/sdp/vi/parser.py | 114 +++ tania_scripts/supar/modules/__init__.py | 20 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 795 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1028 bytes .../__pycache__/affine.cpython-310.pyc | Bin 0 -> 8011 bytes .../__pycache__/affine.cpython-311.pyc | Bin 0 -> 12963 bytes .../__pycache__/decoder.cpython-310.pyc | Bin 0 -> 1746 bytes .../__pycache__/decoder.cpython-311.pyc | Bin 0 -> 2997 bytes .../__pycache__/dropout.cpython-310.pyc | Bin 0 -> 6173 bytes .../__pycache__/dropout.cpython-311.pyc | Bin 0 -> 8710 bytes .../modules/__pycache__/gnn.cpython-310.pyc | Bin 0 -> 5471 bytes .../modules/__pycache__/gnn.cpython-311.pyc | Bin 0 -> 7820 bytes .../modules/__pycache__/lstm.cpython-310.pyc | Bin 0 -> 10155 bytes .../modules/__pycache__/lstm.cpython-311.pyc | Bin 0 -> 16394 bytes .../modules/__pycache__/mlp.cpython-310.pyc | Bin 0 -> 2397 bytes .../modules/__pycache__/mlp.cpython-311.pyc | Bin 0 -> 3517 bytes .../__pycache__/pretrained.cpython-310.pyc | Bin 0 -> 10694 bytes .../__pycache__/pretrained.cpython-311.pyc | Bin 0 -> 16517 bytes .../__pycache__/transformer.cpython-310.pyc | Bin 0 -> 17309 bytes .../__pycache__/transformer.cpython-311.pyc | Bin 0 -> 36701 bytes tania_scripts/supar/modules/affine.py | 260 ++++++ tania_scripts/supar/modules/decoder.py | 38 + tania_scripts/supar/modules/dropout.py | 155 ++++ tania_scripts/supar/modules/gnn.py | 135 +++ tania_scripts/supar/modules/lstm.py | 271 ++++++ tania_scripts/supar/modules/mlp.py | 62 ++ tania_scripts/supar/modules/pretrained.py | 256 ++++++ tania_scripts/supar/modules/transformer.py | 585 +++++++++++++ tania_scripts/supar/parser.py | 620 ++++++++++++++ tania_scripts/supar/structs/__init__.py | 23 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 703 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 946 bytes .../structs/__pycache__/chain.cpython-310.pyc | Bin 0 -> 9988 bytes .../structs/__pycache__/chain.cpython-311.pyc | Bin 0 -> 17390 bytes .../structs/__pycache__/dist.cpython-310.pyc | Bin 0 -> 5710 bytes .../structs/__pycache__/dist.cpython-311.pyc | Bin 0 -> 7995 bytes .../structs/__pycache__/fn.cpython-310.pyc | Bin 0 -> 11869 bytes .../structs/__pycache__/fn.cpython-311.pyc | Bin 0 -> 21496 bytes .../__pycache__/semiring.cpython-310.pyc | Bin 0 -> 17503 bytes .../__pycache__/semiring.cpython-311.pyc | Bin 0 -> 33629 bytes .../structs/__pycache__/tree.cpython-310.pyc | Bin 0 -> 26754 bytes .../structs/__pycache__/tree.cpython-311.pyc | Bin 0 -> 52834 bytes .../structs/__pycache__/vi.cpython-310.pyc | Bin 0 -> 13833 bytes .../structs/__pycache__/vi.cpython-311.pyc | Bin 0 -> 28892 bytes tania_scripts/supar/structs/chain.py | 208 +++++ tania_scripts/supar/structs/dist.py | 138 +++ tania_scripts/supar/structs/fn.py | 379 +++++++++ tania_scripts/supar/structs/semiring.py | 406 +++++++++ tania_scripts/supar/structs/tree.py | 635 ++++++++++++++ tania_scripts/supar/structs/vi.py | 499 +++++++++++ tania_scripts/supar/utils/__init__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 590 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 781 bytes .../utils/__pycache__/common.cpython-310.pyc | Bin 0 -> 358 bytes .../utils/__pycache__/common.cpython-311.pyc | Bin 0 -> 496 bytes .../utils/__pycache__/config.cpython-310.pyc | Bin 0 -> 4218 bytes .../utils/__pycache__/config.cpython-311.pyc | Bin 0 -> 7268 bytes .../utils/__pycache__/data.cpython-310.pyc | Bin 0 -> 15054 bytes .../utils/__pycache__/data.cpython-311.pyc | Bin 0 -> 25699 bytes .../utils/__pycache__/embed.cpython-310.pyc | Bin 0 -> 13204 bytes .../utils/__pycache__/embed.cpython-311.pyc | Bin 0 -> 19798 bytes .../utils/__pycache__/field.cpython-310.pyc | Bin 0 -> 16475 bytes .../utils/__pycache__/field.cpython-311.pyc | Bin 0 -> 24575 bytes .../utils/__pycache__/fn.cpython-310.pyc | Bin 0 -> 13456 bytes .../utils/__pycache__/fn.cpython-311.pyc | Bin 0 -> 26506 bytes .../utils/__pycache__/logging.cpython-310.pyc | Bin 0 -> 3238 bytes .../utils/__pycache__/logging.cpython-311.pyc | Bin 0 -> 5351 bytes .../utils/__pycache__/metric.cpython-310.pyc | Bin 0 -> 10873 bytes .../utils/__pycache__/metric.cpython-311.pyc | Bin 0 -> 20588 bytes .../utils/__pycache__/optim.cpython-310.pyc | Bin 0 -> 2798 bytes .../utils/__pycache__/optim.cpython-311.pyc | Bin 0 -> 4195 bytes .../__pycache__/parallel.cpython-310.pyc | Bin 0 -> 2976 bytes .../__pycache__/parallel.cpython-311.pyc | Bin 0 -> 5035 bytes .../__pycache__/tokenizer.cpython-310.pyc | Bin 0 -> 9291 bytes .../__pycache__/tokenizer.cpython-311.pyc | Bin 0 -> 15768 bytes .../__pycache__/transform.cpython-310.pyc | Bin 0 -> 9574 bytes .../__pycache__/transform.cpython-311.pyc | Bin 0 -> 15399 bytes .../utils/__pycache__/vocab.cpython-310.pyc | Bin 0 -> 4122 bytes .../utils/__pycache__/vocab.cpython-311.pyc | Bin 0 -> 6223 bytes tania_scripts/supar/utils/common.py | 14 + tania_scripts/supar/utils/config.py | 85 ++ tania_scripts/supar/utils/data.py | 344 ++++++++ tania_scripts/supar/utils/embed.py | 334 ++++++++ tania_scripts/supar/utils/field.py | 415 +++++++++ tania_scripts/supar/utils/fn.py | 383 +++++++++ tania_scripts/supar/utils/logging.py | 100 +++ tania_scripts/supar/utils/metric.py | 346 ++++++++ tania_scripts/supar/utils/optim.py | 55 ++ tania_scripts/supar/utils/parallel.py | 80 ++ tania_scripts/supar/utils/tokenizer.py | 220 +++++ tania_scripts/supar/utils/transform.py | 219 +++++ tania_scripts/supar/utils/vocab.py | 77 ++ tania_scripts/supar/vector_quantize.py | 130 +++ tania_scripts/tania-some-other-metrics.ipynb | 178 +++- tania_scripts/transform.py | 459 ++++++++++ 372 files changed, 23775 insertions(+), 80 deletions(-) create mode 100644 tania_scripts/.ipynb_checkpoints/transform-checkpoint.py create mode 100644 tania_scripts/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py create mode 100644 tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py create mode 100644 tania_scripts/supar/__init__.py create mode 100644 tania_scripts/supar/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/__pycache__/__init__.cpython-39.pyc create mode 100644 tania_scripts/supar/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/__pycache__/vector_quantize.cpython-310.pyc create mode 100644 tania_scripts/supar/cmds/__init__.py create mode 100644 tania_scripts/supar/cmds/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/cmds/__pycache__/run.cpython-310.pyc create mode 100644 tania_scripts/supar/cmds/const/aj.py create mode 100644 tania_scripts/supar/cmds/const/crf.py create mode 100644 tania_scripts/supar/cmds/const/sl.py create mode 100644 tania_scripts/supar/cmds/const/tt.py create mode 100644 tania_scripts/supar/cmds/const/vi.py create mode 100644 tania_scripts/supar/cmds/dep/__pycache__/biaffine.cpython-310.pyc create mode 100644 tania_scripts/supar/cmds/dep/__pycache__/eager.cpython-310.pyc create mode 100644 tania_scripts/supar/cmds/dep/__pycache__/sl.cpython-310.pyc create mode 100644 tania_scripts/supar/cmds/dep/biaffine.py create mode 100644 tania_scripts/supar/cmds/dep/crf.py create mode 100644 tania_scripts/supar/cmds/dep/crf2o.py create mode 100644 tania_scripts/supar/cmds/dep/eager.py create mode 100644 tania_scripts/supar/cmds/dep/sl.py create mode 100644 tania_scripts/supar/cmds/dep/vi.py create mode 100644 tania_scripts/supar/cmds/run.py create mode 100644 tania_scripts/supar/cmds/sdp/biaffine.py create mode 100644 tania_scripts/supar/cmds/sdp/vi.py create mode 100644 tania_scripts/supar/codelin/__init__.py create mode 100644 tania_scripts/supar/codelin/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/abstract_encoding.py create mode 100644 tania_scripts/supar/codelin/encs/constituent.py create mode 100644 tania_scripts/supar/codelin/encs/dependency.py create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__init__.py create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_relative.py create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__init__.py create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/brk_based.py create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/pos_based.py create mode 100644 tania_scripts/supar/codelin/models/__init__.py create mode 100644 tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/models/const_label.py create mode 100644 tania_scripts/supar/codelin/models/const_tree.py create mode 100644 tania_scripts/supar/codelin/models/deps_label.py create mode 100644 tania_scripts/supar/codelin/models/deps_tree.py create mode 100644 tania_scripts/supar/codelin/models/linearized_tree.py create mode 100644 tania_scripts/supar/codelin/utils/__init__.py create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-310.pyc create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-311.pyc create mode 100644 tania_scripts/supar/codelin/utils/constants.py create mode 100644 tania_scripts/supar/codelin/utils/extract_feats.py create mode 100644 tania_scripts/supar/model.py create mode 100644 tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py create mode 100644 tania_scripts/supar/models/__init__.py create mode 100644 tania_scripts/supar/models/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/__pycache__/__init__.cpython-39.pyc create mode 100644 tania_scripts/supar/models/const/__init__.py create mode 100644 tania_scripts/supar/models/const/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/__pycache__/__init__.cpython-39.pyc create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py create mode 100644 tania_scripts/supar/models/const/aj/__init__.py create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-39.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/model.cpython-39.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/aj/model.py create mode 100644 tania_scripts/supar/models/const/aj/parser.py create mode 100644 tania_scripts/supar/models/const/aj/transform.py create mode 100644 tania_scripts/supar/models/const/crf/__init__.py create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/crf/model.py create mode 100644 tania_scripts/supar/models/const/crf/parser.py create mode 100644 tania_scripts/supar/models/const/crf/transform.py create mode 100644 tania_scripts/supar/models/const/sl/__init__.py create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/sl/model.py create mode 100644 tania_scripts/supar/models/const/sl/parser.py create mode 100644 tania_scripts/supar/models/const/sl/transform.py create mode 100644 tania_scripts/supar/models/const/tt/__init__.py create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/tt/model.py create mode 100644 tania_scripts/supar/models/const/tt/parser.py create mode 100644 tania_scripts/supar/models/const/tt/transform.py create mode 100644 tania_scripts/supar/models/const/vi/__init__.py create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/const/vi/model.py create mode 100644 tania_scripts/supar/models/const/vi/parser.py create mode 100644 tania_scripts/supar/models/dep/__init__.py create mode 100644 tania_scripts/supar/models/dep/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__init__.py create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/biaffine/model.py create mode 100644 tania_scripts/supar/models/dep/biaffine/parser.py create mode 100644 tania_scripts/supar/models/dep/biaffine/transform.py create mode 100644 tania_scripts/supar/models/dep/crf/__init__.py create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/crf/model.py create mode 100644 tania_scripts/supar/models/dep/crf/parser.py create mode 100644 tania_scripts/supar/models/dep/crf2o/__init__.py create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/crf2o/model.py create mode 100644 tania_scripts/supar/models/dep/crf2o/parser.py create mode 100644 tania_scripts/supar/models/dep/eager/__init__.py create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/model.py create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__init__.py create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/eager/oracle/arceager.py create mode 100644 tania_scripts/supar/models/dep/eager/oracle/buffer.py create mode 100644 tania_scripts/supar/models/dep/eager/oracle/dependency.py create mode 100644 tania_scripts/supar/models/dep/eager/oracle/node.py create mode 100644 tania_scripts/supar/models/dep/eager/oracle/stack.py create mode 100644 tania_scripts/supar/models/dep/eager/parser.py create mode 100644 tania_scripts/supar/models/dep/eager/transform.py create mode 100644 tania_scripts/supar/models/dep/sl/__init__.py create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/sl/model.py create mode 100644 tania_scripts/supar/models/dep/sl/parser.py create mode 100644 tania_scripts/supar/models/dep/sl/transform.py create mode 100644 tania_scripts/supar/models/dep/vi/__init__.py create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/dep/vi/model.py create mode 100644 tania_scripts/supar/models/dep/vi/parser.py create mode 100644 tania_scripts/supar/models/sdp/__init__.py create mode 100644 tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/__init__.py create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/biaffine/model.py create mode 100644 tania_scripts/supar/models/sdp/biaffine/parser.py create mode 100644 tania_scripts/supar/models/sdp/vi/__init__.py create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-310.pyc create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-311.pyc create mode 100644 tania_scripts/supar/models/sdp/vi/model.py create mode 100644 tania_scripts/supar/models/sdp/vi/parser.py create mode 100644 tania_scripts/supar/modules/__init__.py create mode 100644 tania_scripts/supar/modules/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/affine.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/affine.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/decoder.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/decoder.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/dropout.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/dropout.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/gnn.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/gnn.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/lstm.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/lstm.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/mlp.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/mlp.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/pretrained.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/pretrained.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/transformer.cpython-310.pyc create mode 100644 tania_scripts/supar/modules/__pycache__/transformer.cpython-311.pyc create mode 100644 tania_scripts/supar/modules/affine.py create mode 100644 tania_scripts/supar/modules/decoder.py create mode 100644 tania_scripts/supar/modules/dropout.py create mode 100644 tania_scripts/supar/modules/gnn.py create mode 100644 tania_scripts/supar/modules/lstm.py create mode 100644 tania_scripts/supar/modules/mlp.py create mode 100644 tania_scripts/supar/modules/pretrained.py create mode 100644 tania_scripts/supar/modules/transformer.py create mode 100644 tania_scripts/supar/parser.py create mode 100644 tania_scripts/supar/structs/__init__.py create mode 100644 tania_scripts/supar/structs/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/chain.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/chain.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/dist.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/dist.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/fn.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/fn.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/semiring.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/semiring.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/tree.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/tree.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/vi.cpython-310.pyc create mode 100644 tania_scripts/supar/structs/__pycache__/vi.cpython-311.pyc create mode 100644 tania_scripts/supar/structs/chain.py create mode 100644 tania_scripts/supar/structs/dist.py create mode 100644 tania_scripts/supar/structs/fn.py create mode 100644 tania_scripts/supar/structs/semiring.py create mode 100644 tania_scripts/supar/structs/tree.py create mode 100644 tania_scripts/supar/structs/vi.py create mode 100644 tania_scripts/supar/utils/__init__.py create mode 100644 tania_scripts/supar/utils/__pycache__/__init__.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/__init__.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/common.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/common.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/config.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/config.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/data.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/data.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/embed.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/embed.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/field.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/field.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/fn.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/fn.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/logging.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/logging.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/metric.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/metric.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/optim.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/optim.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/parallel.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/parallel.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/tokenizer.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/tokenizer.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/transform.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/transform.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/vocab.cpython-310.pyc create mode 100644 tania_scripts/supar/utils/__pycache__/vocab.cpython-311.pyc create mode 100644 tania_scripts/supar/utils/common.py create mode 100644 tania_scripts/supar/utils/config.py create mode 100644 tania_scripts/supar/utils/data.py create mode 100644 tania_scripts/supar/utils/embed.py create mode 100644 tania_scripts/supar/utils/field.py create mode 100644 tania_scripts/supar/utils/fn.py create mode 100644 tania_scripts/supar/utils/logging.py create mode 100644 tania_scripts/supar/utils/metric.py create mode 100644 tania_scripts/supar/utils/optim.py create mode 100644 tania_scripts/supar/utils/parallel.py create mode 100644 tania_scripts/supar/utils/tokenizer.py create mode 100644 tania_scripts/supar/utils/transform.py create mode 100644 tania_scripts/supar/utils/vocab.py create mode 100644 tania_scripts/supar/vector_quantize.py create mode 100644 tania_scripts/transform.py diff --git a/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb b/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb index e23180b..ceb6052 100644 --- a/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb +++ b/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb @@ -88,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "2a882cc9-8f9d-4457-becb-d2e26ab3f14f", "metadata": {}, "outputs": [ @@ -107,7 +107,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "8897dcc3-4218-4ee5-9984-17b9a6d8dce2", "metadata": {}, "outputs": [], @@ -163,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "1363f307-fa4b-43ba-93d5-2d1c11ceb9e4", "metadata": {}, "outputs": [ @@ -184,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "1362e192-514a-4a77-a8cb-5c012026e2bb", "metadata": {}, "outputs": [], @@ -238,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "544ff6aa-4104-4580-a01f-97429ffcc228", "metadata": {}, "outputs": [ @@ -328,7 +328,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "b9052dc2-ce45-4af4-a0a0-46c60a13da12", "metadata": {}, "outputs": [], @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "1e9dd0fb-db6a-47d1-8bfb-1015845f6d3e", "metadata": {}, "outputs": [ @@ -398,7 +398,7 @@ "{'Flesch-Douma': 88.68, 'LIX': 11.55, 'Kandel-Moles': 5.86}" ] }, - "execution_count": 11, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -421,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "24bc84a5-b2df-4194-838a-8f24302599bd", "metadata": {}, "outputs": [], @@ -467,7 +467,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "0cdb972f-31b6-4e7e-82a8-371eda344f2c", "metadata": {}, "outputs": [ @@ -477,7 +477,7 @@ "{'Average Word Length': 3.79, 'Average Sentence Length': 7.0}" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -521,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "id": "56af520c-d56b-404a-aebf-ad7c2a9ca503", "metadata": {}, "outputs": [], @@ -567,7 +567,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "f7c8b125-4651-4b21-bcc4-93ef78a4239b", "metadata": {}, "outputs": [ @@ -603,7 +603,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 15, "id": "daa17c33-adca-4695-90eb-741579382939", "metadata": {}, "outputs": [], @@ -622,7 +622,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 16, "id": "80d8fa08-6b7d-4ab7-85cd-987823639277", "metadata": {}, "outputs": [ @@ -665,7 +665,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 18, "id": "3f9c7dc7-6820-4013-a85c-2af4f846d4f5", "metadata": {}, "outputs": [ @@ -693,7 +693,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "65e1a630-c46e-4b18-9831-b97864de53ee", "metadata": {}, "outputs": [], @@ -713,7 +713,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "1612e911-12a8-47c9-b811-b2d6885c3647", "metadata": {}, "outputs": [ @@ -742,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "925a3a75-aaaa-4851-b77b-b42cb1e21e11", "metadata": {}, "outputs": [], @@ -757,7 +757,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "6fa60897-ad26-43b4-b8de-861290ca6bd3", "metadata": {}, "outputs": [ @@ -783,25 +783,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 23, "id": "f3678462-e572-4ce5-8d3d-a5389b2356c8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Defaulting to user installation because normal site-packages is not writeable\n", - "Collecting scipy\n", - " Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)\n", - "Requirement already satisfied: numpy<2.5,>=1.23.5 in /public/conda/Miniconda/envs/pytorch-2.6/lib/python3.11/site-packages (from scipy) (2.2.4)\n", - "Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (37.7 MB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m37.7/37.7 MB\u001b[0m \u001b[31m75.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", - "\u001b[?25hInstalling collected packages: scipy\n", - "Successfully installed scipy-1.15.3\n" - ] - } - ], + "outputs": [], "source": [ "#!pip3 install seaborn\n", "#!pip3 install scipy" @@ -809,7 +794,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 24, "id": "b621b2a8-488f-44db-b085-fe156f453943", "metadata": {}, "outputs": [ @@ -830,7 +815,7 @@ "import matplotlib.pyplot as plt\n", "from scipy.stats import spearmanr\n", "\n", - "# Sample data (replace with your real values)\n", + "# Sample data (to be replaces with real values)\n", "data = {\n", " \"perplexity\": [32.5, 45.2, 28.1, 39.0, 50.3],\n", " \"avg_word_length\": [4.1, 4.3, 4.0, 4.2, 4.5],\n", @@ -853,10 +838,123 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "id": "45ee04fc-acab-4bba-ba06-e4cf4bca9fe5", + "metadata": {}, + "source": [ + "## Tree depth" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "79f99787-c220-4f1d-93a9-59230363ec3f", + "metadata": {}, + "outputs": [], + "source": [ + "def parse_sentence_block(text):\n", + " lines = text.strip().split('\\n')\n", + " result = []\n", + " tokenlist = []\n", + " for line in lines:\n", + " # Split the line by tab and strip whitespace\n", + " parts = tuple(line.strip().split('\\t'))\n", + " # Only include lines that have exactly 4 parts\n", + " if len(parts) == 4:\n", + " parentidx = int(parts[3])\n", + " if '@@' in parts[2]:\n", + " nonterm1 = parts[2].split('@@')[0]\n", + " nonterm2 = parts[2].split('@@')[1]\n", + " else:\n", + " nonterm1 = parts[2]\n", + " nonterm2 = '<nul>'\n", + " postag = parts[1]\n", + " token = parts[0]\n", + " result.append((parentidx, nonterm1, nonterm2, postag))\n", + " tokenlist.append(token)\n", + " return result, tokenlist\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "f567efb0-8b0b-4782-9345-052cf1785776", + "metadata": {}, + "outputs": [], + "source": [ + "example_sentence = \"\"\"\n", + "<s>\t<s>\t<s>\t1\n", + "--\tponct\t<nul>@@<nul>\t1\n", + "Eh\tnpp\t<nul>@@<nul>\t1\n", + "bien?\tadv\tAP@@<nul>\t1\n", + "fit\tv\tVN@@<nul>\t2\n", + "-il\tcls-suj\tVN@@VPinf-OBJ\t3\n", + ".\tponct\t<nul>@@<nul>\t4\n", + "</s>\t</s>\t</s>\t4\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "8d4ecba9-89b8-4000-a061-aa16aa68a404", + "metadata": {}, + "outputs": [], + "source": [ + "from transform import *\n", + "\n", + "def visualize_const_prediction(example_sent):\n", + " parsed, tokenlist = parse_sentence_block(example_sent)\n", + " tree = AttachJuxtaposeTree.totree(tokenlist, 'SENT')\n", + " AttachJuxtaposeTree.action2tree(tree, parsed).pretty_print()\n", + " nltk_tree = AttachJuxtaposeTree.action2tree(tree, parsed)\n", + " #print(\"NLTK TREE\", nltk_tree)\n", + " depth = nltk_tree.height() - 1 # NLTK includes the leaf level as height 1, so subtract 1 for tree depth \n", + " print(\"Tree depth:\", depth)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "bfd3abf3-b83a-4817-85ad-654daf72be88", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " SENT \n", + " | \n", + " <s> \n", + " | \n", + " <s> \n", + " ______________|__________ \n", + " | | | AP \n", + " | | | __________|________ \n", + " | | | | VPinf-OBJ \n", + " | | | | ______________|_______ \n", + " | | | | | VN \n", + " | | | | | ________________|____ \n", + " | | | | VN | | </s>\n", + " | | | | | | | | \n", + " | ponct npp adv v cls-suj ponct </s>\n", + " | | | | | | | | \n", + "<s> -- Eh bien? fit -il . </s>\n", + "\n", + "Tree depth: 8\n" + ] + } + ], + "source": [ + "visualize_const_prediction(example_sentence)" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "3a6e3b53-7104-45ef-a4b5-e831bdd6ca6f", + "id": "bc51ab44-6885-45cc-bad2-6a43a7791fdb", "metadata": {}, "outputs": [], "source": [] diff --git a/tania_scripts/.ipynb_checkpoints/transform-checkpoint.py b/tania_scripts/.ipynb_checkpoints/transform-checkpoint.py new file mode 100644 index 0000000..56e0f51 --- /dev/null +++ b/tania_scripts/.ipynb_checkpoints/transform-checkpoint.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union + +import nltk +import torch + +from supar.models.const.crf.transform import Tree +from supar.utils.common import NUL +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class AttachJuxtaposeTree(Tree): + r""" + :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class, + supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`. + + Attributes: + WORD: + Words in the sentence. + POS: + Part-of-speech tags, or underscores if not available. + TREE: + The raw constituency tree in :class:`nltk.tree.Tree` format. + NODE: + The target node on each rightmost chain. + PARENT: + The label of the parent node of each terminal. + NEW: + The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children. + ``NUL`` represents the `Attach` action. + """ + + fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW'] + + def __init__( + self, + WORD: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + TREE: Optional[Union[Field, Iterable[Field]]] = None, + NODE: Optional[Union[Field, Iterable[Field]]] = None, + PARENT: Optional[Union[Field, Iterable[Field]]] = None, + NEW: Optional[Union[Field, Iterable[Field]]] = None + ) -> Tree: + super().__init__() + + self.WORD = WORD + self.POS = POS + self.TREE = TREE + self.NODE = NODE + self.PARENT = PARENT + self.NEW = NEW + + @property + def src(self): + return self.WORD, self.POS, self.TREE + + @property + def tgt(self): + return self.NODE, self.PARENT, self.NEW + + @classmethod + def tree2action(cls, tree: nltk.Tree): + r""" + Converts a constituency tree into AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + A constituency tree in :class:`nltk.tree.Tree` format. + + Returns: + A sequence of AttachJuxtapose actions. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ Arthur)) + (VP + (_ is) + (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons))))) + (_ .))) + ''') + >>> tree.pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + >>> AttachJuxtaposeTree.tree2action(tree) + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')] + """ + + def isroot(node): + return node == tree[0] + + def isterminal(node): + return len(node) == 1 and not isinstance(node[0], nltk.Tree) + + def last_leaf(node): + pos = () + while True: + pos += (len(node) - 1,) + node = node[-1] + if isterminal(node): + return node, pos + + def parent(position): + return tree[position[:-1]] + + def grand(position): + return tree[position[:-2]] + + def detach(tree): + last, last_pos = last_leaf(tree) + siblings = parent(last_pos)[:-1] + + if len(siblings) > 0: + last_subtree = last + last_subtree_siblings = siblings + parent_label = NUL + else: + last_subtree, last_pos = parent(last_pos), last_pos[:-1] + last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1] + parent_label = last_subtree.label() + + target_pos, new_label, last_tree = 0, NUL, tree + if isroot(last_subtree): + last_tree = None + + elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]): + new_label = parent(last_pos).label() + new_label = new_label + target = last_subtree_siblings[0] + last_grand = grand(last_pos) + if last_grand is None: + last_tree = targetistermina + else: + last_grand[-1] = target + target_pos = len(last_pos) - 2 + else: + target = parent(last_pos) + target.pop() + target_pos = len(last_pos) - 2 + action = target_pos, parent_label, new_label + return action, last_tree + if tree is None: + return [] + action, last_tree = detach(tree) + return cls.tree2action(last_tree) + [action] + + @classmethod + def action2tree( + cls, + tree: nltk.Tree, + actions: List[Tuple[int, str, str]], + join: str = '::', + ) -> nltk.Tree: + r""" + Recovers a constituency tree from a sequence of AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + An empty tree that provides a base for building a result tree. + actions (List[Tuple[int, str, str]]): + A sequence of AttachJuxtapose actions. + join (str): + A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains. + Default: ``'::'``. + + Returns: + A result constituency tree. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.action2tree(tree, + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')]).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + """ + + def target(node, depth): + node_pos = () + for _ in range(depth): + node_pos += (len(node) - 1,) + node = node[-1] + return node, node_pos + + def parent(tree, position): + return tree[position[:-1]] + + def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree: + target_pos, parent_label, new_label, post = action + #print(target_pos, parent_label, new_label) + new_leaf = nltk.Tree(post, [terminal[0]]) + + # create the subtree to be inserted + new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf]) + # find the target position at which to insert the new subtree + target_node = tree + if target_node is not None: + target_node, target_pos = target(target_node, target_pos) + + # Attach + if new_label == NUL: + # attach the first token + if target_node is None: + return new_subtree + target_node.append(new_subtree) + # Juxtapose + else: + new_subtree = nltk.Tree(new_label, [target_node, new_subtree]) + if len(target_pos) > 0: + parent_node = parent(tree, target_pos) + parent_node[-1] = new_subtree + else: + tree = new_subtree + return tree + + tree, root, terminals = None, tree.label(), tree.pos() + for terminal, action in zip(terminals, actions): + tree = execute(tree, terminal, action) + # recover unary chains + nodes = [tree] + while nodes: + node = nodes.pop() + if isinstance(node, nltk.Tree): + nodes.extend(node) + if join in node.label(): + labels = node.label().split(join) + node.set_label(labels[0]) + subtree = nltk.Tree(labels[-1], node) + for label in reversed(labels[1:-1]): + subtree = nltk.Tree(label, [subtree]) + node[:] = [subtree] + return nltk.Tree(root, [tree]) + + @classmethod + def action2span( + cls, + action: torch.Tensor, + spans: torch.Tensor = None, + nul_index: int = -1, + mask: torch.BoolTensor = None + ) -> torch.Tensor: + r""" + Converts a batch of the tensorized action at a given step into spans. + + Args: + action (~torch.Tensor): ``[3, batch_size]``. + A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels. + spans (~torch.Tensor): + Spans generated at previous steps, ``None`` at the first step. Default: ``None``. + nul_index (int): + The index for the obj:`NUL` token, representing the Attach action. Default: -1. + mask (~torch.BoolTensor): ``[batch_size]``. + The mask for covering the unpadded tokens. + + Returns: + A tensor representing a batch of spans for the given step. + + Examples: + >>> from collections import Counter + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab + >>> from supar.utils.common import NUL + >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL), + (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL), + (0, NUL, NUL)]) + >>> vocab = Vocab(Counter(sorted(set([*parents, *news])))) + >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1) + >>> spans = None + >>> for action in actions.unbind(-1): + ... spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL]) + ... + >>> spans + tensor([[[-1, 1, -1, -1, -1, -1, -1, 3], + [-1, -1, -1, -1, -1, -1, 4, -1], + [-1, -1, -1, 1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, 2, -1], + [-1, -1, -1, -1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1]]]) + >>> sequence = torch.where(spans.ge(0)) + >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]])) + >>> sequence + [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')] + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + + """ + + # [batch_size] + target, parent, new = action + if spans is None: + spans = action.new_full((action.shape[1], 2, 2), -1) + spans[:, 0, 1] = parent + return spans + if mask is None: + mask = torch.ones_like(target, dtype=bool) + juxtapose_mask = new.ne(nul_index) & mask + # ancestor nodes are those on the rightmost chain and higher than the target node + # [batch_size, seq_len] + rightmost_mask = spans[..., -1].ge(0) + ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1 + # should not include the target node for the Juxtapose action + ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1)) + target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1] + # the right boundaries of ancestor nodes should be aligned with the new generated terminals + spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1) + spans[..., -2].masked_fill_(ancestor_mask, -1) + spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask] + spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask] + # [batch_size, seq_len+1, seq_len+1] + spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1) + return spans + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ) -> List[AttachJuxtaposeTreeSentence]: + r""" + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + + Returns: + A list of :class:`AttachJuxtaposeTreeSentence` instances. + """ + + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + if data.endswith('.txt'): + data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1) + else: + data = open(data) + else: + if lang is not None: + data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + + index = 0 + for s in data: + + try: + tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root) + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + except ValueError: + logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!") + continue + except IndexError: + tree = nltk.Tree.fromstring('(S ' + s + ')') + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + else: + yield sentence + index += 1 + self.root = tree.label() + + +class AttachJuxtaposeTreeSentence(Sentence): + r""" + Args: + transform (AttachJuxtaposeTree): + A :class:`AttachJuxtaposeTree` object. + tree (nltk.tree.Tree): + A :class:`nltk.tree.Tree` object. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + """ + + def __init__( + self, + transform: AttachJuxtaposeTree, + tree: nltk.Tree, + index: Optional[int] = None + ) -> AttachJuxtaposeTreeSentence: + super().__init__(transform, index) + + words, tags = zip(*tree.pos()) + nodes, parents, news = None, None, None + if transform.training: + oracle_tree = tree.copy(True) + # the root node must have a unary chain + if len(oracle_tree) > 1: + oracle_tree[:] = [nltk.Tree('*', oracle_tree)] + oracle_tree.collapse_unary(joinChar='::') + if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree): + oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]]) + nodes, parents, news = zip(*transform.tree2action(oracle_tree)) + tags = [x.split("##")[0] for x in tags] + self.values = [words, tags, tree, nodes, parents, news] + + def __repr__(self): + return self.values[-4].pformat(1000000) + + def pretty_print(self): + self.values[-4].pretty_print() diff --git a/tania_scripts/__pycache__/transform.cpython-311.pyc b/tania_scripts/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0fa71196328a1158b12ae2fffe91d227ae067efc GIT binary patch literal 24881 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py b/tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py new file mode 100644 index 0000000..146f3df --- /dev/null +++ b/tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- + +from .models import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos, + BiaffineDependencyParser, + BiaffineSemanticDependencyParser, CRF2oDependencyParser, + CRFConstituencyParser, CRFDependencyParser, SLDependencyParser, ArcEagerDependencyParser, + TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser, + VIDependencyParser, VISemanticDependencyParser) +from .parser import Parser +from .structs import (BiLexicalizedConstituencyCRF, ConstituencyCRF, + ConstituencyLBP, ConstituencyMFVI, Dependency2oCRF, + DependencyCRF, DependencyLBP, DependencyMFVI, + LinearChainCRF, MatrixTree, SemanticDependencyLBP, + SemanticDependencyMFVI, SemiMarkovCRF) + + + +__all__ = ['Parser', + + # Dependency Parsing + 'BiaffineDependencyParser', + 'CRFDependencyParser', + 'CRF2oDependencyParser', + 'VIDependencyParser', + 'SLDependencyParser', + 'ArcEagerDependencyParser', + + # Constituent Parsing + 'AttachJuxtaposeConstituencyParser', + 'CRFConstituencyParser', + 'TetraTaggingConstituencyParser', + 'VIConstituencyParser', + 'SLConstituentParser', + + # Semantic Parsing + 'BiaffineSemanticDependencyParser', + 'VISemanticDependencyParser', + 'LinearChainCRF', + 'SemiMarkovCRF', + + # transforms + 'MatrixTree', + 'DependencyCRF', + 'Dependency2oCRF', + 'ConstituencyCRF', + 'BiLexicalizedConstituencyCRF', + 'DependencyLBP', + 'DependencyMFVI', + 'ConstituencyLBP', + 'ConstituencyMFVI', + 'SemanticDependencyLBP', + 'SemanticDependencyMFVI'] + +__version__ = '1.1.4' + +PARSER = {parser.NAME: parser for parser in [BiaffineDependencyParser, + CRFDependencyParser, + CRF2oDependencyParser, + VIDependencyParser, + SLDependencyParser, + ArcEagerDependencyParser, + AttachJuxtaposeConstituencyParser, + CRFConstituencyParser, + TetraTaggingConstituencyParser, + VIConstituencyParser, + SLConstituentParser, + BiaffineSemanticDependencyParser, + VISemanticDependencyParser]} + +SRC = {'github': 'https://github.com/yzhangcs/parser/releases/download', + 'hlt': 'http://hlt.suda.edu.cn/~yzhang/supar'} +NAME = { + 'biaffine-dep-en': 'ptb.biaffine.dep.lstm.char', + 'biaffine-dep-zh': 'ctb7.biaffine.dep.lstm.char', + 'crf2o-dep-en': 'ptb.crf2o.dep.lstm.char', + 'crf2o-dep-zh': 'ctb7.crf2o.dep.lstm.char', + 'biaffine-dep-roberta-en': 'ptb.biaffine.dep.roberta', + 'biaffine-dep-electra-zh': 'ctb7.biaffine.dep.electra', + 'biaffine-dep-xlmr': 'ud.biaffine.dep.xlmr', + 'crf-con-en': 'ptb.crf.con.lstm.char', + 'crf-con-zh': 'ctb7.crf.con.lstm.char', + 'crf-con-roberta-en': 'ptb.crf.con.roberta', + 'crf-con-electra-zh': 'ctb7.crf.con.electra', + 'crf-con-xlmr': 'spmrl.crf.con.xlmr', + 'biaffine-sdp-en': 'dm.biaffine.sdp.lstm.tag-char-lemma', + 'biaffine-sdp-zh': 'semeval16.biaffine.sdp.lstm.tag-char-lemma', + 'vi-sdp-en': 'dm.vi.sdp.lstm.tag-char-lemma', + 'vi-sdp-zh': 'semeval16.vi.sdp.lstm.tag-char-lemma', + 'vi-sdp-roberta-en': 'dm.vi.sdp.roberta', + 'vi-sdp-electra-zh': 'semeval16.vi.sdp.electra' +} +MODEL = {src: {n: f"{link}/v1.1.0/{m}.zip" for n, m in NAME.items()} for src, link in SRC.items()} +CONFIG = {src: {n: f"{link}/v1.1.0/{m}.ini" for n, m in NAME.items()} for src, link in SRC.items()} + + +def compatible(): + import sys + supar = sys.modules[__name__] + if supar.__version__ < '1.2': + sys.modules['supar.utils.transform'].CoNLL = supar.models.dep.biaffine.transform.CoNLL + sys.modules['supar.utils.transform'].Tree = supar.models.const.crf.transform.Tree + sys.modules['supar.parsers'] = supar.models + sys.modules['supar.parsers.con'] = supar.models.const + + +compatible() diff --git a/tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py b/tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py new file mode 100644 index 0000000..f1c372e --- /dev/null +++ b/tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py @@ -0,0 +1,620 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import contextlib +import os +import shutil +import sys +import tempfile +import pickle +from contextlib import contextmanager +from datetime import datetime, timedelta +from typing import Any, Iterable, Union + +import dill +import torch +import torch.distributed as dist +import torch.nn as nn +from torch.cuda.amp import GradScaler +from torch.optim import Adam, Optimizer +from torch.optim.lr_scheduler import ExponentialLR, _LRScheduler + +import supar +from supar.utils import Config, Dataset +from supar.utils.field import Field +from supar.utils.fn import download, get_rng_state, set_rng_state +from supar.utils.logging import get_logger, init_logger, progress_bar +from supar.utils.metric import Metric +from supar.utils.optim import InverseSquareRootLR, LinearLR +from supar.utils.parallel import DistributedDataParallel as DDP +from supar.utils.parallel import gather, is_dist, is_master, reduce +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class Parser(object): + + NAME = None + MODEL = None + + def __init__(self, args, model, transform): + self.args = args + self.model = model + self.transform = transform + + @property + def device(self): + return 'cuda' if torch.cuda.is_available() else 'cpu' + + @property + def sync_grad(self): + return self.step % self.args.update_steps == 0 or self.step % self.n_batches == 0 + + @contextmanager + def sync(self): + context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext') + if is_dist() and not self.sync_grad: + context = self.model.no_sync + with context(): + yield + + @contextmanager + def join(self): + context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext') + if not is_dist(): + with context(): + yield + elif self.model.training: + with self.model.join(): + yield + else: + try: + dist_model = self.model + # https://github.com/pytorch/pytorch/issues/54059 + if hasattr(self.model, 'module'): + self.model = self.model.module + yield + finally: + self.model = dist_model + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int, + patience: int, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + clip: float = 5.0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ) -> None: + r""" + Args: + train/dev/test (Union[str, Iterable]): + Filenames of the train/dev/test datasets. + epochs (int): + The number of training iterations. + patience (int): + The number of consecutive iterations after which the training process would be early stopped if no improvement. + batch_size (int): + The number of tokens in each batch. Default: 5000. + update_steps (int): + Gradient accumulation steps. Default: 1. + buckets (int): + The number of buckets that sentences are assigned to. Default: 32. + workers (int): + The number of subprocesses used for data loading. 0 means only the main process. Default: 0. + clip (float): + Clips gradient of an iterable of parameters at specified value. Default: 5.0. + amp (bool): + Specifies whether to use automatic mixed precision. Default: ``False``. + cache (bool): + If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``. + verbose (bool): + If ``True``, increases the output verbosity. Default: ``True``. + """ + + args = self.args.update(locals()) + init_logger(logger, verbose=args.verbose) + + self.transform.train() + batch_size = batch_size // update_steps + eval_batch_size = args.get('eval_batch_size', batch_size) + if is_dist(): + batch_size = batch_size // dist.get_world_size() + eval_batch_size = eval_batch_size // dist.get_world_size() + logger.info("Loading the data") + if args.cache: + args.bin = os.path.join(os.path.dirname(args.path), 'bin') + args.even = args.get('even', is_dist()) + + train = Dataset(self.transform, args.train, **args).build(batch_size=batch_size, + n_buckets=buckets, + shuffle=True, + distributed=is_dist(), + even=args.even, + n_workers=workers) + dev = Dataset(self.transform, args.dev, **args).build(batch_size=eval_batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + logger.info(f"{'train:':6} {train}") + if not args.test: + logger.info(f"{'dev:':6} {dev}\n") + else: + test = Dataset(self.transform, args.test, **args).build(batch_size=eval_batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + logger.info(f"{'dev:':6} {dev}") + logger.info(f"{'test:':6} {test}\n") + loader, sampler = train.loader, train.loader.batch_sampler + args.steps = len(loader) * epochs // args.update_steps + args.save(f"{args.path}.yaml") + + self.optimizer = self.init_optimizer() + self.scheduler = self.init_scheduler() + self.scaler = GradScaler(enabled=args.amp) + + if dist.is_initialized(): + self.model = DDP(module=self.model, + device_ids=[args.local_rank], + find_unused_parameters=args.get('find_unused_parameters', True), + static_graph=args.get('static_graph', False)) + if args.amp: + from torch.distributed.algorithms.ddp_comm_hooks.default_hooks import fp16_compress_hook + self.model.register_comm_hook(dist.group.WORLD, fp16_compress_hook) + if args.wandb and is_master(): + import wandb + # start a new wandb run to track this script + wandb.init(config=args.primitive_config, + project=args.get('project', self.NAME), + name=args.get('name', args.path), + resume=self.args.checkpoint) + self.step, self.epoch, self.best_e, self.patience = 1, 1, 1, patience + # uneven batches are excluded + self.n_batches = min(gather(len(loader))) if is_dist() else len(loader) + self.best_metric, self.elapsed = Metric(), timedelta() + if args.checkpoint: + try: + self.optimizer.load_state_dict(self.checkpoint_state_dict.pop('optimizer_state_dict')) + self.scheduler.load_state_dict(self.checkpoint_state_dict.pop('scheduler_state_dict')) + self.scaler.load_state_dict(self.checkpoint_state_dict.pop('scaler_state_dict')) + set_rng_state(self.checkpoint_state_dict.pop('rng_state')) + for k, v in self.checkpoint_state_dict.items(): + setattr(self, k, v) + sampler.set_epoch(self.epoch) + except AttributeError: + logger.warning("No checkpoint found. Try re-launching the training procedure instead") + + for epoch in range(self.epoch, args.epochs + 1): + start = datetime.now() + bar, metric = progress_bar(loader), Metric() + + logger.info(f"Epoch {epoch} / {args.epochs}:") + self.model.train() + with self.join(): + # we should reset `step` as the number of batches in different processes is not necessarily equal + self.step = 1 + for batch in bar: + with self.sync(): + with torch.autocast(self.device, enabled=args.amp): + loss = self.train_step(batch) + self.backward(loss) + if self.sync_grad: + self.clip_grad_norm_(self.model.parameters(), args.clip) + self.scaler.step(self.optimizer) + self.scaler.update() + self.scheduler.step() + self.optimizer.zero_grad(True) + + bar.set_postfix_str(f"lr: {self.scheduler.get_last_lr()[0]:.4e} - loss: {loss:.4f}") + # log metrics to wandb + if args.wandb and is_master(): + wandb.log({'lr': self.scheduler.get_last_lr()[0], 'loss': loss}) + self.step += 1 + logger.info(f"{bar.postfix}") + self.model.eval() + with self.join(), torch.autocast(self.device, enabled=args.amp): + metric = self.reduce(sum([self.eval_step(i) for i in progress_bar(dev.loader)], Metric())) + logger.info(f"{'dev:':5} {metric}") + if args.wandb and is_master(): + wandb.log({'dev': metric.values, 'epochs': epoch}) + if args.test: + test_metric = sum([self.eval_step(i) for i in progress_bar(test.loader)], Metric()) + logger.info(f"{'test:':5} {self.reduce(test_metric)}") + if args.wandb and is_master(): + wandb.log({'test': test_metric.values, 'epochs': epoch}) + + t = datetime.now() - start + self.epoch += 1 + self.patience -= 1 + self.elapsed += t + + if metric > self.best_metric: + self.best_e, self.patience, self.best_metric = epoch, patience, metric + if is_master(): + self.save_checkpoint(args.path) + logger.info(f"{t}s elapsed (saved)\n") + else: + logger.info(f"{t}s elapsed\n") + if self.patience < 1: + break + if is_dist(): + dist.barrier() + + best = self.load(**args) + # only allow the master device to save models + if is_master(): + best.save(args.path) + + logger.info(f"Epoch {self.best_e} saved") + logger.info(f"{'dev:':5} {self.best_metric}") + if args.test: + best.model.eval() + with best.join(): + test_metric = sum([best.eval_step(i) for i in progress_bar(test.loader)], Metric()) + logger.info(f"{'test:':5} {best.reduce(test_metric)}") + logger.info(f"{self.elapsed}s elapsed, {self.elapsed / epoch}s/epoch") + if args.wandb and is_master(): + wandb.finish() + + self.evaluate(data=args.test, batch_size=batch_size) + self.predict(args.test, batch_size=batch_size, buckets=buckets, workers=workers) + + with open(f'{self.args.folder}/status', 'w') as file: + file.write('finished') + + + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + r""" + Args: + data (Union[str, Iterable]): + The data for evaluation. Both a filename and a list of instances are allowed. + batch_size (int): + The number of tokens in each batch. Default: 5000. + buckets (int): + The number of buckets that sentences are assigned to. Default: 8. + workers (int): + The number of subprocesses used for data loading. 0 means only the main process. Default: 0. + amp (bool): + Specifies whether to use automatic mixed precision. Default: ``False``. + cache (bool): + If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``. + verbose (bool): + If ``True``, increases the output verbosity. Default: ``True``. + + Returns: + The evaluation results. + """ + + args = self.args.update(locals()) + init_logger(logger, verbose=args.verbose) + + self.transform.train() + logger.info("Loading the data") + if args.cache: + args.bin = os.path.join(os.path.dirname(args.path), 'bin') + if is_dist(): + batch_size = batch_size // dist.get_world_size() + data = Dataset(self.transform, **args) + data.build(batch_size=batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + logger.info(f"\n{data}") + + logger.info("Evaluating the data") + start = datetime.now() + self.model.eval() + with self.join(): + bar, metric = progress_bar(data.loader), Metric() + for batch in bar: + metric += self.eval_step(batch) + bar.set_postfix_str(metric) + metric = self.reduce(metric) + elapsed = datetime.now() - start + logger.info(f"{metric}") + logger.info(f"{elapsed}s elapsed, " + f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, " + f"{len(data)/elapsed.total_seconds():.2f} Sents/s") + os.makedirs(os.path.dirname(self.args.folder + '/metrics.pickle'), exist_ok=True) + with open(f'{self.args.folder}/metrics.pickle', 'wb') as file: + pickle.dump(obj=metric, file=file) + + return metric + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + r""" + Args: + data (Union[str, Iterable]): + The data for prediction. + - a filename. If ends with `.txt`, the parser will seek to make predictions line by line from plain texts. + - a list of instances. + pred (str): + If specified, the predicted results will be saved to the file. Default: ``None``. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + prob (bool): + If ``True``, outputs the probabilities. Default: ``False``. + batch_size (int): + The number of tokens in each batch. Default: 5000. + buckets (int): + The number of buckets that sentences are assigned to. Default: 8. + workers (int): + The number of subprocesses used for data loading. 0 means only the main process. Default: 0. + amp (bool): + Specifies whether to use automatic mixed precision. Default: ``False``. + cache (bool): + If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``. + verbose (bool): + If ``True``, increases the output verbosity. Default: ``True``. + + Returns: + A :class:`~supar.utils.Dataset` object containing all predictions if ``cache=False``, otherwise ``None``. + """ + + args = self.args.update(locals()) + init_logger(logger, verbose=args.verbose) + + if self.args.use_vq: + self.model.passes_remaining = 0 + self.model.vq.observe_steps_remaining = 0 + + self.transform.eval() + if args.prob: + self.transform.append(Field('probs')) + + #logger.info("Loading the data") + if args.cache: + args.bin = os.path.join(os.path.dirname(args.path), 'bin') + if is_dist(): + batch_size = batch_size // dist.get_world_size() + data = Dataset(self.transform, **args) + data.build(batch_size=batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + + #logger.info(f"\n{data}") + + #logger.info("Making predictions on the data") + start = datetime.now() + self.model.eval() + #with tempfile.TemporaryDirectory() as t: + # we have clustered the sentences by length here to speed up prediction, + # so the order of the yielded sentences can't be guaranteed + for batch in progress_bar(data.loader): + #batch, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict = self.pred_step(batch) + *predicted_values, = self.pred_step(batch) + #print('429 supar/parser.py ', batch.sentences) + #print(head_preds, deprel_preds, stack_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text) + #logger.info(f"Saving predicted results to {pred}") + # with open(pred, 'w') as f: + + + elapsed = datetime.now() - start + + #if is_dist(): + # dist.barrier() + #tdirs = gather(t) if is_dist() else (t,) + #if pred is not None and is_master(): + #logger.info(f"Saving predicted results to {pred}") + """with open(pred, 'w') as f: + # merge all predictions into one single file + if is_dist() or args.cache: + sentences = (os.path.join(i, s) for i in tdirs for s in os.listdir(i)) + for i in progress_bar(sorted(sentences, key=lambda x: int(os.path.basename(x)))): + with open(i) as s: + shutil.copyfileobj(s, f) + else: + for s in progress_bar(data): + f.write(str(s) + '\n')""" + # exit util all files have been merged + if is_dist(): + dist.barrier() + #logger.info(f"{elapsed}s elapsed, " + # f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, " + # f"{len(data)/elapsed.total_seconds():.2f} Sents/s") + + if not cache: + #return data, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict + return *predicted_values, + + def backward(self, loss: torch.Tensor, **kwargs): + loss /= self.args.update_steps + if hasattr(self, 'scaler'): + self.scaler.scale(loss).backward(**kwargs) + else: + loss.backward(**kwargs) + + def clip_grad_norm_( + self, + params: Union[Iterable[torch.Tensor], torch.Tensor], + max_norm: float, + norm_type: float = 2 + ) -> torch.Tensor: + self.scaler.unscale_(self.optimizer) + return nn.utils.clip_grad_norm_(params, max_norm, norm_type) + + def clip_grad_value_( + self, + params: Union[Iterable[torch.Tensor], torch.Tensor], + clip_value: float + ) -> None: + self.scaler.unscale_(self.optimizer) + return nn.utils.clip_grad_value_(params, clip_value) + + def reduce(self, obj: Any) -> Any: + if not is_dist(): + return obj + return reduce(obj) + + def train_step(self, batch: Batch) -> torch.Tensor: + ... + + @torch.no_grad() + def eval_step(self, batch: Batch) -> Metric: + ... + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + ... + + def init_optimizer(self) -> Optimizer: + if self.args.encoder in ('lstm', 'transformer'): + optimizer = Adam(params=self.model.parameters(), + lr=self.args.lr, + betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)), + eps=self.args.get('eps', 1e-8), + weight_decay=self.args.get('weight_decay', 0)) + else: + # we found that Huggingface's AdamW is more robust and empirically better than the native implementation + from transformers import AdamW + optimizer = AdamW(params=[{'params': p, 'lr': self.args.lr * (1 if n.startswith('encoder') else self.args.lr_rate)} + for n, p in self.model.named_parameters()], + lr=self.args.lr, + betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)), + eps=self.args.get('eps', 1e-8), + weight_decay=self.args.get('weight_decay', 0)) + return optimizer + + def init_scheduler(self) -> _LRScheduler: + if self.args.encoder == 'lstm': + scheduler = ExponentialLR(optimizer=self.optimizer, + gamma=self.args.decay**(1/self.args.decay_steps)) + elif self.args.encoder == 'transformer': + scheduler = InverseSquareRootLR(optimizer=self.optimizer, + warmup_steps=self.args.warmup_steps) + else: + scheduler = LinearLR(optimizer=self.optimizer, + warmup_steps=self.args.get('warmup_steps', int(self.args.steps*self.args.get('warmup', 0))), + steps=self.args.steps) + return scheduler + + @classmethod + def build(cls, path, **kwargs): + ... + + @classmethod + def load( + cls, + path: str, + reload: bool = True, + src: str = 'github', + checkpoint: bool = False, + **kwargs + ) -> Parser: + r""" + Loads a parser with data fields and pretrained model parameters. + + Args: + path (str): + - a string with the shortcut name of a pretrained model defined in ``supar.MODEL`` + to load from cache or download, e.g., ``'biaffine-dep-en'``. + - a local path to a pretrained model, e.g., ``./<path>/model``. + reload (bool): + Whether to discard the existing cache and force a fresh download. Default: ``False``. + src (str): + Specifies where to download the model. + ``'github'``: github release page. + ``'hlt'``: hlt homepage, only accessible from 9:00 to 18:00 (UTC+8). + Default: ``'github'``. + checkpoint (bool): + If ``True``, loads all checkpoint states to restore the training process. Default: ``False``. + + Examples: + >>> from supar import Parser + >>> parser = Parser.load('biaffine-dep-en') + >>> parser = Parser.load('./ptb.biaffine.dep.lstm.char') + """ + + args = Config(**locals()) + if not os.path.exists(path): + path = download(supar.MODEL[src].get(path, path), reload=reload) + state = torch.load(path, map_location='cpu', weights_only=False) + #torch.load(path, map_location='cpu') + cls = supar.PARSER[state['name']] if cls.NAME is None else cls + args = state['args'].update(args) + #print('ARGS', args) + model = cls.MODEL(**args) + model.load_pretrained(state['pretrained']) + model.load_state_dict(state['state_dict'], True) + transform = state['transform'] + parser = cls(args, model, transform) + parser.checkpoint_state_dict = state.get('checkpoint_state_dict', None) if checkpoint else None + parser.model.to(parser.device) + return parser + + def save(self, path: str) -> None: + model = self.model + if hasattr(model, 'module'): + model = self.model.module + state_dict = {k: v.cpu() for k, v in model.state_dict().items()} + pretrained = state_dict.pop('pretrained.weight', None) + state = {'name': self.NAME, + 'args': model.args, + 'state_dict': state_dict, + 'pretrained': pretrained, + 'transform': self.transform} + torch.save(state, path, pickle_module=dill) + + def save_checkpoint(self, path: str) -> None: + model = self.model + if hasattr(model, 'module'): + model = self.model.module + checkpoint_state_dict = {k: getattr(self, k) for k in ['epoch', 'best_e', 'patience', 'best_metric', 'elapsed']} + checkpoint_state_dict.update({'optimizer_state_dict': self.optimizer.state_dict(), + 'scheduler_state_dict': self.scheduler.state_dict(), + 'scaler_state_dict': self.scaler.state_dict(), + 'rng_state': get_rng_state()}) + state_dict = {k: v.cpu() for k, v in model.state_dict().items()} + pretrained = state_dict.pop('pretrained.weight', None) + state = {'name': self.NAME, + 'args': model.args, + 'state_dict': state_dict, + 'pretrained': pretrained, + 'checkpoint_state_dict': checkpoint_state_dict, + 'transform': self.transform} + torch.save(state, path, pickle_module=dill) diff --git a/tania_scripts/supar/__init__.py b/tania_scripts/supar/__init__.py new file mode 100644 index 0000000..146f3df --- /dev/null +++ b/tania_scripts/supar/__init__.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- + +from .models import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos, + BiaffineDependencyParser, + BiaffineSemanticDependencyParser, CRF2oDependencyParser, + CRFConstituencyParser, CRFDependencyParser, SLDependencyParser, ArcEagerDependencyParser, + TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser, + VIDependencyParser, VISemanticDependencyParser) +from .parser import Parser +from .structs import (BiLexicalizedConstituencyCRF, ConstituencyCRF, + ConstituencyLBP, ConstituencyMFVI, Dependency2oCRF, + DependencyCRF, DependencyLBP, DependencyMFVI, + LinearChainCRF, MatrixTree, SemanticDependencyLBP, + SemanticDependencyMFVI, SemiMarkovCRF) + + + +__all__ = ['Parser', + + # Dependency Parsing + 'BiaffineDependencyParser', + 'CRFDependencyParser', + 'CRF2oDependencyParser', + 'VIDependencyParser', + 'SLDependencyParser', + 'ArcEagerDependencyParser', + + # Constituent Parsing + 'AttachJuxtaposeConstituencyParser', + 'CRFConstituencyParser', + 'TetraTaggingConstituencyParser', + 'VIConstituencyParser', + 'SLConstituentParser', + + # Semantic Parsing + 'BiaffineSemanticDependencyParser', + 'VISemanticDependencyParser', + 'LinearChainCRF', + 'SemiMarkovCRF', + + # transforms + 'MatrixTree', + 'DependencyCRF', + 'Dependency2oCRF', + 'ConstituencyCRF', + 'BiLexicalizedConstituencyCRF', + 'DependencyLBP', + 'DependencyMFVI', + 'ConstituencyLBP', + 'ConstituencyMFVI', + 'SemanticDependencyLBP', + 'SemanticDependencyMFVI'] + +__version__ = '1.1.4' + +PARSER = {parser.NAME: parser for parser in [BiaffineDependencyParser, + CRFDependencyParser, + CRF2oDependencyParser, + VIDependencyParser, + SLDependencyParser, + ArcEagerDependencyParser, + AttachJuxtaposeConstituencyParser, + CRFConstituencyParser, + TetraTaggingConstituencyParser, + VIConstituencyParser, + SLConstituentParser, + BiaffineSemanticDependencyParser, + VISemanticDependencyParser]} + +SRC = {'github': 'https://github.com/yzhangcs/parser/releases/download', + 'hlt': 'http://hlt.suda.edu.cn/~yzhang/supar'} +NAME = { + 'biaffine-dep-en': 'ptb.biaffine.dep.lstm.char', + 'biaffine-dep-zh': 'ctb7.biaffine.dep.lstm.char', + 'crf2o-dep-en': 'ptb.crf2o.dep.lstm.char', + 'crf2o-dep-zh': 'ctb7.crf2o.dep.lstm.char', + 'biaffine-dep-roberta-en': 'ptb.biaffine.dep.roberta', + 'biaffine-dep-electra-zh': 'ctb7.biaffine.dep.electra', + 'biaffine-dep-xlmr': 'ud.biaffine.dep.xlmr', + 'crf-con-en': 'ptb.crf.con.lstm.char', + 'crf-con-zh': 'ctb7.crf.con.lstm.char', + 'crf-con-roberta-en': 'ptb.crf.con.roberta', + 'crf-con-electra-zh': 'ctb7.crf.con.electra', + 'crf-con-xlmr': 'spmrl.crf.con.xlmr', + 'biaffine-sdp-en': 'dm.biaffine.sdp.lstm.tag-char-lemma', + 'biaffine-sdp-zh': 'semeval16.biaffine.sdp.lstm.tag-char-lemma', + 'vi-sdp-en': 'dm.vi.sdp.lstm.tag-char-lemma', + 'vi-sdp-zh': 'semeval16.vi.sdp.lstm.tag-char-lemma', + 'vi-sdp-roberta-en': 'dm.vi.sdp.roberta', + 'vi-sdp-electra-zh': 'semeval16.vi.sdp.electra' +} +MODEL = {src: {n: f"{link}/v1.1.0/{m}.zip" for n, m in NAME.items()} for src, link in SRC.items()} +CONFIG = {src: {n: f"{link}/v1.1.0/{m}.ini" for n, m in NAME.items()} for src, link in SRC.items()} + + +def compatible(): + import sys + supar = sys.modules[__name__] + if supar.__version__ < '1.2': + sys.modules['supar.utils.transform'].CoNLL = supar.models.dep.biaffine.transform.CoNLL + sys.modules['supar.utils.transform'].Tree = supar.models.const.crf.transform.Tree + sys.modules['supar.parsers'] = supar.models + sys.modules['supar.parsers.con'] = supar.models.const + + +compatible() diff --git a/tania_scripts/supar/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5c3cf986e39a18d48492fcd3a44278864d4b01b GIT binary patch literal 3404 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56a7800cb9807c641e2b80be758fb03c3bf53e19 GIT binary patch literal 5116 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6cfcfd5b0e97b495425c09456acbce3e34f9f610 GIT binary patch literal 3349 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f9c7f70c814a90cca12c500a2fd2a58d1bca963 GIT binary patch literal 6512 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bda67fe0c4d0c1e433a13cbc03f01e01e490e0d9 GIT binary patch literal 14276 zcmZ3^%ge>Uz`&q*Uo}Htmx19ihy%l{P{!vu3=9m@8B!Qh7;_k+AT(nxQxp>;h|QG4 zoXZl$lFJ&!3g$ECu;sExvFCC`apZDFaprPGapiJHap&?x@#OMG@q*Q`<nZP4NAc$h zL<xZTtT}?YLQz6sHd~Hxu1J&!BLfqIJ3|V43quM=DpQsy)GZ9lm>C#WGsAdMVkwNl z44RxTK>~i7Ot(Y|5|gvz3ldXOQd8oKQwvK|^O93<2^S=$#Dipz1U1=jaX4or7Wo8+ z_}=1m_3_Pj%}q*8Ny*Ghza`|Emy%kLnwOHASK?BXUyxr~a*H=OBe5to1;!N#DN4*M zPRlRKO)Wxblt2;<&o4?r$nb|H7G)-uWaj53=76l!WV$7Uq}VktIX@+}=$1I9m``G5 zYLO=6EjH);ytK@8O~zY%VX4U_`9*=HiFqZNRjJ7!&%>}hl=1l%0|P@l!*qsJhA74q zhA5^KMlfVbVNPL5XG&pBVM}34VNYR8;Yi^~;Y{I5VNBsp;Ys05;Yi_2;Yi_6;ZNa6 z5lG=n;Y(pn5lj(E5l)j&5lLlE5lv-D5ldxGW9wi@V@wfm;f-QVQA&|$VT@u+k!)dz zVo#Au<;dcMx`QE&DMh-4C5kIWriCGjJ4Go)wuLc@Cq=G>A&NIezJ(!*4@12INPQ}Q zied}HG6n{Q)i9$Nq69h^Dj1^#gBdiHZ?XF3r=;fi-D1fpF3G*cT#}f6izPWDu_#lA zk%8f53IhYfOI-#Ah9V{g1_n*0kdSnUF%RrtvM?|(KzR%dw^(vh6Z72C<y&6|?vT4` z{}QA=lYxnWA>9}ZF5ABZrMFuGdGRT!;8=>!0YypiE#9Qel+2>kWJs*u;w&qSFGwsd zPAyJWgxCcpK^csjfq~(31{VXvRL1EHC5&KkFoEj71xPYrX)uARhLNEJmN6L^(86Z{ z$f008$V3S|F3{C4V`N}h4Y#v~As%jW4QmQxHYg+*CNLE}E8#_$m&Fca*Dz$k)n{>F z6@}ZphG`iS1H)>ti6E6V4Dq0F0Wld+%z^8uRYDO5g&-c)*<ha+@z>zcRmID|P^*-} zjAAAa*gysbhBAgCJ0koD4+Ruc_+X}B@gqM>4$WO~Jy3VCpqPm4uGA8ww1lEc5N<Yd zJP2VG6~-zGcLj>MB3RYJ3*a@Z%h(tgR<j{g#f!n&sG$!xAL>gs6nl_;NlfUA!)-zK zFWe3+p)Uc~f!|&1INjx6Vhl5b0X3aU!NgJYN@Eq3!73^X6J5ixjD>+=HK<eq3)L{h z%YhjT3=H6O1LtMIN_Pfmh;pLXjvS%|C5|vN&|D5rPbhkoV5(6>vHMaPt6CMTqN-R$ z5q{@d#?HX78mUZ)SA**S#TuN4?)MUZm^w87X~4wSaATBjaJiCTm?~%(BT6zYm`o8r zN?2&a#8Y^xm>3xHxUtKki0Z)fpoqe4KoJF1R$%38c$cv<Fsz2VsD>e44=lmJz)%to zW1;yPp&QfJaJdPLd8=z!Q~01IJ7W=ZNg@vO2$bh2E;odkfg)-I6J5iPk-p(&KT4?! z&ub{=z~c;Wd}hLIV_+!BMzB##GJ}buh{EF)MbsRtS_`bAmRLpMp}s}{y~ISSH?gM> zxSQ4pqBeL@(gM6bVqnO^9(D*f;7JvE3u{<YI3a1GXf{>K4Y>PJ!W4VC0Z%6=YDq6Q z5P5`3;Znnp1ve8>`XIY99^p^f8isf)csh_NQY|Tm@z8QALXTXHe2qei&>CTk{B8r& zo5B#xfRaaSVKS(#!WxEn6g`?Eenp_BfF{!|zP!@h_*7WmruY^woE@K%nOg*E8We%* zd`-4n?0NB^7IZO)0akU3BQHK9GbJT8?-pxbJg6JQ3F=B^=B1=o++t6Gc8yqbQgd?? zZ?UB2<mPL#6oD#&TkJ{s#qp{6#YLb3{1!)AW?pJZX<q6rmZa385>577EP08!sUYJa zZE2{cg8clP%)Im>Q0(90&dscdhuTpDDl;`1Z!s1WNrKw*thcx_^9o8!;)^q@Qg3lX z+z8=tf&2?K6;$&=T)<s|=&xzAfIL{1pPZOf1giILF&E?)gYATbK}Kp~3OEdMK|KtR z+RVJX)S_EFi6td@Fc;n8PD_Jxz;<Xd-(m&ZTLj8>MWC`G{bR=Cj;%kQ*lDufVou4- zy~PXaKqTeoXG7e|nv$BFSb0k@IX^cyvm`e)uOz-aH8VY<<Q8*kL9wRYE!N`Fg4Cj0 z9P#m)d6^~g@kOBa&Mmgmf|SIP)LU#h`N@en#kW`zi_(j4G3Djm;zaZ~+4JJd^NUi7 zAztJHu_4Le7EfM$K~ZW+QDSCZYRWB^wA93sTWoppC5h?9AUO~ps*<xLF&)Az0#!#v zptb`@2`H67#BcFJ(hMw_@PVZeiG&BthsNS9E-(+Cw7}`6_!c*qhL~3bYFOUl&WkU| zfu`D9JfL(H4^2-{9@Ic^vbe<sRsc2?oQ{e(LH#~ZJ_ET9l;B`JHXbksn#ykRL3oKN z@!$kqq|d;>aEl8p2r&%QEP>`1ShN>`IwD1&bOq`Vrb4>yFwYC*#lu9v38DBFKa3A` z@GW+zKoO{dEdtepMWAX4oceCDLq`{iKrOi<P%(CkA7LaUSt1EQQl$vg#CVj{DGU=u zN~O01Al=jWqSV~P%sfy=19ebtF_jhG;_ysK%`3?)snk@t#ZsJ_lUC#j3PfKJ0gCma zP!J0=)KKIDVuA8akvE9t2O<JML?DO=0ui9rRZ#?p6$v6hQBf2PVu6CVC<ere1reZJ zT@(&tf!Z}iNgx&|?-zj@(vVPQD=kiqFDonpH5rTSKrzHoRtV~eCsr0YfVgbg<>2Jc zo)-@;5^izE$0z3`78l3I7lVo-1;U`=my>=*er~FMNn%N6VqT(NQchw@W@?dsa(-?> zzHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xBL1K|UxRB5*s4Q}3U|^`?1CL7R!SXAp zU@hLj!ocvOf#ItcBLgR2CwmY3bq<M391<5fq^@vCUEq*<Dk3$}V~WRg|4IH!-4=Q* z@wh0WdqqUIgQbV_0k_bEv`gGF7rABb$|=mr*`cyW^NN-C4NKcSl2<IfJ}@)N`!IfF z0Fht7WQR+S{|7b(ap@_USH#pi+#m1@_f%ftS6v~pM)HcL)g^wb3;b3$1jJ{U%(1*8 zZFo_@a02@cevuh0b2#VlUEo){z^`^!QF)2Xj*vZ(S8RQ6*f{L*ykZmdftgV$1Z0s? z2;&z95PJg46ut+j<~-mRogp$ua*o^ue)S9d>UWj2HkfR&ykhKf!`K`|d)_dy*y4G` z#QTP!=@!W=hVC~^Ew@BoG4+MXf8b_S_GbLZ03yGD$q6h|_&@M42udKk_X8V)fcOlR zIhu3yF7Rty;McgTth&TzN6DVbEB1jm?40&wUa<@Lz|5!;26C}V7|6vcVT==4t_Ucg zIr#><ll3>GY{|T0=6%D$W)J5T3qLpw332Za?99r(j2{_5<QFgrb|MGFiS}2d4K4~8 zfPxe)D9m=a?D5>=cf-Nu2<H`t@Ef*{pzsa4Vebrbb?6O8*CUcw93yWyyC1Q<;v4~0 z7xaObO&JvKAo2?Xhy+{5hi2VfMPrD&eJ?2bT~zeDqUhJ*a)n3kuC&$-X(gy-As1vy zX1L7pydq<^gYlw_<pmkb3sG@bqLQyfmE4e)2c-wo10hEuueiqCkdT?fc}2qT11F1& z@ka(08RIV?qQj-f=PMV3iXkLkeJ&{bUR3tIqU;N@OyMGr!VO-L8N8QxRWI_Y-jy?h z#7F?tj{!HV?e|#jv4wgy<O4giJSc)d<QE1I2}-+PIT(~wmPoBgS(AB1&-H?$+eJmU zD~fI)3*_!f>s~eSz7P^|B_#GrNbU_NBM-*Ny%8CEB{JzsWciJVm@5&9S0YN`QXjZk zP4huX%QT<y3j>J#frr7uW=rK2^S~QsR-iZ!_`uID6U6wD0YrWQlVA@EFsP_4vD(10 zh4YGm=LKc2i^^VCl)XSMQn&!|GTS9yxeL5<cct|=glvi25(mwm0WgE%iO9+hlzm~j zDiEs9`vWhV3@A~7$S({a5^OOaZi{bd>aLNwqG{dX(&KrBN9}=vW(Ug^4%r*rf*%-I zI92Y7sX#Kk^M&Aq3mFAB%soz|d|+l22c;zt`Go;QcDVGocer=Be`RA3mz<J4F?UKX zOz1PHotX?DuVY|f0F6(8M%g}FFoLE7Y8V@*mw*&OaTa_WaRIU}s4N3R4I@Tx9Ap|; zzJ@UiWIC9g!U$^MftjcyE}(`1SQt9ir;j|2iZm)ol35s|lAvlCYzvCtKn)78=mJoU z4Q3$|H4IsxW&v0z3siT5S*ZSHWT;^XX3%8vdkG3CP2M7RP-W)<s=@fvit=-jn`B%_ z%`?{GjKqS}A~%p~P<?xg%_lQ2HL>Ux7r2cQUr>~vb&CbmI=sbJm0FZv9AD%GGL#L{ zkkn)<$^mg%!K#ZvQKO(xR0I;@&&dZ(i@;lgRico(3r)D6fq|j8kb!}rf#C+Xzy)YU zbY0HslAP5J(~EMBSL7T)Irj#?NKf?)!=AbYB1<H%D4Jj5H^0Ddepg9liRKE|HQqZI z*Z6_Tz$-RE7nOpqC<TKGvb#KdJ?{N}U4Ao6=GcR(BOaqGJVqCIjBfA?cW@UKGcYhD zgMtejo(v2OAT}t~d=>ytNg>Bk6XQxozm<%)g#GeMJaY?jQbDch)D+jEqWq$jjNm{h z25E<So;@wUs64SKrHU8gX()F(XrLaH1{xUd@+n^6Pz1Z-7GniURsbbMurm~xz*&JI z3+6xuL^dcEt6@YQs?P%H0IN$u%L-{s!JwoL&jK~b=7HMX5M4}F+zbraU{yuhH4F<t zt^ms*6X@A2hJ}HlmZ_GhmbsRxhM@vEb1+wlGcY7G#e+=*nUOasg|UVKkrk7fDwrT+ zDMi9~-2~FiP!yTR#K@2rMv}`|ATC1*Cs3;!Y+?;#4QOB-?!FoZ#56+{7r0vuiYl;L zP}rajmDDm4^sf|2Ze@hHwT5{CC)i3f0<}Y4%UZ)&!wQPol`MYXIVf<)wWySVfng;V zBs=GVav^I;eo=D9Ew+->yyE<#BG5P%q^%1|Q@2=hQi}?1u|eAHx7dpdOH)&;QZ?DY z>A9#KWB_CQEpABvF+L~1xcC-#MSLN2W-#RzYavLi7?e~X&0t8@=PE0Vho<-{0Z0Zw zh|B_IczH%}hKIBs<v%bma;n`B7MYqlC1-)*#QZ7w7lc(W@TflE=D)(Nu)t-B=M@$6 z9f}uKtS@ofT;R63p{%~#e3AJI!-ZB$tS<5>bU1btPSBoFc!Nja0*~Sq9>oQL7kShm z%nLk<H+cCbh+Gj=yTI#of!FC0m|UT<M)Qi6?E%J%T8<DAi0lPkryIJ4>%&)tZwOo& zwI=E!k5-5G48a-RD+KQfh)&^}VK^guh07Hk#{(`$yf5nbUkDDr5*&9?JMN-D{1t)t z4o4hrc!0~v0@Bw7lrIS=UldTiBB0vA`hZ_xf@()a2S2!IAij7iY6KPGO(3EL6v9Y_ z5eq1is<<E#0b+xuJd4^uO2I`SyyReDU;w2(5dX6a8@TLYtYt>72x}Np7*Q*=BKsOf z>=TPM3|XN10Gy5yr4wqkRm)PtxB#95!AhY7IB&vBrz}ts1IwV=Udvp=fTKacjAj!n z0e{5TFf4$V4PdLF1bUfQi#pK+FC%J@Cyqej2-XiB_++bLtziRCtFY#2mB6RF7?7&= z8rB+y1@P(}tQktwu%Y@TjVT3f!n2k&ouQT;Z2}V1!v~vC#!zHk!@dACxC7=R6EzGA zK)rNiAuzj!X#uDf1hbKe6c$vs;Nvkeq_Cod3b8JNPd*~sOeGhg#vZXQ0*!VeI|j_A zl8aC$2#IwOXk-=a3S@#xF5)07)<B~X$c_QCspFy&&=?QcJaD}XpAs&C51}(Kpq30p zxh3$4BL;>VcGPs5!UD~gvdB}gDX0^k@R*p*kis<=tvqRB#F2{`7QkHxbugH!Va1`I z9X&6j`U73ImLo5uhP9T1fbYO%Y7wrIhJ#qQU@2)hYH<0G12v3mIchk988o^5ia>J} zFaQ7l{~t0P0IC(ha{@)6$+sd<)E23OMz?elK!d{x3Yo<UdHE#@i8(p><*6wOCHV?T zsS2sN1tpa_3gsD@$r&IORV)g5`Q@5Yx7afhixW#qif%Ebr-C~tMWA`?Tim&c#o4JT z@oAYkIp7A-EzZ)sZ0J}l$VK3hYsesDH>jn<oSaxvR0XOPK|_$Y*b)msYqW|$6TzS% z{DPtokX#gqhyxK}AWdAE#hH1<C5d^-sYT#HMo<-Ui#aDX?-ox`X<kWYZYsEspveht zQ{7?(4U`w(Vg-4$_!ehsMG0gW{T2s^334*T3m^yH;sU9H4qVrPDs@n;0%>R|K)YE* zAn_`0NZk(ZgslT9+{6TKUx`R|a6aW0nqV?R<|4P+6>hZ;3{0G!j5ow(rdLd=SirJ` z|B8a$MREHp;`SXLHzZ`QOK4t_&|IOh!38vs=6+Ga<BEhwhvx@21~IAW@sr{gL|zot zzapyN!F3naR94O~#v78d^W|sBuMoW`seeUMzr*VWq<IHzz`+LxrDkMZ6wsK!HG%7? ztkRsw6<ix!w)=1LKj3xI#Q%zk{{{7c3qc_lWkavXhECwRAu8U%^?+Mog3A=oDSj8Y zl`e2A-QW?s&Lew?M|MWa{JdFtD?-;tu8Q1HxH4u<%tbk?D{@vBd91JSSYP0=zQHXx zA!JJAl(-Ar$``nmA0TPWpOwENb$#Zl%pHs?bJpZsl(W7fXMK^!<_eF^1s)qTjmS3A zOry|*lqs20@-A?zT;Ntgvhli{-X%G`6{YJdS5@v1Tv@ZG=AxX<6*-%WJhoSOY%lQG z-sKjZka9&#<Eoa;MQ+<G+_oPWI5_q0@(WF{>a6dnU!Zu2U-<&R@?9~d3(9F1g2Ju@ zMPCU@0I`+RE-0s66idG%mVQAX{jP}Q6wetc*X0Z@$r)^r+8eqj@<7#v;LwY<VOMO! zF3N>pkqf^N8GTVC=88y6hiixH0};6nSA;!+m-v+~@GISwke$Q1z;vzZ8qEz}2beBu zIbYFozM$lCAnBrn=M@Rh39L6nB(967T@q1SPzoK3cD=zb(!m31@`9S5;3AWOfdSO) z1Mxp+;OPp(){+%1MDFO-FkoM=R>N3>)_B6%1jX7>MlIy9cau|?&{Tm+1(=`UG-{VF zg*k-<btMD1aSLk4!*#$IHE5Ml3=;!GEpshP2~xwUhB<|~h7qw+GKC2-^0kH)wKEIT zpO=f$5r^BI!UnA_J!%+mHTLNd+Nf1yEpwhIPWPY<f`G#k`{){4SOzm_vO{LK!M*7a zH%-P{JSF)hi8=8(sd?!o8AT?bDPnGLol*pzvI3=0a6x>FDK8Z=*T!62ntO|_BtIv! zxTFYF85dQ6>I~2nlqM^<DkxeE5?BHvKppL(37~Qt)Zqaa@I~M;G&aaITNMwqd<V}5 zUIi)q3mq}z@3FkXEwg~_61Um~Zne7tDhooEM=grlz`CLIqN?o`Rofk<`zv-;oM1V_ zdBr38qJ7L2`<UzY376~>E+i&hv`@ZbpM2du>ymxeMf;p9_Bj{wiY}B?UKFUhB2d-g z_&`{Ey3Hh;1&kBzr`UJ8fV$ath1C`mu29(#x+nUC;GVb(!af&;eXa=mKx8`#Z}1BC zL|);QTcCT1SN{U9{tW?<={%EoW`xX-niaKzbw%k#S<@@BrW;DPS8S>{zyg}B2)<|@ za>YF4qCn^sfzS@e4#x*jJ)su`l&=UVcR1eQ7rxG~e2HIqf#XGfwJZE;7dX@)Wd%Hi z5*oe3(>-Q`th<E;GKBXK6fcM_GN{P{%Y5)MNeWMyMAP9pEusgOm>HnMa|8#gCQvju z7Xcoe3nj^2;K4cM5*vAx9o+o~<r{FQQ+;Sok|dWh*0R<z6FD%)R>N4s1{#<v>I5aB zE>Ky)4$1KFY+f`GBsB@teq_(gOUX=5EiRf2%GIE10-XI}t-C1<3=Eh<Xiq?DB`F(1 zQ&3sXzKDGV<3g?_To-v{L3w+EHjcq7QU}nq^wz7dQs1DsQfrOYMILp?02*b(XX@I^ z%NLceC|p>zr0OD%a))C_`3&wG=!0iBa1Wk=axkcz{_FxC+s9GQL06?0F@ZLIq%dJu zHJf2BQ!s-jv)?V|<bu*F*5uNZL@P}uaD{M-EhV)qGdZ;gZ4j<#3n(U`<v2vi7f>vM zmMAnZJm3bG<I*!qFF{&=!V(iq9|-G0rlqwn2<w6nk1n{-0~ckQLZDSUpjA%s@wd3* z<8$*<N^?@<<8SfAgT`lbpfb#vc_p`4lJfI&!0QK!>Ol#w6-0o$JZvGU;9+4<GAo(} z5(afAiq?Wy>p{trqo63iAhoEZ672q4ywJ4|$*DOx@$s6BMWBfr@VtiuxWXy|wLicF zXuPDjlM%c!p@9JcKX5Qe%HEKay&)xcLsI^RxXg^S3Hdi9Wp2nRf|0@vd8Hc)iZ|rs zZ^&tZM8u?S$Sd5CmA@gU0uq;!zac9JQlqGHLt5s6rq&I0od*)KH<VOCf>N?KlvO^s zGFCFOs(fGolV%Jm>L1L(ObZ4@)en|nrX7Q<!UuaW6QT?kS;ox9D)NB=l@MTLRr<gH zC)oH|C1$wJ@%g~O&nkgVD8ZG1HL$6&ihf`~CHxq<Sk*r;zzGR7EqpNJ`9Q{_5(*4# zd>@!tSoJ<Iu(0ZVWM*LFYl%PzfJG4mB<+AANK?EB9Qz#LxdFYrJn&@UEg=|Jue2mH zr&zBjFRuucV~Rk<@GV~OauhvCIxB{(*8<gqMW8YZvfK#NJB6${0!>%ml0?y=hqOWt zX#o;9L=o6V$m%okGVt~zP$~xRKZ-A?1Usw<G)#Gm%@>@|!D(zI1H@0DrqVAC8;H~F zijG3t0>w6r3=AKb85tQrurV<5Ht>Mp4F=H*sOScR#|3QY0}B(Q8{-ECx{z#)j1G(+ u7>FewFvwj%MIbL4UtlmoMjzPHnHlvyFkmM;oO(Pzg5|z|NlbO%&;<b3IqYNr literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..854f1c47cee59890cdb61da54ee728faf5093ffb GIT binary patch literal 20095 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 aC;(bi&LqId171Q7;`1;{fa)M75oQ3-{<lK_ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7dcf19a63a0a627a255230554792697d13dc2fb5 GIT binary patch literal 38217 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/__pycache__/vector_quantize.cpython-310.pyc b/tania_scripts/supar/__pycache__/vector_quantize.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..821f6b3037a8f6dcf6144badeb248d0ba76a3cf0 GIT binary patch literal 3635 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 BjdK71 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/cmds/__init__.py b/tania_scripts/supar/cmds/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tania_scripts/supar/cmds/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/cmds/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1abebfc6e576b314b0012bd5702c707a2e1f663 GIT binary patch literal 144 zcmd1j<>g{vU|`_PGe`%~k3j@7W@KPsaA06yC}v?`U`SyIX3%8xTggxa5=IcejP*0} zb5r$85=$}@^Ah!vauQQAQ;YO7^O6e^i}Z_2L1c1nO0j-?d}dx|NqoFsLFFwDo80`A R(wtN~kYUA43=9k`3;^29A2R>| literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/cmds/__pycache__/run.cpython-310.pyc b/tania_scripts/supar/cmds/__pycache__/run.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2391df2e6f812f40aa83be07b9bc14104795013a GIT binary patch literal 2736 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 F0svv=_vQcq literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/cmds/const/aj.py b/tania_scripts/supar/cmds/const/aj.py new file mode 100644 index 0000000..7952168 --- /dev/null +++ b/tania_scripts/supar/cmds/const/aj.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import AttachJuxtaposeConstituencyParser +from supar.cmds.run import init + +def main(): + parser = argparse.ArgumentParser(description='Create AttachJuxtapose Constituency Parser.') + parser.set_defaults(Parser=AttachJuxtaposeConstituencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file') + subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization') + subparser.add_argument('--delay', type=int, default=0) + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + subparser.add_argument('--pred', default='pred.pid', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/const/crf.py b/tania_scripts/supar/cmds/const/crf.py new file mode 100644 index 0000000..d380931 --- /dev/null +++ b/tania_scripts/supar/cmds/const/crf.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import CRFConstituencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create CRF Constituency Parser.') + parser.set_defaults(Parser=CRFConstituencyParser) + parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding') + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file') + subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + subparser.add_argument('--pred', default='pred.pid', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/const/sl.py b/tania_scripts/supar/cmds/const/sl.py new file mode 100644 index 0000000..97c9d47 --- /dev/null +++ b/tania_scripts/supar/cmds/const/sl.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import SLConstituentParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create SL Constituency Parser.') + parser.set_defaults(Parser=SLConstituentParser) + parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding') + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization') + subparser.add_argument('--max_len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file') + subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization') + subparser.add_argument('--decoder', choices=['mlp', 'lstm'], default='mlp', help='incremental decoder to use') + subparser.add_argument('--codes', choices=['abs', 'rel'], default=None, help='sequential encoding used') + subparser.add_argument('--delay', type=int, default=0) + subparser.add_argument('--root_node', type=str, default='S') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + subparser.add_argument('--pred', default='pred.pid', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/const/tt.py b/tania_scripts/supar/cmds/const/tt.py new file mode 100644 index 0000000..286c402 --- /dev/null +++ b/tania_scripts/supar/cmds/const/tt.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import TetraTaggingConstituencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create Tetra-tagging Constituency Parser.') + parser.set_defaults(Parser=TetraTaggingConstituencyParser) + parser.add_argument('--depth', default=8, type=int, help='stack depth') + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + subparser.add_argument('--pred', default='pred.pid', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/const/vi.py b/tania_scripts/supar/cmds/const/vi.py new file mode 100644 index 0000000..0b63a3b --- /dev/null +++ b/tania_scripts/supar/cmds/const/vi.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import VIConstituencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create Constituency Parser using Variational Inference.') + parser.set_defaults(Parser=VIConstituencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + subparser.add_argument('--inference', default='mfvi', choices=['mfvi', 'lbp'], help='approximate inference methods') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + subparser.add_argument('--pred', default='pred.pid', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/dep/__pycache__/biaffine.cpython-310.pyc b/tania_scripts/supar/cmds/dep/__pycache__/biaffine.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d1e880285e3ad83ee46efd54d2f67696d3632f8 GIT binary patch literal 2259 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 M9LyZbT#PLL0VCd?y#N3J literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/cmds/dep/__pycache__/eager.cpython-310.pyc b/tania_scripts/supar/cmds/dep/__pycache__/eager.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad57c97660122f9abeadd858036cba5f3669e9cd GIT binary patch literal 2194 zcmd1j<>g{vU|`_PGe|e%W?*;>;vi!t1_lNP1_p*=I|c@Z6owSW9EK<m&6LBK%M``L z2x2qmFz2#Fu`n{Eu%xiIFhsGYvZb(PGZo3EvNkg?GNdpDgRv(2OOVNanvAz39E*}& z6Vp?RTv7{C^HNgtk}Crei;7c=G#PKPWaed-B!g7KFf#)K0~-SagEPn-XBZh6N*J;j zQy5d2dKqgOY8bMZQkX$Dr?B-hGeY?6DJ&@*NPNx|mJ}{HpSgr3g}av#td=!}CxthK zua~Kov4$~=ErmZtAVsj3sg|jRDT^sZC`CAhB}F8Kt(S$70W2b#!jd8eH3_6bJcT7i z0*NnK!k!|PA`Ny4NM0sIwuC)JE=3-0f<lU7ic*R)T!l)CYKj^XUp+-5MH7jymBNss zjl|bUVM)<V(M!>Xn`n??m|~R9lwz1-oMHkOH7#LJF-tKA+XM2MMT#Yo&(Pg1lVXMD zPU{qn6dS0$ApN!}c1Zg1s|WeqKE)x$5vm`=cS>PNafXCc2}cb>Gb1SN1T$#5_*JPm z7o{eaq$-3ICFT`pmSpDVDIgMt0wiVVX)@m8PDw3JF3Kzbsi<Pp)h#JXO})icT#{du z8edXWnp&k;o{?ITky@lslCO}OS6o_@s!*PqlcSrKUzD4gl9yUstjTnXEioBnz%7=H z)SLp4F$G2WSyc*1T0sJ-$t9U(nN_I@B^jv-DTyVCRh+uI1&Ku^nTa`7YB0r60fof8 zy!?_xkg*Dx#R{2u$vLGdsVSO_x7Z-AkK%C7&&^HDODVp^lAE8Bs>yVVwIs77C-oLf zN@{V*E!L8v#LT=Z{tytQkf=}q&JB8+j797W3=CE5y1GfFnK>y{Ou9)ZE(ME%od_~D zM<Fe<sJNtxM^`sFBQ-g@AU`v&q{;y1*phsOoczQTg+v8}EGVRkQo%u}0Cq!WUOLFS zg3`R?k}5eQtx!)XfMrU-egy?dZeoRQPHJA2bZ%mWLQZO4dP#;tej3<G#i@BEsd>q% zpg?CSsVqo^c!m??ndI!$lH!*N3=9lak|3RVrMVz&Nu^*3kgH0IQ#F}yv8SY_C6?xt z6!9`JFhKOPgCZUjTB4w6(Jv@T(g(X-FF8LiC#RxHs35T<17reNR3R-hCsmWFh##(> zRaZA9wX8}Qt~({Q45n8ArZ*+E46GBBK1x!HOR7ZR%0XP1dO?_akRU_@yRL3(Zc=JW zl{v^}h5RA~FgGPLFTGeHu`Dq&Cow4}RUxrNA)&amAhAfVv?Md9SkD!t2c#&WibGeo zv^X`stkA7W2`K_fi&GWKQj<&aixdh=6Z1+ktH6<<$y@{~9FaW83G!faeoAW5E#};u zf?F&(#U;5_Qki+lMX9-|c_oQC3Mr{zc~B@p!#O!4KQlSC7|9rRkTE%ll|_sU3=En~ zkQe|3<1LQVvc#Oy#FEr1EmtTD65$1@$(d=HsVUI(tB{zN0?s?dsU><ZIY5!krmG7I z$SQtVz=3$hsU^4A3yM-xGLuWHG((G16%rwd5n)nEzCvzdcB%qYRc3x(u^uRHK>R9h z5DAMC37E+s!OY~6)D(rH)Z)^d5{UBrq$+WwK+P{LDJU&bC@9KLD%Rw@#gSN)4$gbG z_#BJUOF^Lp$-uXG5>ry*6QN?ac#2a?;-N{ixCm59-r@r(C@xI`YcDFk#RcL+IJcNH z^Gb?9)tDypEjEZ)6c<8m6epa$lA%bBfq~(diGD_YZmK@0Oi9d3)Jw`qOvy|w($CCG zE=VlW2PYi;<lK~E{gl)K{Zvp@s#j2XizPQPGY=Hb#a0Xq3_OeiV93MB$H>Pd1ZE2` z!e|gnj8TA*j|s#A(J&bv#v)M0yu}e84>B)4UX#5@jDdmS7Ax3Zuy>>Qz-&E`8}y1w z^T57?Ys*W_O^uHS`vi%Q2bsZPlbfGXnv-e=N>#;t3=9k$Ogv0Hj2uiH%3O>r{{aGQ BgmwS` literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/cmds/dep/__pycache__/sl.cpython-310.pyc b/tania_scripts/supar/cmds/dep/__pycache__/sl.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce6e7c7bc3a266002f7b31faf3e1bfbd4c6f6aef GIT binary patch literal 2281 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/cmds/dep/biaffine.py b/tania_scripts/supar/cmds/dep/biaffine.py new file mode 100644 index 0000000..315ae6e --- /dev/null +++ b/tania_scripts/supar/cmds/dep/biaffine.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import BiaffineDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create Biaffine Dependency Parser.') + parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness') + parser.add_argument('--proj', action='store_true', help='whether to projectivize the data') + parser.add_argument('--partial', action='store_true', help='whether partial annotation is included') + parser.set_defaults(Parser=BiaffineDependencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/dep/crf.py b/tania_scripts/supar/cmds/dep/crf.py new file mode 100644 index 0000000..1229ae1 --- /dev/null +++ b/tania_scripts/supar/cmds/dep/crf.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import CRFDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create first-order CRF Dependency Parser.') + parser.set_defaults(Parser=CRFDependencyParser) + parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding') + parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness') + parser.add_argument('--proj', action='store_true', help='whether to projectivize the data') + parser.add_argument('--partial', action='store_true', help='whether partial annotation is included') + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/dep/crf2o.py b/tania_scripts/supar/cmds/dep/crf2o.py new file mode 100644 index 0000000..cc066ec --- /dev/null +++ b/tania_scripts/supar/cmds/dep/crf2o.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import CRF2oDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create second-order CRF Dependency Parser.') + parser.set_defaults(Parser=CRF2oDependencyParser) + parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding') + parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness') + parser.add_argument('--proj', action='store_true', help='whether to projectivize the data') + parser.add_argument('--partial', action='store_true', help='whether partial annotation is included') + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/dep/eager.py b/tania_scripts/supar/cmds/dep/eager.py new file mode 100644 index 0000000..74ae879 --- /dev/null +++ b/tania_scripts/supar/cmds/dep/eager.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import ArcEagerDependencyParser +from supar.cmds.run import init + +def main(): + parser = argparse.ArgumentParser(description='Create Transition Dependency Parser.') + parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness') + parser.add_argument('--proj', action='store_true', help='whether to projectivize the data') + parser.add_argument('--partial', action='store_true', help='whether partial annotation is included') + parser.set_defaults(Parser=ArcEagerDependencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file') + subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization') + subparser.add_argument('--decoder', choices=['mlp', 'lstm'], default='mlp', help='incremental decoder to use') + subparser.add_argument('--delay', type=int, default=0) + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/dep/sl.py b/tania_scripts/supar/cmds/dep/sl.py new file mode 100644 index 0000000..97f852b --- /dev/null +++ b/tania_scripts/supar/cmds/dep/sl.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import SLDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create SL Dependency Parsing Parser.') + parser.set_defaults(Parser=SLDependencyParser) + parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness') + parser.add_argument('--proj', action='store_true', help='whether to projectivize the data') + parser.add_argument('--partial', action='store_true', help='whether partial annotation is included') + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization') + subparser.add_argument('--max_len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file') + subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization') + subparser.add_argument('--decoder', choices=['mlp', 'lstm'], default='mlp', help='incremental decoder to use') + subparser.add_argument('--codes', choices=['abs', 'rel', 'pos', '1p', '2p'], default=None, help='SL coding used') + subparser.add_argument('--delay', type=int, default=0) + subparser.add_argument('--root_node', type=str, default='S') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset') + subparser.add_argument('--pred', default='pred.pid', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/dep/vi.py b/tania_scripts/supar/cmds/dep/vi.py new file mode 100644 index 0000000..1175977 --- /dev/null +++ b/tania_scripts/supar/cmds/dep/vi.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import VIDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create Dependency Parser using Variational Inference.') + parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness') + parser.add_argument('--proj', action='store_true', help='whether to projectivise the data') + parser.add_argument('--partial', action='store_true', help='whether partial annotation is included') + parser.set_defaults(Parser=VIDependencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file') + subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file') + subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + subparser.add_argument('--inference', default='mfvi', choices=['mfvi', 'lbp'], help='approximate inference methods') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--punct', action='store_true', help='whether to include punctuation') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/run.py b/tania_scripts/supar/cmds/run.py new file mode 100644 index 0000000..df93b72 --- /dev/null +++ b/tania_scripts/supar/cmds/run.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +import os, shutil +import torch +import torch.distributed as dist +import torch.multiprocessing as mp +from supar.utils import Config +from supar.utils.logging import init_logger, logger +from supar.utils.parallel import get_device_count, get_free_port + + +def init(parser): + parser.add_argument('--path', '-p', help='path to model file') + parser.add_argument('--conf', '-c', default='', help='path to config file') + parser.add_argument('--device', '-d', default='0', help='ID of GPU to use') + parser.add_argument('--seed', '-s', default=1, type=int, help='seed for generating random numbers') + parser.add_argument('--threads', '-t', default=16, type=int, help='num of threads') + parser.add_argument('--workers', '-w', default=0, type=int, help='num of processes used for data loading') + parser.add_argument('--cache', action='store_true', help='cache the data for fast loading') + parser.add_argument('--binarize', action='store_true', help='binarize the data first') + parser.add_argument('--amp', action='store_true', help='use automatic mixed precision for parsing') + parser.add_argument('--dist', choices=['ddp', 'fsdp'], default='ddp', help='distributed training types') + parser.add_argument('--wandb', action='store_true', help='wandb for tracking experiments') + args, unknown = parser.parse_known_args() + args, unknown = parser.parse_known_args(unknown, args) + args = Config.load(**vars(args), unknown=unknown) + + args.folder = '/'.join(args.path.split('/')[:-1]) + if not os.path.exists(args.folder): + os.makedirs(args.folder) + + os.environ['CUDA_VISIBLE_DEVICES'] = args.device + if get_device_count() > 1: + os.environ['MASTER_ADDR'] = 'tcp://localhost' + os.environ['MASTER_PORT'] = get_free_port() + mp.spawn(parse, args=(args,), nprocs=get_device_count()) + else: + parse(0 if torch.cuda.is_available() else -1, args) + + +def parse(local_rank, args): + Parser = args.pop('Parser') + torch.set_num_threads(args.threads) + torch.manual_seed(args.seed) + if get_device_count() > 1: + dist.init_process_group(backend='nccl', + init_method=f"{os.environ['MASTER_ADDR']}:{os.environ['MASTER_PORT']}", + world_size=get_device_count(), + rank=local_rank) + torch.cuda.set_device(local_rank) + # init logger after dist has been initialized + init_logger(logger, f"{args.path}.{args.mode}.log", 'a' if args.get('checkpoint') else 'w') + logger.info('\n' + str(args)) + + args.local_rank = local_rank + os.environ['RANK'] = os.environ['LOCAL_RANK'] = f'{local_rank}' + if args.mode == 'train': + parser = Parser.load(**args) if args.checkpoint else Parser.build(**args) + parser.train(**args) + elif args.mode == 'evaluate': + parser = Parser.load(**args) + parser.evaluate(**args) + elif args.mode == 'predict': + parser = Parser.load(**args) + parser.predict(**args) diff --git a/tania_scripts/supar/cmds/sdp/biaffine.py b/tania_scripts/supar/cmds/sdp/biaffine.py new file mode 100644 index 0000000..a36ab6a --- /dev/null +++ b/tania_scripts/supar/cmds/sdp/biaffine.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import BiaffineSemanticDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create Biaffine Semantic Dependency Parser.') + parser.set_defaults(Parser=BiaffineSemanticDependencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'lemma', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/sdp/DM/train.conllu', help='path to train file') + subparser.add_argument('--dev', default='data/sdp/DM/dev.conllu', help='path to dev file') + subparser.add_argument('--test', default='data/sdp/DM/test.conllu', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--n-embed-proj', default=125, type=int, help='dimension of projected embeddings') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllu', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/cmds/sdp/vi.py b/tania_scripts/supar/cmds/sdp/vi.py new file mode 100644 index 0000000..26fee77 --- /dev/null +++ b/tania_scripts/supar/cmds/sdp/vi.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +import argparse + +from supar import VISemanticDependencyParser +from supar.cmds.run import init + + +def main(): + parser = argparse.ArgumentParser(description='Create Semantic Dependency Parser using Variational Inference.') + parser.set_defaults(Parser=VISemanticDependencyParser) + subparsers = parser.add_subparsers(title='Commands', dest='mode') + # train + subparser = subparsers.add_parser('train', help='Train a parser.') + subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'lemma', 'elmo', 'bert'], nargs='*', help='features to use') + subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first') + subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training') + subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use') + subparser.add_argument('--max-len', type=int, help='max length of the sentences') + subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use') + subparser.add_argument('--train', default='data/sdp/DM/train.conllu', help='path to train file') + subparser.add_argument('--dev', default='data/sdp/DM/dev.conllu', help='path to dev file') + subparser.add_argument('--test', default='data/sdp/DM/test.conllu', help='path to test file') + subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`') + subparser.add_argument('--n-embed-proj', default=125, type=int, help='dimension of projected embeddings') + subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use') + subparser.add_argument('--inference', default='mfvi', choices=['mfvi', 'lbp'], help='approximate inference methods') + # evaluate + subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset') + # predict + subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.') + subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use') + subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset') + subparser.add_argument('--pred', default='pred.conllu', help='path to predicted result') + subparser.add_argument('--prob', action='store_true', help='whether to output probs') + init(parser) + + +if __name__ == "__main__": + main() diff --git a/tania_scripts/supar/codelin/__init__.py b/tania_scripts/supar/codelin/__init__.py new file mode 100644 index 0000000..847de4f --- /dev/null +++ b/tania_scripts/supar/codelin/__init__.py @@ -0,0 +1,34 @@ +from .encs.enc_deps import D_NaiveAbsoluteEncoding, D_NaiveRelativeEncoding, D_PosBasedEncoding, D_BrkBasedEncoding, D_Brk2PBasedEncoding +from .encs.enc_const import C_NaiveAbsoluteEncoding, C_NaiveRelativeEncoding +from .utils.constants import D_2P_GREED, D_2P_PROP + +# import structures for encoding/decoding +from .models.const_label import C_Label +from .models.const_tree import C_Tree +from .models.linearized_tree import LinearizedTree +from .models.deps_label import D_Label +from .models.deps_tree import D_Tree + +LABEL_SEPARATOR = '€' +UNARY_JOINER = '@' + +def get_con_encoder(encoding: str, sep: str = LABEL_SEPARATOR, unary_joiner: str = UNARY_JOINER): + if encoding == 'abs': + return C_NaiveAbsoluteEncoding(sep, unary_joiner) + elif encoding == 'rel': + return C_NaiveRelativeEncoding(sep, unary_joiner) + return NotImplementedError + +def get_dep_encoder(encoding: str, sep: str, displacement: bool = False): + if encoding == 'abs': + return D_NaiveAbsoluteEncoding(sep) + elif encoding == 'rel': + return D_NaiveRelativeEncoding(sep, hang_from_root=False) + elif encoding == 'pos': + return D_PosBasedEncoding(sep) + elif encoding == '1p': + return D_BrkBasedEncoding(sep, displacement) + elif encoding == '2p': + return D_Brk2PBasedEncoding(sep, displacement, D_2P_PROP) + return NotImplementedError + diff --git a/tania_scripts/supar/codelin/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21b03f9cdf5de941345a04314d4e726119e9dfd2 GIT binary patch literal 1419 zcmd1j<>g{vU|`^5Uz8rn%E0g##6iaF3=9ko3=9m#I~W)kQW#Pga~N_NqZo6UqL^}- zqnLA9qF8cSqgWY1a!fgFx$IHwxg1d(U_NsWXD(M1S1xxHH<-_o!;{M!#S3P$=J4h6 zNAZK%Y&inCf>DBCHhYdxu5gqvn9Y$Rk}Db|%E*wy86}p&6(yc3mMWgcl){}Vk;0QI zk;0oQk;az7m%`t|8YP(`3Kthll}ckv5lRtmVU3bb5ea6{6nn|Yz`&r%dQ03T-Y+q; zEY&foI6tSfB-J%9IX@*cFC8usl$w)Rl39k35ORqR$S-zEEKW^<D;9EzcPh$86%zrA z83mw-YBJptcgAHSR07>bO{QC1F7ZYI@$Nyct}eGY!R&w_{{T(KTkOv9K8Z=GIhu^O z*qq}-ic(WG8E^6VWagzN7G+kYra(p5T@cD#z{*OQ85kHIHLdx@=x~c873OK?;?#m$ zJf(SwMV0Yc`I&jCMadv_u=oeDLD(4-{~8Po3^fcXjM+>@oFxo3j5SQnOu--#rfjAn zp%O-zNC{IggC?`zE#}0e;#<r`sX3a=MW94f#KFM8a7)-Pzr-`QASX39HLoN!#kHs? zzetn0NRWYnp-2cs2s1D+tYjz>XJBCXWv`!+pPQ;*l30?Nn3t%Rl#`f}nOdZuoS$2e zubW;_qMMtalA5DmTw0I_5=}|X$;{J_kI&4@EQycTE2zB1pPpJ0pPZi;5B70t5kJTy zp!Ckc$i)c4ER02x3=9lzw|G)AiwklRlfmx72m}@e1_p2-#32HK0~83&jHp47!kog= z3keq1Y^EZq5~dnPs2a9xrXuAMW>_%QFr=_&GZpEUuz*BLSeu!H8A{lK88kWkibOyG zAqsMrCSw#|Mq*xid|FX{ZhTRGe#tH7g8bqrCc}a#CZhsP_97;bT2LevfgD-H3gWVX z2#`06#6YPYIe4W&QlP*Ehj5VuC{Dnkl#*Hi3nh@IVi3W>2!cFd5)@h-j694ij72gG z3=DpnjBc7TQM{>n$;Eo9dCBo9sRhM29TUX|SC^chS6qTf5K;W4C7C(JdSKziyprM~ zPLK;hj*k)oM=w+^J_nTUi?|sW7@`DGBua`>Q;T>&;$l$o9C&_+2TSsTBw?CB4uu-V z2ND;6Y66Rcm4i~rEq)(ICs&{NVAlZ0Ajc5@pj$klevUzr@m~I(ey%~cn2Sq_z)9y8 zOHzJ*4meC8L5dc*95%W6DWy57cAx^N7!=+z3<8V-j6BRdj1b7e#KI`UB*P8>OzUF; literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..737b648aa6c9eb05010e8759390d493979dff7fc GIT binary patch literal 2143 zcmZ3^%ge>Uz`&q*Uo|6=m4V?ghy%myP{!wN3=9m@8B!Qh7;_kM8KW3;nWC6-nWLC< zS)y2SS)*7PL2^tvY`N@F?719K9AG|k4reY`6jv^H6gQa9lEahB8^sG|v*z&S@<;K5 z*=#uixq?xGU^aV>P_A&4FqqAeBa$l`CCbQ<!Wku&!WAW+DwZmq#+1UHDv`pIDv`pQ zDv`#P!q>tYC7B`&7ZpgAN@GhAY+;R(P7w-b&=h&e$iTp$$$CrNCEhPFvn<sysW?BU zv?SFvFF8LYGcO%35tN#fSdv+WkPvc-56CZeN-R!Ifh!hriFYc>MimnQix~x=h-xz3 z5_iUBBUA$2Mop$$TrTlO0rBoZuC6Y(IKk|IApZbO##`*p@ji)3sX3aAx7eKHLyA&U zH5qU5`DEs$CKhE@rKUhd*j*6HT)@gonHd-u9yP7`#prO0BNgUp=Hk?XTRf$CiA9z1 zS^1fHsYS^kb<hZBU}0cj0P#O(fMdRfA%!uU2_#u0Pyz~15R-v{p@y-BX&Dm(!)mY` zNHCb8h9QLst`=klNEnCO5|BMm`CtZ3X1`m^iAlw`n2S<#G?|My7#J9eI2jliZVCJ4 zmw4tD<fP`N=9Q$TxE2-V7ilsV34s&{g9s4@28LpgWeN%kzkKyG@^e%5OA<>m6Y~=F zl5!GLGE<B6lk;;6@^wp6D@t@z%Mx?+OA_-k6XT1Mi!uvJiuH?23lc$UQc`m=^Yr86 zGxIV_;^XxSDsS<pr<TMg=jX+P1246xNQ!}hfgfa{9RmYH1H%n={t2d+*d;EoOWfsG zTTr~h=OVx56@JSL9F{jY1t)}F;*`3;DTOX|ms{=vi`-|B=iP4cq+}Ks<Rm78{f80} ztgwjqh8_|8s1dP@k%3_~JZey)L9hfAG9a74(U8Kth6PKcu|gw_zXW6_Ts0PR*`O)~ zN?-*9*j%hhfgP$=tb`M4Bvfq)xY&V+En{Y2SPge$FhdCsL>xp0GiY-76^Vf&S)74^ z!3~t^GZORC<I{@rbK{Hh^Gj|q7vvY;Vlpha#bi{V$zB99s0fs>ia;JIVgqRfIkboy z#F7A&2FOWA1{9MZJqij6MUtS@29EHQ)B<>fD={!IfLu^K0c(U`<k!B!uYG|-8$G&r zm|oy_yvXl(h2QZ4ha-xt;sWK1{AySD)h=+Tfh0mMaY|m`l)THYxIlS9%|(8bEBq!G zI80EalovR!kl9)ZHxQD9iliAB82mID-85xx@uub_7we_wCC8_v78K(QiCcVdb;<d8 z#U)5NjlZ-cGpAS&ES#8EQd|UzCUD5z63Wd_NrlP9=YR^MB2Yx#5=4<GDN0Q(;su4H z7*sq5UP#4*CHX*-FijwbLJb4usapb2O<-}basiNXeji6CSD*M`*8s;L#}NOZTRfqD zjzN*}UjCkbu0gk$i%TH+@)k={etu37D8^PYfP)4cr@uICa`RJ4b5iY!3>X*~K>4IN znvsFw12ZEd;|C@NMlYrh4AdlVF!)@+hHfwzUBHGuurV-dTwqW~MmHE#FQ6h!-8UH2 zE})_t3@R5;(E}mz2L2oTLJd3*^lUE#$A4g8Wt0aKGm^p73T7~MA{b1e6MWnt)!dBo ZAl2NA@*vgRjPg57J}|&!u(7~_4*<LXBNzYx literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-310.pyc b/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..163660a55c0e295e147a3eb4645efc78e2a5e088 GIT binary patch literal 1801 zcmd1j<>g{vU|`^5UzGlynStRkh=Yt-7#J8F7#J9eO&Ay$QW#Pga~N_NqZo6UqL>&N z+!<1sQkYv9QkYX2o0+4S-5F9?QdnCUQdq%!mK3&N22J*tAoDbtZZSJLIp5+-Oe!uZ zN=z=vO)bgDPe}&JA!8<}eV;WL7#LC+q8L*cqL@+`qnIH!MX^9^h+<7)OJQ$eh+<3O z2xidayv60{;+mJ7pOTrEUiF1bK|w*m5o(b_a!z7#u|isYk%CKVL26z~YF=`s0!(o+ zSZ#1>NwGpnMyf(?VrHH~a(-TMNl|HXNq&(6#F+|-c_|7hscD&csZe!b*F!XeEYpP; zm<l!xBH)smoSy;_2+v5(Q%Fn!IZh!_AuqKYn@bcjOB8ZTi%S$zD@s!HQWQ!uGK(Q@ z2OA1<L1u12PHJvyUWr0UMt*TB)Nv43B!fZ@7Lp(~2s?vf4iv#Pj5Q4L3@Hr33@aJ^ zG#PJk7N-^@7A2PC7iluxVku6|Nh@M!U|?9uP{hf=!0^jgKO;XkRlg*$Br`EDQ7<Vc zF(os#NIyA0w;*3Py`V%lH$NpcN58nVAQ2>*lA4p5r=OaaT&xd^-uP5#Z0HqK-r|Ul z&&<m#iI3+2xd-GhF2*WhM2zXd<S{(K$iTn=^2BFQIs`eth>d{(;z&)VA`S)yhFh$8 z`6;QzV0S|ZkbiHnf$dM_XJBCX46=}gu}TohLWpcK$W&OEf!HwXia-uUvWf*_6<bbX zQff}|E%t)^;*!Ml;#;ic`9&$1cBg=&UJ&F`kONR`hRFG?WCw*xUSe))eEco0`1suX zl+qj!n<qZLurx6TD#IQhpOT*(A78``GK>#I2!jYtR08DXB31?l24+wIgLoVaEQ}l+ z9LzjSU~!!JtO(?7aQ<<IWr?c)-~@*y|2Ts(MrKJVC<Ve)LsB2f83>k6P|`3Y<A6<u zWE_Y9-kgNZO_XLOP$<HZ1&9qwK%i7uEWp6P0Le-<Of?MgjPMkx$pp?nw|GkP5{oM1 zv+^_ZQj0X1!N~?J6UAN%5rm{saQuPd2^_JqpjZP%1REnbW5A<=aK=DSsgO(&B>*nN zAW;=xQk0sCZY?M&DS{FaG=U<lgk}wppJ8DDV&lph5DRbd=Va!kCKhE@rKVuD50q+^ zvDydC5Je&&S#Y=@2yh5VGB7ZJB#S{jXu4+MVJZTN`)RV?Vopp-E&@5R2ozV~<PMfY d@-o;&koH>~HjtcV2l7ubs4x*=5MUA!1OSyTpk@F7 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-311.pyc b/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7faea83a2faeba0be37ddc0648b2989d60fcc074 GIT binary patch literal 2197 zcmZ3^%ge>Uz`&q*Up3=BGXuk85C?`?p^VRd3=9m@8B!Qh7;_kM8KW3;nWC5&8JHN{ z8B&;97*d#18J96LFsx>Vs%MB|2FtOuFr=_z$g!lb1v6-}zXU1PWV*%d=;VBhFEOdO zq$n}DBsaArBR?e>BnQKcP{wB!uq#p-q8L*cqL@+`qnJUqN3o<Zw=hJprm(ayM6so? z1~X`~-Qsd|am`E4Psz+nulmBJprD}O2(>^VIVZ8WSRpOHNWmqwAT=)~H7~hR0j9VZ ztTs5cq*$ROBUK?cF*8pgIX|zsq^LBxB)>=j;yi`KycC6$)U?dJRH!<zt09^}mgzza zOa+?;5pYRO&QE~|glDAYDI}(V9H)?|ke6DH%_Rz%B?`Hv#U%=<6(y;8DGDVSnZ*#d zgAE0_ATzfhCp9-UuSB6FBfmHm>Ntoil9`~P2BJW0P~3bL0f%4>V+}(*NF0n)7=jsA zGWuyU-r_7yEl4a%EXgm@WV*#toSKtX#L2+GPz=(ppzteNKO;XkRlg*$Br`EDQ7<Vc zF(os#NIyA0w;*4)B(<VMH?=G=N53R7FEcT|IJqdZprly8xU?V<q$VXbCo@k!H7~hX z9~RZ|sn8hGE2zB15g(tKmst`YUnPu)Iz5;m56Bt33=9kn3^yc|I#_!6I`}&HK7-tk z;!#ji0eh4U>`{={iZ~b;7*;Z9G8KW+`7PGG{FKyUsF#Yk85kIDv4P!@S|x~NF+_-; zfq~&OJH%QJo(`5GkQ0(wK-NMrE(?o5S~Xc9cCzIpCZ*;S-(oMwFD^+;FTTZEo?nzw zTnsV@lsKTyNCBr16lXw$1Q{3@iiAJ}$bP?-?4Z!fOUzA;kH5tgAD^3_Qknx|^Tfv& zmL}#vW!U56Q}UDJ<BLFnR|Gag9ApN_Wnhnhtt|qD6qo>oTd_CTvkeRo_<@O?mE!{g zh!9|8RsO&LC)gNSc|lw#!Gg+VfN>%AfUKZGj&_D+(yIU9EPy3PJA<-nW=Sb1Pry_| z@&n0P8kR~?auq1HNX^^W+(c>S2E`RL1u}qgCy4)937qCpGj|PB4MRLAk%Cpj^MfW6 zIA`DDDa}hPs*KOd&&*3L(qslFSBMOIDMYXsWVC{U0wl43l2VnhBRnSH8B`XOK|#q2 zo<VQOD0i@2;gGxlM&N`%R91!L9B6J80GGXx2#qf(N=-%1xZpHhC5Yr2NUl``rE++7 zA>C5`oXot`#G=fq)D%oRL4HKB6Ou)hQS9_9k^u41a+(}S3`BrRVLUmFiB;tT1DxQ1 z<t0dV!=KYYru%8K-eOKnN-hG$ToI^@0cY<bkQ_L0!EphO&tDuikix^RNS%R!0hCUP zs~H#=J}@&fGTvZNzJLvVVBu%v{lI`pOc4GE68!=qAo5BAAeEQ|NTmQH?-vG4DX`-J Dznca) literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/abstract_encoding.py b/tania_scripts/supar/codelin/encs/abstract_encoding.py new file mode 100644 index 0000000..1e3fa03 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/abstract_encoding.py @@ -0,0 +1,37 @@ +from abc import ABC, abstractmethod + +class ADEncoding(ABC): + ''' + Abstract class for Dependency Encodings + Sets the main constructor method and defines the methods + - Encode + - Decode + When adding a new Dependency Encoding it must extend this class + and implement those methods + ''' + def __init__(self, separator): + self.separator = separator + + def encode(self, nodes): + pass + def decode(self, labels, postags, words): + pass + +class ACEncoding(ABC): + ''' + Abstract class for Constituent Encodings + Sets the main constructor method and defines the abstract methods + - Encode + - Decode + When adding a new Constituent Encoding it must extend this class + and implement those methods + ''' + def __init__(self, separator, ujoiner): + self.separator = separator + self.unary_joiner = ujoiner + + def encode(self, constituent_tree): + pass + def decode(self, linearized_tree): + pass + diff --git a/tania_scripts/supar/codelin/encs/constituent.py b/tania_scripts/supar/codelin/encs/constituent.py new file mode 100644 index 0000000..0dbe8f0 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/constituent.py @@ -0,0 +1,115 @@ +from src.models.linearized_tree import LinearizedTree +from src.encs.enc_const import * +from src.utils.extract_feats import extract_features_const +from src.utils.constants import C_INCREMENTAL_ENCODING, C_ABSOLUTE_ENCODING, C_RELATIVE_ENCODING, C_DYNAMIC_ENCODING + +import stanza.pipeline +from supar.codelin.models.const_tree import C_Tree + + +## Encoding and decoding + +def encode_constituent(in_path, out_path, encoding_type, separator, unary_joiner, features): + ''' + Encodes the selected file according to the specified parameters: + :param in_path: Path of the file to be encoded + :param out_path: Path where to write the encoded labels + :param encoding_type: Encoding used + :param separator: string used to separate label fields + :param unary_joiner: string used to separate nodes from unary chains + :param features: features to add as columns to the labels file + ''' + + if encoding_type == C_ABSOLUTE_ENCODING: + encoder = C_NaiveAbsoluteEncoding(separator, unary_joiner) + elif encoding_type == C_RELATIVE_ENCODING: + encoder = C_NaiveRelativeEncoding(separator, unary_joiner) + elif encoding_type == C_DYNAMIC_ENCODING: + encoder = C_NaiveDynamicEncoding(separator, unary_joiner) + elif encoding_type == C_INCREMENTAL_ENCODING: + encoder = C_NaiveIncrementalEncoding(separator, unary_joiner) + else: + raise Exception("Unknown encoding type") + + # build feature index dictionary + f_idx_dict = {} + if features: + if features == ["ALL"]: + features = extract_features_const(in_path) + i=0 + for f in features: + f_idx_dict[f]=i + i+=1 + + file_out = open(out_path, "w") + file_in = open(in_path, "r") + + tree_counter = 0 + labels_counter = 0 + label_set = set() + + for line in file_in: + line = line.rstrip() + tree = C_Tree.from_string(line) + linearized_tree = encoder.encode(tree) + file_out.write(linearized_tree.to_string(f_idx_dict)) + file_out.write("\n") + tree_counter += 1 + labels_counter += len(linearized_tree) + for lbl in linearized_tree.get_labels(): + label_set.add(str(lbl)) + + return labels_counter, tree_counter, len(label_set) + +def decode_constituent(in_path, out_path, encoding_type, separator, unary_joiner, conflicts, nulls, postags, lang): + ''' + Decodes the selected file according to the specified parameters: + :param in_path: Path of the labels file to be decoded + :param out_path: Path where to write the decoded tree + :param encoding_type: Encoding used + :param separator: string used to separate label fields + :param unary_joiner: string used to separate nodes from unary chains + :param conflicts: conflict resolution heuristics to apply + ''' + + if encoding_type == C_ABSOLUTE_ENCODING: + decoder = C_NaiveAbsoluteEncoding(separator, unary_joiner) + elif encoding_type == C_RELATIVE_ENCODING: + decoder = C_NaiveRelativeEncoding(separator, unary_joiner) + elif encoding_type == C_DYNAMIC_ENCODING: + decoder = C_NaiveDynamicEncoding(separator, unary_joiner) + elif encoding_type == C_INCREMENTAL_ENCODING: + decoder = C_NaiveIncrementalEncoding(separator, unary_joiner) + else: + raise Exception("Unknown encoding type") + + if postags: + stanza.download(lang=lang) + nlp = stanza.Pipeline(lang=lang, processors='tokenize, pos') + + f_in = open(in_path) + f_out = open(out_path,"w+") + + tree_string = "" + labels_counter = 0 + tree_counter = 0 + + for line in f_in: + if line == "\n": + tree_string = tree_string.rstrip() + current_tree = LinearizedTree.from_string(tree_string, mode="CONST", separator=separator, unary_joiner=unary_joiner) + + if postags: + c_tags = nlp(current_tree.get_sentence()) + current_tree.set_postags([word.pos for word in c_tags]) + + decoded_tree = decoder.decode(current_tree) + decoded_tree = decoded_tree.postprocess_tree(conflicts, nulls) + + f_out.write(str(decoded_tree).replace('\n','')+'\n') + tree_string = "" + tree_counter+=1 + tree_string += line + labels_counter += 1 + + return tree_counter, labels_counter \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/dependency.py b/tania_scripts/supar/codelin/encs/dependency.py new file mode 100644 index 0000000..b2a49d4 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/dependency.py @@ -0,0 +1,129 @@ +import stanza +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.deps_label import D_Label +from supar.codelin.utils.extract_feats import extract_features_deps +from supar.codelin.encs.enc_deps import * +from supar.codelin.utils.constants import * +from supar.codelin.models.deps_tree import D_Tree + +# Encoding +def encode_dependencies(in_path, out_path, encoding_type, separator, displacement, planar_alg, root_enc, features): + ''' + Encodes the selected file according to the specified parameters: + :param in_path: Path of the file to be encoded + :param out_path: Path where to write the encoded labels + :param encoding_type: Encoding used + :param separator: string used to separate label fields + :param displacement: boolean to indicate if use displacement in bracket based encodings + :param planar_alg: string used to choose the plane separation algorithm + :param features: features to add as columns to the labels file + ''' + + # Create the encoder + if encoding_type == D_ABSOLUTE_ENCODING: + encoder = D_NaiveAbsoluteEncoding(separator) + elif encoding_type == D_RELATIVE_ENCODING: + encoder = D_NaiveRelativeEncoding(separator, root_enc) + elif encoding_type == D_POS_ENCODING: + encoder = D_PosBasedEncoding(separator) + elif encoding_type == D_BRACKET_ENCODING: + encoder = D_BrkBasedEncoding(separator, displacement) + elif encoding_type == D_BRACKET_ENCODING_2P: + encoder = D_Brk2PBasedEncoding(separator, displacement, planar_alg) + else: + raise Exception("Unknown encoding type") + + f_idx_dict = {} + if features: + if features == ["ALL"]: + features = extract_features_deps(in_path) + i=0 + for f in features: + f_idx_dict[f]=i + i+=1 + + file_out = open(out_path,"w+") + label_set = set() + tree_counter = 0 + label_counter = 0 + trees = D_Tree.read_conllu_file(in_path, filter_projective=False) + + for t in trees: + # encode labels + linearized_tree = encoder.encode(t) + file_out.write(linearized_tree.to_string(f_idx_dict)) + file_out.write("\n") + + tree_counter+=1 + label_counter+=len(linearized_tree) + + for lbl in linearized_tree.get_labels(): + label_set.add(str(lbl)) + + print('/supar/codelin/encs/dependency.py') + return tree_counter, label_counter, len(label_set) + +# Decoding + +def decode_dependencies(in_path, out_path, encoding_type, separator, displacement, multiroot, root_search, root_enc, postags, lang): + ''' + Decodes the selected file according to the specified parameters: + :param in_path: Path of the file to be encoded + :param out_path: Path where to write the encoded labels + :param encoding_type: Encoding used + :param separator: string used to separate label fields + :param displacement: boolean to indicate if use displacement in bracket based encodings + :param multiroot: boolean to indicate if multiroot conll trees are allowed + :param root_search: strategy to select how to search the root if no root found in decoded tree + ''' + + if encoding_type == D_ABSOLUTE_ENCODING: + decoder = D_NaiveAbsoluteEncoding(separator) + elif encoding_type == D_RELATIVE_ENCODING: + decoder = D_NaiveRelativeEncoding(separator, root_enc) + elif encoding_type == D_POS_ENCODING: + decoder = D_PosBasedEncoding(separator) + elif encoding_type == D_BRACKET_ENCODING: + decoder = D_BrkBasedEncoding(separator, displacement) + elif encoding_type == D_BRACKET_ENCODING_2P: + decoder = D_Brk2PBasedEncoding(separator, displacement, None) + else: + raise Exception("Unknown encoding type") + + f_in=open(in_path) + f_out=open(out_path,"w+") + + tree_counter=0 + labels_counter=0 + + tree_string = "" + + print('/supar/codelin/encs/dependency.py 101') + + if postags: + stanza.download(lang=lang) + nlp = stanza.Pipeline(lang=lang, processors='tokenize,pos') + + + for line in f_in: + if line == "\n": + tree_string = tree_string.rstrip() + current_tree = LinearizedTree.from_string(tree_string, mode="DEPS", separator=separator) + + if postags: + c_tags = nlp(current_tree.get_sentence()) + current_tree.set_postags([word.pos for word in c_tags]) + + decoded_tree = decoder.decode(current_tree) + decoded_tree.postprocess_tree(root_search, multiroot) + f_out.write("# text = "+decoded_tree.get_sentence()+"\n") + f_out.write(str(decoded_tree)) + + tree_string = "" + tree_counter+=1 + + tree_string += line + labels_counter += 1 + + + return tree_counter, labels_counter diff --git a/tania_scripts/supar/codelin/encs/enc_const/__init__.py b/tania_scripts/supar/codelin/encs/enc_const/__init__.py new file mode 100644 index 0000000..d803a3b --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_const/__init__.py @@ -0,0 +1,4 @@ +from .naive_absolute import C_NaiveAbsoluteEncoding +from .naive_relative import C_NaiveRelativeEncoding +from .naive_dynamic import C_NaiveDynamicEncoding +from .naive_incremental import C_NaiveIncrementalEncoding \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41d16cbfa21181d065d0c1f0e255961bc5fc54b8 GIT binary patch literal 423 zcmd1j<>g{vU|`^5UzC2Cfq~&Mh=Yuo7#J8F7#J9eO&Ay$QW#Pga~N_NqZk=MY^EHh zT;?cdFq=7tC6_gd70hPIVasKYVrOJXVGU-`WP8cTz`&r%cuU+l-Y+q;EY&foI6tSf zB-J%9IX@*cFC9rLC^aXsB(n@zN(`#Yr7|xuH!~SYlN40OGcUO)H8(Y{Bryjj>!-<a zi!TpkS$rbYwjz*EV1h+Zdy1GD7#N~>Au3ZKHWaad!~`K?nFzCsSQ!`?Rx%WEFfc%f zUw---`MIh3C5a`OiFt{7NjZrrnW;tk$@#ej`MT)^CAzu!DXBU7#ia#_Akmc6oXkA^ z)V$<k5D}l8pI2O>A0MBYmst`YuUAlci^C>2KczG$)eaP3#UOil7<d?Y7zG#snu>W; literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12f0189eb2fabe6bb71d622e2452f312b08a7c8c GIT binary patch literal 515 zcmZ3^%ge>Uz`&q*Up3=00|Ucj5C?{tpp4IE3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW-yyMhb5OaiWSUe$zjW7k78$JNMQ|T&}4hb$iTp$$#_fLIo>ZZvn<sysW?BUv?SFv zFF8LYGcO%UDkwE4u_Ut$SxOA5%cU|eF*h?ANs|;*#xpOuC^a`VuOu-CChMokaf>ex zWLbP7)V3mK1_lP0U=h@wA{LM!FGOVu#D*ePkeDDuEE8dN5gP*o!%BwFpdk4bqo0wV zo2p-uSdy8Tm#CMNlbDj3TBM(xpIeZxTasE)qMKTln4@2kn3tItUz}W&Sx{1}UtC&{ z2vU=hnv<EQpPH9k3?kx_^Ye;J^yA|*^D;}~<Mj$Ee{tC4=BJeAq}mnnF)%QIg0DE3 kfq~%zGb1D84F=;2s0f>g;ROa1bc4b20yb2{!@$4*0DIS-Qvd(} literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e654e52ff2f574d7c86285d440042167471c068d GIT binary patch literal 3375 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb3ffaca5b999a39848ef14e042cb37fd4f4ebae GIT binary patch literal 6958 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 N!7^XKB&I5`&j7(ZH3$Fz literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d6495f2c7305a9257f7a536493cc1034c193804 GIT binary patch literal 3661 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30ad5b6badac7cd3836fb4078ae00b30e8c29bd2 GIT binary patch literal 7604 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 JVyXhiKL8R%%V7Wj literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0df5670f680c988a0e1be47f68f977f4e1915c30 GIT binary patch literal 3908 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f6374cacf05ac756434ee357b9b18a208fcc681 GIT binary patch literal 7608 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 CX|}uo literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58ce1fee263b5b20fbc8fe069e0ca2f9155706e4 GIT binary patch literal 3289 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b42a4c47d2c9a3e7745917396a876bf0af990d50 GIT binary patch literal 6884 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 Dg$pZZ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py b/tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py new file mode 100644 index 0000000..5dbb984 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py @@ -0,0 +1,144 @@ +from supar.codelin.encs.abstract_encoding import ACEncoding +from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL +from supar.codelin.models.const_label import C_Label +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.const_tree import C_Tree + +import re + +class C_NaiveAbsoluteEncoding(ACEncoding): + def __init__(self, separator, unary_joiner): + self.separator = separator + self.unary_joiner = unary_joiner + + def __str__(self): + return "Constituent Naive Absolute Encoding" + + def encode(self, constituent_tree): + lc_tree = LinearizedTree.empty_tree() + leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner) + + for i in range(0, len(leaf_paths)-1): + path_a = leaf_paths[i] + path_b = leaf_paths[i+1] + + last_common = "" + n_commons = 0 + for a,b in zip(path_a, path_b): + + if (a!=b): + # Remove the digits and aditional feats in the last common node + last_common = re.sub(r'[0-9]+', '', last_common) + last_common = last_common.split("##")[0] + + # Get word and POS tag + word = path_a[-1] + postag = path_a[-2] + + # Build the Leaf Unary Chain + unary_chain = None + leaf_unary_chain = postag.split(self.unary_joiner) + if len(leaf_unary_chain)>1: + unary_list = [] + for element in leaf_unary_chain[:-1]: + unary_list.append(element.split("##")[0]) + + unary_chain = self.unary_joiner.join(unary_list) + postag = leaf_unary_chain[len(leaf_unary_chain)-1] + + # Clean the POS Tag and extract additional features + postag_split = postag.split("##") + feats = [None] + + if len(postag_split) > 1: + postag = re.sub(r'[0-9]+', '', postag_split[0]) + feats = postag_split[1].split("|") + else: + postag = re.sub(r'[0-9]+', '', postag) + + c_label= C_Label(n_commons, last_common, unary_chain, C_ABSOLUTE_ENCODING, + self.separator, self.unary_joiner) + + # Append the data + lc_tree.add_row(word, postag, feats, c_label) + + break + + n_commons += len(a.split(self.unary_joiner)) + last_common = a + + # n = max number of features of the tree + lc_tree.n = max([len(f) for f in lc_tree.additional_feats]) + return lc_tree + + def decode(self, linearized_tree): + # Check valid labels + if not linearized_tree: + print("[!] Error while decoding: Null tree.") + return + + # Create constituent tree + tree = C_Tree(C_ROOT_LABEL, []) + current_level = tree + + old_n_commons = 0 + old_level = None + for word, postag, feats, label in linearized_tree.iterrows(): + + # Descend through the tree until reach the level indicated by last_common + current_level = tree + for level_index in range(label.n_commons): + if (current_level.is_terminal()) or (level_index >= old_n_commons): + current_level.add_child(C_Tree(C_NONE_LABEL, [])) + + current_level = current_level.r_child() + + # Split the Last Common field of the Label in case it has a Unary Chain Collapsed + label.last_common = label.last_common.split(self.unary_joiner) + + if len(label.last_common) == 1: + # If current level has no label yet, put the label + # If current level has label but different than this one, set it as a conflict + if (current_level.label == C_NONE_LABEL): + current_level.label = label.last_common[0].rstrip() + else: + current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0] + if len(label.last_common)>1: + current_level = tree + + # problem when n_commons predicted is LESS than the number of last commons predicted + descend_levels = label.n_commons - (len(label.last_common)) + 1 + for level_index in range(descend_levels): + current_level = current_level.r_child() + for i in range(len(label.last_common)-1): + if (current_level.label == C_NONE_LABEL): + current_level.label = label.last_common[i] + else: + current_level.label = current_level.label+C_CONFLICT_SEPARATOR+label.last_common[i] + + if len(current_level.children)>0: + current_level = current_level.r_child() + + # If we reach a POS tag, set it as child of the current chain + if current_level.is_preterminal(): + temp_current_level_children = current_level.children + current_level.label = label.last_common[i+1] + current_level.children = temp_current_level_children + for c in temp_current_level_children: + c.parent = current_level + else: + current_level.label=label.last_common[i+1] + + + # Fill POS tag in this node or previous one + if (label.n_commons >= old_n_commons): + current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + else: + old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + + old_n_commons=label.n_commons + old_level=current_level + + tree.inherit_tree() + + return tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py b/tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py new file mode 100644 index 0000000..c4dc11f --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py @@ -0,0 +1,166 @@ +from supar.codelin.encs.abstract_encoding import ACEncoding +from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_RELATIVE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL +from supar.codelin.models.const_label import C_Label +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.const_tree import C_Tree + +import re + +class C_NaiveDynamicEncoding(ACEncoding): + def __init__(self, separator, unary_joiner): + self.separator = separator + self.unary_joiner = unary_joiner + + def __str__(self): + return "Constituent Naive Dynamic Encoding" + + def encode(self, constituent_tree): + lc_tree = LinearizedTree.empty_tree() + leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner) + + last_n_common=0 + for i in range(0, len(leaf_paths)-1): + path_a=leaf_paths[i] + path_b=leaf_paths[i+1] + + last_common="" + n_commons=0 + for a,b in zip(path_a, path_b): + + if (a!=b): + # Remove the digits and aditional feats in the last common node + last_common = re.sub(r'[0-9]+', '', last_common) + last_common = last_common.split("##")[0] + + # Get word and POS tag + word = path_a[-1] + postag = path_a[-2] + + # Build the Leaf Unary Chain + unary_chain = None + leaf_unary_chain = postag.split(self.unary_joiner) + if len(leaf_unary_chain)>1: + unary_list = [] + for element in leaf_unary_chain[:-1]: + unary_list.append(element.split("##")[0]) + + unary_chain = self.unary_joiner.join(unary_list) + postag = leaf_unary_chain[len(leaf_unary_chain)-1] + + # Clean the POS Tag and extract additional features + postag_split = postag.split("##") + feats = [None] + + if len(postag_split) > 1: + postag = re.sub(r'[0-9]+', '', postag_split[0]) + feats = postag_split[1].split("|") + else: + postag = re.sub(r'[0-9]+', '', postag) + + # Compute the encoded value + abs_val=n_commons + rel_val=(n_commons-last_n_common) + + if (abs_val<=3 and rel_val<=-2): + c_label = (C_Label(abs_val, last_common, unary_chain, C_ABSOLUTE_ENCODING, self.separator, self.unary_joiner)) + else: + c_label = (C_Label(rel_val, last_common, unary_chain, C_RELATIVE_ENCODING, self.separator, self.unary_joiner)) + + lc_tree.add_row(word, postag, feats, c_label) + + last_n_common=n_commons + break + + # Store Last Common and increase n_commons + # Note: When increasing n_commons use the number from split the collapsed chains + n_commons += len(a.split(self.unary_joiner)) + last_common = a + + # n = max number of features of the tree + lc_tree.n = max([len(f) for f in lc_tree.additional_feats]) + return lc_tree + + def decode(self, linearized_tree): + # Check valid labels + if not linearized_tree: + print("[*] Error while decoding: Null tree.") + return + + # Create constituent tree + tree = C_Tree(C_ROOT_LABEL, []) + current_level = tree + + old_n_commons=0 + old_last_common='' + old_level=None + is_first = True + last_label = None + + for word, postag, feats, label in linearized_tree.iterrows(): + + # Convert the labels to absolute scale + if last_label!=None and label.encoding_type==C_RELATIVE_ENCODING: + label.to_absolute(last_label) + + # First label must have a positive n_commons value + if is_first and label.n_commons <= 0: + label.n_commons = 1 + + # Descend through the tree until reach the level indicated by last_common + current_level = tree + for level_index in range(label.n_commons): + if (len(current_level.children)==0) or (level_index >= old_n_commons): + current_level.add_child(C_Tree(C_NONE_LABEL, [])) + + current_level = current_level.r_child() + + # Split the Last Common field of the Label in case it has a Unary Chain Collapsed + label.last_common = label.last_common.split(self.unary_joiner) + + if len(label.last_common)==1: + # If current level has no label yet, put the label + # If current level has label but different than this one, set it as a conflict + if (current_level.label==C_NONE_LABEL): + current_level.label = label.last_common[0].rstrip() + else: + current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0] + if len(label.last_common)>1: + current_level = tree + + # problem when n_commons predicted is LESS than the number of last commons predicted + descend_levels = label.n_commons - (len(label.last_common)) + 1 + for level_index in range(descend_levels): + current_level = current_level.r_child() + for i in range(len(label.last_common)-1): + if (current_level.label == C_NONE_LABEL): + current_level.label = label.last_common[i] + else: + current_level.label = current_level.label+C_CONFLICT_SEPARATOR+label.last_common[i] + + if len(current_level.children)>0: + current_level = current_level.r_child() + + # If we reach a POS tag, set it as child of the current chain + if current_level.is_preterminal(): + temp_current_level_children = current_level.children + current_level.label = label.last_common[i+1] + current_level.children = temp_current_level_children + for c in temp_current_level_children: + c.parent = current_level + else: + current_level.label=label.last_common[i+1] + + + # Fill POS tag in this node or previous one + if (label.n_commons >= old_n_commons): + current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + else: + old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + + old_n_commons=label.n_commons + old_level=current_level + last_label=label + + tree.inherit_tree() + + return tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py b/tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py new file mode 100644 index 0000000..8ceb06b --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py @@ -0,0 +1,160 @@ +from supar.codelin.encs.abstract_encoding import ACEncoding +from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL, C_DUMMY_END +from supar.codelin.models.const_label import C_Label +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.const_tree import C_Tree + +import re + +class C_NaiveIncrementalEncoding(ACEncoding): + def __init__(self, separator, unary_joiner): + self.separator = separator + self.unary_joiner = unary_joiner + + def __str__(self): + return "Constituent Naive Incremental Encoding" + + def get_unary_chain(self, postag): + unary_chain = None + leaf_unary_chain = postag.split(self.unary_joiner) + + if len(leaf_unary_chain)>1: + unary_list = [] + for element in leaf_unary_chain[:-1]: + unary_list.append(element.split("##")[0]) + + unary_chain = self.unary_joiner.join(unary_list) + postag = leaf_unary_chain[len(leaf_unary_chain)-1] + + return unary_chain, postag + + def get_features(self, node, feature_marker="##", feature_splitter="|"): + postag_split = node.split(feature_marker) + feats = None + + if len(postag_split) > 1: + postag = re.sub(r'[0-9]+', '', postag_split[0]) + feats = postag_split[1].split(feature_splitter) + else: + postag = re.sub(r'[0-9]+', '', node) + return postag, feats + + def clean_last_common(self, node, feature_marker="##"): + node = re.sub(r'[0-9]+', '', node) + last_common = node.split(feature_marker)[0] + return last_common + + def encode(self, constituent_tree): + constituent_tree.reverse_tree() + leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner) + lc_tree = LinearizedTree.empty_tree() + + for i in range(1, len(leaf_paths)): + path_a = leaf_paths[i-1] + path_b = leaf_paths[i] + + last_common = "" + n_commons = 0 + + for a,b in zip(path_a, path_b): + if (a!=b): + # Remove the digits and aditional feats in the last common node + last_common = self.clean_last_common(last_common) + + # Get word and POS tag + word = path_a[-1] + postag = path_a[-2] + + # Build the Leaf Unary Chain + unary_chain, postag = self.get_unary_chain(postag) + + # Clean the POS Tag and extract additional features + postag, feats = self.get_features(postag) + + # Append the data + c_label = (C_Label(n_commons, last_common, unary_chain, C_ABSOLUTE_ENCODING, self.separator, self.unary_joiner)) + lc_tree.add_row(word, postag, feats, c_label) + + break + + # Store Last Common and increase n_commons + # Note: When increasing n_commons use the number from split the collapsed chains + n_commons += len(a.split(self.unary_joiner)) + last_common = a + + # reverse and return + lc_tree.reverse_tree(ignore_bos_eos=False) + return lc_tree + + def decode(self, linearized_tree): + # Check valid labels + if not linearized_tree: + print("[*] Error while decoding: Null tree.") + return + + # Create constituent tree + tree = C_Tree(C_ROOT_LABEL, []) + current_level = tree + + old_n_commons=0 + old_level=None + + linearized_tree.reverse_tree(ignore_bos_eos=False) + for word, postag, feats, label in linearized_tree.iterrows(): + + # Descend through the tree until reach the level indicated by last_common + current_level = tree + for level_index in range(label.n_commons): + if (current_level.is_terminal()) or (level_index >= old_n_commons): + current_level.add_child(C_Tree(C_NONE_LABEL, [])) + + current_level = current_level.r_child() + + # Split the Last Common field of the Label in case it has a Unary Chain Collapsed + label.last_common = label.last_common.split(self.unary_joiner) + + if len(label.last_common) == 1: + # If current level has no label yet, put the label + # If current level has label but different than this one, set it as a conflict + if (current_level.label == C_NONE_LABEL): + current_level.label = label.last_common[0] + else: + current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0] + else: + current_level = tree + + # Descend to the beginning of the Unary Chain and fill it + descend_levels = label.n_commons - (len(label.last_common)) + 1 + + for level_index in range(descend_levels): + current_level = current_level.r_child() + + for i in range(len(label.last_common)-1): + if (current_level.label == C_NONE_LABEL): + current_level.label = label.last_common[i] + else: + current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[i] + current_level = current_level.r_child() + + # If we reach a POS tag, set it as child of the current chain + if current_level.is_preterminal(): + temp_current_level = current_level + current_level.label = label.last_common[i+1] + current_level.children = [temp_current_level] + + else: + current_level.label=label.last_common[i+1] + + # Fill POS tag in this node or previous one + if (label.n_commons >= old_n_commons): + current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + + else: + old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + + old_n_commons=label.n_commons + old_level=current_level + + tree.inherit_tree() + tree.reverse_tree() + return tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_relative.py b/tania_scripts/supar/codelin/encs/enc_const/naive_relative.py new file mode 100644 index 0000000..0794e3b --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_const/naive_relative.py @@ -0,0 +1,152 @@ +from supar.codelin.encs.abstract_encoding import ACEncoding +from supar.codelin.utils.constants import C_RELATIVE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL +from supar.codelin.models.const_label import C_Label +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.const_tree import C_Tree + +import re + +class C_NaiveRelativeEncoding(ACEncoding): + def __init__(self, separator, unary_joiner): + self.separator = separator + self.unary_joiner = unary_joiner + + def __str__(self): + return "Constituent Naive Relative Encoding" + + def encode(self, constituent_tree): + leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner) + lc_tree = LinearizedTree.empty_tree() + + last_n_common=0 + for i in range(0, len(leaf_paths)-1): + path_a=leaf_paths[i] + path_b=leaf_paths[i+1] + + last_common="" + n_commons=0 + for a,b in zip(path_a, path_b): + + if (a!=b): + # Remove the digits and aditional feats in the last common node + last_common = re.sub(r'[0-9]+', '', last_common) + last_common = last_common.split("##")[0] + + # Get word and POS tag + word = path_a[-1] + postag = path_a[-2] + + # Build the Leaf Unary Chain + unary_chain = None + leaf_unary_chain = postag.split(self.unary_joiner) + if len(leaf_unary_chain)>1: + unary_list = [] + for element in leaf_unary_chain[:-1]: + unary_list.append(element.split("##")[0]) + + unary_chain = self.unary_joiner.join(unary_list) + postag = leaf_unary_chain[len(leaf_unary_chain)-1] + + # Clean the POS Tag and extract additional features + postag_split = postag.split("##") + feats = None + + if len(postag_split) > 1: + postag = re.sub(r'[0-9]+', '', postag_split[0]) + feats = postag_split[1].split("|") + else: + postag = re.sub(r'[0-9]+', '', postag) + + c_label = C_Label((n_commons-last_n_common), last_common, unary_chain, C_RELATIVE_ENCODING, self.separator, self.unary_joiner) + lc_tree.add_row(word, postag, feats, c_label) + + last_n_common=n_commons + break + + # Store Last Common and increase n_commons + # Note: When increasing n_commons use the number from split the collapsed chains + n_commons += len(a.split(self.unary_joiner)) + last_common = a + + return lc_tree + + def decode(self, linearized_tree): + # Check valid labels + if not linearized_tree: + print("[*] Error while decoding: Null tree.") + return + + # Create constituent tree + tree = C_Tree(C_ROOT_LABEL, []) + current_level = tree + + old_n_commons=0 + old_level=None + + is_first = True + last_label = None + + for word, postag, feats, label in linearized_tree.iterrows(): + # Convert the labels to absolute scale + if last_label!=None: + label.to_absolute(last_label) + + # First label must have a positive n_commons value + if is_first and label.n_commons <= 0: + label.n_commons = 1 + + # Descend through the tree until reach the level indicated by last_common + current_level = tree + for level_index in range(label.n_commons): + if (current_level.is_terminal()) or (level_index >= old_n_commons): + current_level.add_child(C_Tree(C_NONE_LABEL, [])) + current_level = current_level.r_child() + + # Split the Last Common field of the Label in case it has a Unary Chain Collapsed + label.last_common = label.last_common.split(self.unary_joiner) + + if len(label.last_common)==1: + if (current_level.label==C_NONE_LABEL): + current_level.label=label.last_common[0].rstrip() + else: + current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0] + + if len(label.last_common)>1: + current_level = tree + + # problem when n_commons predicted is LESS than the number of last commons predicted + descend_levels = label.n_commons - (len(label.last_common)) + 1 + for level_index in range(descend_levels): + current_level = current_level.r_child() + for i in range(len(label.last_common)-1): + if (current_level.label == C_NONE_LABEL): + current_level.label = label.last_common[i] + else: + current_level.label = current_level.label+C_CONFLICT_SEPARATOR+label.last_common[i] + + if len(current_level.children)>0: + current_level = current_level.r_child() + + # If we reach a POS tag, set it as child of the current chain + if current_level.is_preterminal(): + temp_current_level_children = current_level.children + current_level.label = label.last_common[i+1] + current_level.children = temp_current_level_children + for c in temp_current_level_children: + c.parent = current_level + else: + current_level.label=label.last_common[i+1] + + # Fill POS tag in this node or previous one + if (label.n_commons >= old_n_commons): + current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + else: + old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner) + + old_n_commons=label.n_commons + old_level=current_level + + last_label=label + + tree.inherit_tree() + return tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__init__.py b/tania_scripts/supar/codelin/encs/enc_deps/__init__.py new file mode 100644 index 0000000..1dd652c --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_deps/__init__.py @@ -0,0 +1,6 @@ +## Dependency Encodings Package +from .naive_absolute import D_NaiveAbsoluteEncoding +from .naive_relative import D_NaiveRelativeEncoding +from .brk_based import D_BrkBasedEncoding +from .pos_based import D_PosBasedEncoding +from .brk2p_based import D_Brk2PBasedEncoding \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5d526f8782acc6ddb352bc54ce8ef508f64fe80 GIT binary patch literal 454 zcmd1j<>g{vU|`^5UzE<t$iVOz#6iYP3=9ko3=9m#AR>h!g)xUAmobWwks*a4g(-(A zmpO_V%x2DE$z_dV1+!Ul*mBvU*uiYp9FAPhC{9L(6t-XnP4<_J3=9mKjJL#H;{6gc z%TgVait}?yOHy6)lJiqC^U{%|f>Lu5OESxlrG#AKor<!Z5{pw)kTeLn#0TUTql=1w z)fxq$i2G@BMe*f<ERIiv+FS(kAxy9cYG)BM0|P@8XHrpid=kjEA{H>eAio&OX9e-O zlZvv93ZNov3=9k_8H(5$7$C$iU;T{y+*JLN#FEU!yhOdEoWzvO)FS=l{M>?k-SmPI z-Q4_?)Excd(t<>gXi92MW}bd(UUD&rh)+o^DAtdU&&<m#iI3MSsJz8tlbfGXnv-e= P3c+Gfr13C9pa3HPs4;w& literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ce46dfd865d40f78b478a5a314786080bc9266c GIT binary patch literal 562 zcmZ3^%ge>Uz`&q*Up0f1k%8echy%k+P{wB`1_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9 zGnmbs!;;Gy#R_J#<gn$kN3nz1tT`OHoKc*N3@L2E44UjO85tNDG#PJ+yTtn?W|pNo zCKc!Bl$NBr<|XH+WagzKNd=|mB$i~BAxjCl#5)ybJ0%vUrXXn$a)}SfFGd#?0jo6% zKoR%T<hsR|2eLRm5o&W0GXnzyOt1)QXAuiXkTa<$J3a|yTM;XmUyxr6<+FkK+(|{* zMg>q2b_NE9l?<Oj0ro3eKO;XkRlg*$Br`EDQ7<VcF(os#NIyA0w;*4)B(<VMH?=G= zN53R7FEcT|IJqdZprly8xU?V<q$VXbCo@k!H7~gsM8v1078L8p$7kkcmc+;F6;%G> zu*uC&Da}c>D-vK}U;u?@aVi4?!v|(YM#cvW#urf04OH$02ICtHnio(JHWA$m3|LSR I9|Hpe07RjvbN~PV literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50aeb39bab298e183c8d9afec05cac65fb3f9a5e GIT binary patch literal 4874 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbbe00aafec12095b89292d53a158512e1969458 GIT binary patch literal 9802 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08db178e6917bb38a99b0d745ffe3f08121eeeec GIT binary patch literal 2420 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 Zj5ur{p=k#ycZ)$~B@Y7+BLs>t0RYHxX?6er literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20c2dea9b223e0a9c2a7ac3e40c647b6abc9ca0a GIT binary patch literal 4630 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 BMHc`7 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d7369766076aec1dad859894574c0db23c85e29 GIT binary patch literal 1873 zcmd1j<>g{vU|`^5Uz9$Lm4V?gh=Yt-7#J8F7#J9e0~i<>QW#Pga~N_NqZk=MY^EHh zT;?cdFq=7tC6_gd70hPIVasKYVh6KXb2xH2qc|BE+!<2XQrKG<QrJ@&o0+4yQaFMc zG&x^_?9ybs#pUSYnwOlPl9`vT$#{$1CEh17DK$rv@fM#?W?pJyQD#+YN=Q*^swU$t zHkWuPi^nD2&)?5A-pA3&)h8Kb5;A6na*9nD7#LC+q8L*cqL|tl(il@1Q<z#fqL@>d zQ&?IUqF7Q`Q`lM<qF7VdQ#e`}qS)FQSQw(%L9V+c?h@~pm|2$Um{gpfQ(BS=b7L|S z)Nl|5VuLIL;bH*>28I%bW`+ffHH-_v!4%A}lF?6-=@x5oX+dhyEsps3%)HE!_;^jG zTP($?Icc{zi&F~{ixNxni&iq;;*5_^&PgmTj*nl-@GDq9BR@A)za+6FGchkwFDWN6 zB{Q{1KRG|QAYV7VphPz}KP5Fszqqs@5hR+Dnv<EQpPH9k3?kxFQVWXp^FYpzPlUQ( zub{FB6yF@67zMdofU!yehadG|4ozkR`4WmjY!G$^nE*;0DU87knoNFGN-n7dsd*`> zdC8Ru;4o8w1)2gZ)Qb2S7#K7ei?|sW7{F`@0SdBP?D6r%B}MV^Ah}|Y%UBqz<Z-(U ztQI8}*cliYKp5<>C<X?GbcR}{8pZ_-3mF(0Y8YJ@Vnu41YnZbbYguZTvzTgGOPFg| zYglR+vRIm#YuRd;7O>W^fnuzXqlB%7aRK{6h8o5N9AJ`jAwvyQ30DnMGh;JrFhdb2 z_%yk1@f4-z=9i_$r<CUAR^H+$O3g_u$;{8Y#gdVlm{J5v4n;f+3=Fr}5(_{<Qv?dG zTb${sCGq9?MJdHm+#qH_esM`+dT|t3JS{b`r1%zdPHLVeJ2;qbaipXc#FrGMrrzR9 z1!a)bl=vJ_)+oNkl9!*7dW$J1^A=M@<}LQ*(xRf&yb?%|f&#h-9Ik8-U3{SE0tv7% zaxii*u`#kS@-gu+Dlk>a;R<AkMwBoH`J0V_fdL%G9pIF{fU$(BhOwD3g;AVgA!995 z3S%vE4dVjlg$ynXv3fBqwJf!)wQRNQHSAd|C9K&@MY1VOHSF;$HB1ZGYM5(S7BVq1 z)G#ezuVJoXg|aznm}}UxIH5eQ8s-viknUziun2Psqd7w@b0L2X(*hoF+%g3-Xfpe~ z1f|L%5TVIi#LB?H5XF_6TToI74!k09P&{yCmZTOH<(C&1$$(NI$R|<Ur3ER8C8^*T zfpba=@{6PRp)#;&Es_Qq3R4e?;#<s_c_l?cphV39j;$z;oXk9kg%ThO88dIOfTH>q z8zh!*aeyMYv?#Us7ArUwF=8tvH90>e6=YK}$OIuq7A6r!E=D#+9wr_}K1Lx%E=CR} z7Dn8$1~EXB160oBCFZ8a$KT?LkI&6dDa`?~dE(;>OA~V-GT@@1NDvejav(w-<Yr!I z0hFAYlM^40<Un4K5>OH<0%bE0E`}5(Jd7O79Lxf|U~xZ9?kE*-fuslWNls>-9;iUl zOH3**DN0N(i3caE%)Im>P$rL(M^y?g&x-XxB^M-_gL4tOflyUB@R|V<<e=;oC5PKU zP%Z+ej9ap(ib_i|bBgtn^Ye;J67x!mi$Dnj>=`8ABXSgn4J0(}KxwTQl)-rzco-p2 Ggb4tX^WjYZ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c239f14078cb1d2da6df29f582713a3c14d788e GIT binary patch literal 3173 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 L0TF2O;0OT#0&eUt literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bda4d2e8d01c87252607b4b5da3424fdb7ff31f0 GIT binary patch literal 1960 zcmd1j<>g{vU|`^5UzDE1#=!6x#6iX^3=9ko3=9m#0SpWbDGVu$ISjdsQH+crHd78$ zE^`z!n9ZESlFJ&!3TCt9u;sExv4h#HIUKp1QJjnn?hGkxDeNr_DeS3?&CF3;DICEJ znw&2|c4;!+;&OCx%}dTt$;?aFWW2@h67Q3kl$xW-c#F>`GcPr<D6=XxC8Q`dRg>`+ zn@c>D#p4q1=kMnl@8js?>XQsI2^lj(ImIRn3=F9ZQH&`JQB3U&X^bh1DNHRKQOqgK zDJ(4vQ7kE}DQqnaQLHKKDI6^fQEcrDEDTZXAlKazcZv5)%q&X{O3g_u$t+8SxiJ}L zILHnV8-|O;7#J8z7@8RtFxD_GWMpKhVX9$>XG&oRX3%8x(`3HIT3lL?T6BveK0Y%q zvm`$L7IQ{gktXvkmg3Z$v|F6TsRfBei6!|(xA-y=^U~wfit=;gi}LeJRx;k=jE_&w zNh~gok6+2~D_B1xKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`UpKv=L^n4-B{fICxU?V< zB$|?%lbNTVnwMM*BH~k03ySsgKt78vf_hD_pt6XQfq{Vo6xpCy=V9bxtWv-c0D3U@ zCo_VA0E$6u5O#){k-`|vpvmM{rR0)YkeZj0nwMOu01i+EScodXg0x70fq_Ajv51?2 zfdR~h5P}R047b?h<BLm*;^TQh<}xubFt9LI$>VkzSZy*$9n@V6><kQG40c!n0|P@k zLoHJc;{t|-42%plj4lkZ^0mx0%vp@JEH%svm=-eBvVwRijM+>@(lrcO%tg{AEVZm9 ztTn7PEHw;SY|YHIY&A>^*lXB8kzB}8!coJxfO8>34dVhXFv-1;p@yl1r-rGSv6&Sd z2)9^3@u<mri>D|xH@_@3KBY7_xAGPTBm(mDZgHig=9DDHXQU>k6oE2j5gRBdKq;#T z<ndc<i3OlQECNN&Ezb1RlKArcqLkuW+#qH_esM`+dND*iEj6*E_!e_cYMv%LI6!Z4 zq@)(amlUO@-r`FI<+Ie3_#99UE55~&m!Fb)izz4b7E?v$E%xNnqN3Ei5=h{KqNE5M z18fjo{GbRB0Y?A_BL^cJBL|}Z6AL3B6Az;TQ<WU9D1m53i4jmT1NjdeBU8YcW&vXf zQw?J?V+x}<!$QVdrWD3n<{HKY%nKP@7-CIgSZY~nS!>y9*=yLdSV~y4nTix^m=>_r zFsCprWMX8<<A(4`!1B$EHO%4+An_We1spZZH7rmzXAN@=E0oPu!(79j#SP{$r!bl` z)G`<H*Dx*M0jCP4U<OTQzn7r&Tm&LCd5c&<iIFQcx1gjF9GFGYAOVidlGLK2{PN-= z1yF>6e07Vvv>+w1Bo!Q)x0o~YO5h@(ID>Oa3-XI^@k7<Z5<-zY$QV#4YjQwiFDEk( zVxbJkLdMKnEMQ~UAhCXn0~Fz<MXANNSi!N15ql}A$@wX%a-i6gU|?VnVq{?wVdP@u zV-jQHVdi1vW8`AwU}9m!9fJ@9G&w*8S6*UnYJB`HuK4)e{FKrh5Su4HzOXbg2O<M5 zMv8<$o=^f2h9EcdLJP0t)SR67cq9k%fs}yKSP?9f7K0K$2Llfy2MY(Y06$pVPm}wW z3b-)S1NkH;GfxjxnCT@Z6_*qxCYQv6lUQb6dJ!nw-;zgF3N8za^+2T_B-s~%auvFP zP*pkb3I`J8;Or)c+dxpRf}{*tR7IsFnK{LJ$@zK3C5d?@#gOa_@+6Y)5jl**1`?Wf SptM#D%J4i4Jd6-1!UO;u4*!P$ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..269a35bd9bb6605006c7431ea0d320ed293302d0 GIT binary patch literal 3406 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 C<Q^md literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82512a33f500fe06e096da4cc221deeac69f42c8 GIT binary patch literal 2476 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..741e084997009584513b4b9673da439210e63bce GIT binary patch literal 4493 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 SJ2^w@BUt7On8Z{CjxPXujUbEw literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py b/tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py new file mode 100644 index 0000000..665e9e6 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py @@ -0,0 +1,215 @@ +from supar.codelin.encs.abstract_encoding import ADEncoding +from supar.codelin.utils.constants import D_2P_GREED, D_2P_PROP, D_NONE_LABEL +from supar.codelin.models.deps_label import D_Label +from supar.codelin.models.deps_tree import D_Tree +from supar.codelin.models.linearized_tree import LinearizedTree + + +class D_Brk2PBasedEncoding(ADEncoding): + def __init__(self, separator, displacement, planar_alg): + if planar_alg and planar_alg not in [D_2P_GREED, D_2P_PROP]: + print("[*] Error: Unknown planar separation algorithm") + exit(1) + super().__init__(separator) + self.displacement = displacement + self.planar_alg = planar_alg + + def __str__(self): + return "Dependency 2-Planar Bracketing Based Encoding" + + def get_next_edge(self, dep_tree, idx_l, idx_r): + next_arc=None + + if dep_tree[idx_l].head==idx_r: + next_arc = dep_tree[idx_l] + + elif dep_tree[idx_r].head==idx_l: + next_arc = dep_tree[idx_r] + + return next_arc + + def two_planar_propagate(self, nodes): + p1=[] + p2=[] + fp1=[] + fp2=[] + + for i in range(0, (len(nodes))): + for j in range(i, -1, -1): + # if the node in position 'i' has an arc to 'j' + # or node in position 'j' has an arc to 'i' + next_arc=self.get_next_edge(nodes, i, j) + if next_arc is None: + continue + else: + # check restrictions + if next_arc not in fp1: + p1.append(next_arc) + fp1, fp2 = self.propagate(nodes, fp1, fp2, next_arc, 2) + + elif next_arc not in fp2: + p2.append(next_arc) + fp1, fp2 = self.propagate(nodes, fp1, fp2, next_arc, 1) + return p1, p2 + def propagate(self, nodes, fp1, fp2, current_edge, i): + # add the current edge to the forbidden plane opposite to the plane + # where the node has already been added + fpi = None + fp3mi= None + if i==1: + fpi = fp1 + fp3mi= fp2 + if i==2: + fpi = fp2 + fp3mi= fp1 + + fpi.append(current_edge) + + # add all nodes from the dependency graph that crosses the current edge + # to the corresponding forbidden plane + for node in nodes: + if current_edge.check_cross(node): + if node not in fp3mi: + (fp1, fp2)=self.propagate(nodes, fp1, fp2, node, 3-i) + + return fp1, fp2 + + def two_planar_greedy(self, dep_tree): + plane_1 = [] + plane_2 = [] + + for i in range(len(dep_tree)): + for j in range(i, -1, -1): + # if the node in position 'i' has an arc to 'j' + # or node in position 'j' has an arc to 'i' + next_arc = self.get_next_edge(dep_tree, i, j) + if next_arc is None: + continue + + else: + cross_plane_1 = False + cross_plane_2 = False + for node in plane_1: + cross_plane_1 = cross_plane_1 or next_arc.check_cross(node) + for node in plane_2: + cross_plane_2 = cross_plane_2 or next_arc.check_cross(node) + + if not cross_plane_1: + plane_1.append(next_arc) + elif not cross_plane_2: + plane_2.append(next_arc) + + # processs them separately + return plane_1,plane_2 + + + def encode(self, dep_tree): + # create brackets array + n_nodes = len(dep_tree) + labels_brk = [""] * (n_nodes + 1) + + # separate the planes + if self.planar_alg==D_2P_GREED: + p1_nodes, p2_nodes = self.two_planar_greedy(dep_tree) + elif self.planar_alg==D_2P_PROP: + p1_nodes, p2_nodes = self.two_planar_propagate(dep_tree) + + # get brackets separatelly + labels_brk = self.encode_step(p1_nodes, labels_brk, ['>','/','\\','<']) + labels_brk = self.encode_step(p2_nodes, labels_brk, ['>*','/*','\\*','<*']) + + # merge and obtain labels + lbls=[] + dep_tree.remove_dummy() + for node in dep_tree: + current = D_Label(labels_brk[node.id], node.relation, self.separator) + lbls.append(current) + return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), lbls, len(lbls)) + + def encode_step(self, p, lbl_brk, brk_chars): + for node in p: + # skip root relations (optional?) + if node.head==0: + continue + if node.id < node.head: + if self.displacement: + lbl_brk[node.id+1]+=brk_chars[3] + else: + lbl_brk[node.id]+=brk_chars[3] + + lbl_brk[node.head]+=brk_chars[2] + else: + if self.displacement: + lbl_brk[node.head+1]+=brk_chars[1] + else: + lbl_brk[node.head]+=brk_chars[1] + + lbl_brk[node.id]+=brk_chars[0] + return lbl_brk + + def decode(self, lin_tree): + decoded_tree = D_Tree.empty_tree(len(lin_tree)+1) + + # create plane stacks + l_stack_p1=[] + l_stack_p2=[] + r_stack_p1=[] + r_stack_p2=[] + + current_node=1 + + for word, postag, features, label in lin_tree.iterrows(): + brks = list(label.xi) if label.xi != D_NONE_LABEL else [] + temp_brks=[] + + for i in range(0, len(brks)): + current_char=brks[i] + if brks[i]=="*": + current_char=temp_brks.pop()+brks[i] + temp_brks.append(current_char) + + brks=temp_brks + + # set parameters to the node + decoded_tree.update_word(current_node, word) + decoded_tree.update_upos(current_node, postag) + decoded_tree.update_relation(current_node, label.li) + + # fill the relation using brks + for char in brks: + if char == "<": + node_id=current_node + (-1 if self.displacement else 0) + r_stack_p1.append((node_id,char)) + + if char == "\\": + head_id = r_stack_p1.pop()[0] if len(r_stack_p1)>0 else 0 + decoded_tree.update_head(head_id, current_node) + + if char =="/": + node_id=current_node + (-1 if self.displacement else 0) + l_stack_p1.append((node_id,char)) + + if char == ">": + head_id = l_stack_p1.pop()[0] if len(l_stack_p1)>0 else 0 + decoded_tree.update_head(current_node, head_id) + + if char == "<*": + node_id=current_node + (-1 if self.displacement else 0) + r_stack_p2.append((node_id,char)) + + if char == "\\*": + head_id = r_stack_p2.pop()[0] if len(r_stack_p2)>0 else 0 + decoded_tree.update_head(head_id, current_node) + + if char =="/*": + node_id=current_node + (-1 if self.displacement else 0) + l_stack_p2.append((node_id,char)) + + if char == ">*": + head_id = l_stack_p2.pop()[0] if len(l_stack_p2)>0 else 0 + decoded_tree.update_head(current_node, head_id) + + current_node+=1 + + decoded_tree.remove_dummy() + return decoded_tree diff --git a/tania_scripts/supar/codelin/encs/enc_deps/brk_based.py b/tania_scripts/supar/codelin/encs/enc_deps/brk_based.py new file mode 100644 index 0000000..5875815 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_deps/brk_based.py @@ -0,0 +1,87 @@ +from supar.codelin.encs.abstract_encoding import ADEncoding +from supar.codelin.models.deps_label import D_Label +from supar.codelin.models.deps_tree import D_Tree +from supar.codelin.utils.constants import D_NONE_LABEL +from supar.codelin.models.linearized_tree import LinearizedTree + +class D_BrkBasedEncoding(ADEncoding): + + def __init__(self, separator, displacement): + super().__init__(separator) + self.displacement = displacement + + def __str__(self): + return "Dependency Bracketing Based Encoding" + + + def encode(self, dep_tree): + n_nodes = len(dep_tree) + labels_brk = [""] * (n_nodes + 1) + encoded_labels = [] + + # compute brackets array + # brackets array should be sorted ? + dep_tree.remove_dummy() + for node in dep_tree: + # skip root relations (optional?) + if node.head == 0: + continue + + if node.is_left_arc(): + labels_brk[node.id + (1 if self.displacement else 0)]+='<' + labels_brk[node.head]+='\\' + + else: + labels_brk[node.head + (1 if self.displacement else 0)]+='/' + labels_brk[node.id]+='>' + + # encode labels + for node in dep_tree: + li = node.relation + xi = labels_brk[node.id] + + current = D_Label(xi, li, self.separator) + encoded_labels.append(current) + + return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels)) + + def decode(self, lin_tree): + # Create an empty tree with n labels + decoded_tree = D_Tree.empty_tree(len(lin_tree)+1) + + l_stack = [] + r_stack = [] + + current_node = 1 + for word, postag, features, label in lin_tree.iterrows(): + + # get the brackets + brks = list(label.xi) if label.xi != D_NONE_LABEL else [] + + # set parameters to the node + decoded_tree.update_word(current_node, word) + decoded_tree.update_upos(current_node, postag) + decoded_tree.update_relation(current_node, label.li) + + # fill the relation using brks + for char in brks: + if char == "<": + node_id = current_node + (-1 if self.displacement else 0) + r_stack.append(node_id) + + if char == "\\": + head_id = r_stack.pop() if len(r_stack) > 0 else 0 + decoded_tree.update_head(head_id, current_node) + + if char =="/": + node_id = current_node + (-1 if self.displacement else 0) + l_stack.append(node_id) + + if char == ">": + head_id = l_stack.pop() if len(l_stack) > 0 else 0 + decoded_tree.update_head(current_node, head_id) + + current_node+=1 + + decoded_tree.remove_dummy() + return decoded_tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py b/tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py new file mode 100644 index 0000000..e624bb3 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py @@ -0,0 +1,42 @@ +from supar.codelin.encs.abstract_encoding import ADEncoding +from supar.codelin.models.deps_label import D_Label +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.deps_tree import D_Tree +from supar.codelin.utils.constants import D_NONE_LABEL + +class D_NaiveAbsoluteEncoding(ADEncoding): + def __init__(self, separator): + super().__init__(separator) + + def __str__(self): + return "Dependency Naive Absolute Encoding" + + def encode(self, dep_tree): + encoded_labels = [] + dep_tree.remove_dummy() + + for node in dep_tree: + li = node.relation + xi = node.head + + current = D_Label(xi, li, self.separator) + encoded_labels.append(current) + + return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels)) + + def decode(self, lin_tree): + dep_tree = D_Tree.empty_tree(len(lin_tree)+1) + + i=1 + for word, postag, features, label in lin_tree.iterrows(): + if label.xi == D_NONE_LABEL: + label.xi = 0 + + dep_tree.update_word(i, word) + dep_tree.update_upos(i, postag) + dep_tree.update_relation(i, label.li) + dep_tree.update_head(i, int(label.xi)) + i+=1 + + dep_tree.remove_dummy() + return dep_tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py b/tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py new file mode 100644 index 0000000..6880f27 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py @@ -0,0 +1,48 @@ +from supar.codelin.encs.abstract_encoding import ADEncoding +from supar.codelin.models.deps_label import D_Label +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.models.deps_tree import D_Tree +from supar.codelin.utils.constants import D_NONE_LABEL + +class D_NaiveRelativeEncoding(ADEncoding): + def __init__(self, separator, hang_from_root): + super().__init__(separator) + self.hfr = hang_from_root + + def __str__(self): + return "Dependency Naive Relative Encoding" + + def encode(self, dep_tree): + encoded_labels = [] + dep_tree.remove_dummy() + for node in dep_tree: + li = node.relation + xi = node.delta_head() + + if node.relation == 'root' and self.hfr: + xi = D_NONE_LABEL + + current = D_Label(xi, li, self.separator) + encoded_labels.append(current) + + return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels)) + + def decode(self, lin_tree): + dep_tree = D_Tree.empty_tree(len(lin_tree)+1) + + i = 1 + for word, postag, features, label in lin_tree.iterrows(): + if label.xi == D_NONE_LABEL: + # set as root + dep_tree.update_head(i, 0) + else: + dep_tree.update_head(i, int(label.xi)+(i)) + + + dep_tree.update_word(i, word) + dep_tree.update_upos(i, postag) + dep_tree.update_relation(i, label.li) + i+=1 + + dep_tree.remove_dummy() + return dep_tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/encs/enc_deps/pos_based.py b/tania_scripts/supar/codelin/encs/enc_deps/pos_based.py new file mode 100644 index 0000000..714efd8 --- /dev/null +++ b/tania_scripts/supar/codelin/encs/enc_deps/pos_based.py @@ -0,0 +1,89 @@ +from supar.codelin.encs.abstract_encoding import ADEncoding +from supar.codelin.models.deps_label import D_Label +from supar.codelin.models.deps_tree import D_Tree +from supar.codelin.models.linearized_tree import LinearizedTree +from supar.codelin.utils.constants import D_POSROOT, D_NONE_LABEL + +POS_ROOT_LABEL = "0--ROOT" + +class D_PosBasedEncoding(ADEncoding): + def __init__(self, separator): + super().__init__(separator) + + def __str__(self) -> str: + return "Dependency Part-of-Speech Based Encoding" + + def encode(self, dep_tree): + + print("upar/codelin/encs/enc_deps/pos_based.py") + encoded_labels = [] + + for node in dep_tree: + if node.id == 0: + # skip dummy root + continue + + li = node.relation + pi = dep_tree[node.head].upos + oi = 0 + + # move left or right depending if the node + # dependency edge is to the left or to the right + + step = 1 if node.id < node.head else -1 + for i in range(node.id + step, node.head + step, step): + if pi == dep_tree[i].upos: + oi += step + + xi = str(oi)+"--"+pi + + current = D_Label(xi, li, self.separator) + encoded_labels.append(current) + + dep_tree.remove_dummy() + return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels)) + + def decode(self, lin_tree): + dep_tree = D_Tree.empty_tree(len(lin_tree)+1) + + i = 1 + postags = lin_tree.postags + for word, postag, features, label in lin_tree.iterrows(): + node_id = i + if label.xi == D_NONE_LABEL: + label.xi = POS_ROOT_LABEL + + dep_tree.update_word(node_id, word) + dep_tree.update_upos(node_id, postag) + dep_tree.update_relation(node_id, label.li) + + oi, pi = label.xi.split('--') + oi = int(oi) + + # Set head for root + if (pi==D_POSROOT or oi==0): + dep_tree.update_head(node_id, 0) + i+=1 + continue + + # Compute head position + target_oi = oi + + step = 1 if oi > 0 else -1 + stop_point = (len(postags)+1) if oi > 0 else 0 + + for j in range(node_id+step, stop_point, step): + if (pi == postags[j-1]): + target_oi -= step + + if (target_oi==0): + break + + head_id = j + dep_tree.update_head(node_id, head_id) + + i+=1 + + + dep_tree.remove_dummy() + return dep_tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/models/__init__.py b/tania_scripts/supar/codelin/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..055dc41308b5847ea209b4ae31a538031037b6ad GIT binary patch literal 163 zcmd1j<>g{vU|`^5Uz84_AA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_x#?%* z=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>!uf!=;r39q~_=smlh;~L{n08GV}DoV#WIL i@tJv<CGqik1(mlrY;yBcN^?@}K;{=SF)%Q&FaQ9^q9&IB literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7f007831d62522735be047094f4cf4fdcc4000c GIT binary patch literal 193 zcmZ3^%ge>Uz`&q*Uo`_nKL!yn%m`(CW@BJrn9h*G5X_*-=(m!gh>3xL;WJ3`SBQQ_ zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB zK_W;^N@`AKo_=nAN@`BAetdjpUS>&ryk0@&FAkgB{FKt1RJ$Tp1_lO@Gm7~c7#Kb< QGcq!MV1N-t%nS?+0C_tx*Z=?k literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ab31bdd2279ddff308fa26008115f5475640b1c GIT binary patch literal 1556 zcmd1j<>g{vU|`^5UzD!L%E0g##6iZ)3=9ko3=9m#Y77hvDGVu$ISjdsQH;4vQB1ka zQOt}C?hGkRDa<VlDa_4GQ7kDe!3>(LFF__~GT#z*j(2nl_V)=5agBHNbM|-f^m7LZ z2D$n;hIob{3Gz6{`}zC1#``!rx%wo7v?F7<BMcZA7*ZLc7*iOcm{J&1m|7U3m{XWj zSXvmOSW;M1*jgB(SX0?j*i$%K7@8TQ*i$%z88o?Wu{+26BqpWiB(o!#3Su)cFfcfS zd}qPHz)-_d!w}C<!dS!D%vi$^&s4)y!w}D0!(76W&0Hi{!<@&M!cfBy&sxJ;!w}C_ z!&bu(&z`~%%%I8Wr^#`PH#ILgKP59SJ-(!}AoUh=W?soH&b;{K{M_99yy9EjIf=z3 zP+k!W0|Ub??$W%(qRRN>jKs{mTb#wI1&Kw8CHY0Scp&0g`I&jCMVjolSc+3~(rz*3 zCEsGoNxsEYntY2Xwd594altL7(yWyXMIsCg48J_}GxBp&^-B^<G86L>^^$TDQ!-PF z^po>*3-Wc-3rciz^HWlD^ovUi5<#LVsX3W>`e3nQ{p9?-;*$6rPyp!_RNmr<kI&4@ zEQyZ?xw4ptfq{XIk&B6qQHYU^k&CfP02-EhFlEV%NP!9pP*7}v12qB^s0>*QMcg$E zS&R#qY8bK@(is;r<}s!))-skb*Dz$UfPy-UwS+C3sYoJ)2_z%VP{WYL4kkIkBtwxV zNTh~QoI#u+m?4D`L~1ho-D0@KsHMqS1WLd~Aa~wk0R`GE=Hil~A`S)yh9Wi)0dh_e zH;Bc_z`&r%RK&}`z!1d=31yH{Pym8Mu}BmYFC6jlMX3cv@$n#a#UM#3Mkz)XMyCHD z%*V*`pNWy>KXN!glqZAy4hsqp8)Pv!9JIjUz`~HlP{WwTV9vnA5D)SrLkeRyW061# zD4Bth9YZ`5I5{!<6@h~EC5X^uhWG?z9@slD_j7^M6FAZ!ZU;FO;sNfG{P@JA;{2S_ zl2jp3;s%9<03#PD{+OzSVeyBgDjDQdnA1V3L3so0^cb+y7ckT?E@Z4_E@7-;Ze~nj z%w{SQs$q^{s%5EVO<|~I%VVu!j$sDzYS~hlYFNq`ieyWe@)%2)YuRg97O;Ryh=okG zEG4WpEH$h(Y&GmPj5SQnY{3kgEPgM+ev<%2kT@uU*lw{F7vyA?++xm2%_{=AtO%sy z7JE@@K~7?FY7r|)6~`^coLkJrsRc#Cpy(6;hXg2p73Alo=9Lr|@qrBF2N41wLJ&lN z!w5`(W12gyC_gv8xTGjEFI^H8P#~3DOgu~+;Ghy<;$akGL<AU;YEXvfh>y=p%uS7t zzr__FpPQdjnge3<#K#wwCgwn7io`&+N`nYlP}1Tl24&FX+|-hc{FEXUkT}>i2m<6T zum?f@24_AF1`b9JP7YQkc0NY1jGrd!Em?3z)=LIu>dZX7(vr-aVm)v^P6YWK6kd>! g1La|`E~G>Pwhd&_Ee;!qyX`<ptr(<Mgh7Z209FfKKmY&$ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6816f095c20760ddde9f1421313ff80f2f8e887 GIT binary patch literal 2538 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 YMju#|7!5u!U=kleVqZW6nk?Au0ACk1%>V!Z literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..069e2ef3ba4d3d9cbe4ae8d6dea1e8105dfb3d47 GIT binary patch literal 12187 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..376f81b9df97423cdc912c3eac7e7063b9e838a0 GIT binary patch literal 21102 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 QPJRT7e*u%2YQSL$0LKnirvLx| literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a316c2c1296885e31867d3fd9fabd908a3cc177 GIT binary patch literal 973 zcmd1j<>g{vU|`^5UzC21k%8ech=Yuo85kHG7#J9eg%}tZ+!<0BQW#qpQW%?=q8L(` zf*CZKlaW<}*l-;t3=9mZ3{i|J3{gxej44bl3{lJ}%qc7_3{fnptSPK1Y%L7Uj8SZ< ztSRg%9AGwk3TH5bCf6-?mw2DVq|}^b7LbWh3}Q1eFfcfSoFm4-z)-_n!w}C<!&t)* z&sf7$!w}Du!Vt``lF?6-`4(q!YC&RAVo83{EvAahTTD5bnk=_iic@paia_QRu`)0) z++r#&SjkYt!N9=q%R@gSKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`UpKv=L^n4-B{fIC zxU?V<B$|?%lbNRv7Aw|INi8Uj&jGntub}c4M|^x{US>&rJjkuZYzzzxY>aG7T#Qu$ zP*3T>6eKf3eFmaHY*5f4e8-T*Fq@%<A&U`AGR<a~%N)#51Ts~V8R7|$dazG48H+#` zfxQADI6?m7h>tHyEhvhQ2YIm=q*DyV84$^2kOasHAPfo|5C%I#3KYl;3m9q`7c#~$ z)iTvGmw*DAxrVVB?i8k5ti=U6nI%Oa4`{MPvF9Y^#21$o-C{0IEr2)^6xI+|f!t99 zb{cnDQGPB+U1nZ7Hz-0umhv(2Fjfh}f(c0lMo58FgPq93z`#(#kiwY4Si=BvlqQqk zErykh5Z5pkfkOyvE0};-otj%vQVEGL0g%-o|MM^*EJl*|)8qg}XkKD&YJB`HuK4)e z{FKrh5Su4HzOXbg2O?7h%0xvVf863J2Bo3o+|-hc{FEX-1_p*AK@b79A3=az0(K-Q v*or~QI2bq>IoOz(xfq#P_#hteD+0L>Dd@oZL0WHd*g#xj2i6brfe-@#O25RU literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9643deb605dccdecaca4931fdcf8ec1c1ad66a6b GIT binary patch literal 1396 zcmZ3^%ge>Uz`&q*Up3<#BLl-@5C?`?pp4H73=9m@8JHN{8B!Qp7*ZIQF)=W#W`fEx zL@}f=1v6+eC&L6lG)(rh8(42DLlk2QLljdAV+%tRa|%-nLljFYYYKA<!!ia2hSeY) zU>wDk%9_H0A<CY@8qA={c8lF5-X}3BH76P7G>|5cRm=<w44)0aR@E@qFvNqz!MKL8 zh9RC2%w%9-s9~yMhzF?$3#2dvGpuCv(`3HIS)5vsSd>_jUv!J9BJ&ngPNpWyEtcZc zoU|f#1_p*A4h9B>TTI0T#UOhX6ciMGh3RMH=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW z>z1Tel<20GCFbatB<5u%#uq0SWfqha>lc?6B!bkWq~>Ji>F4IBq~;Xsr=%7X$LD~2 zrB_gSiz7ZhGcU6wKE6r->Q_CO2*};V(hLj?4GcFVr8`)9_#Oy}bg=ZW-+)jZ>>cc% zK^{wn`<H=%0TePI3=18GERYf~p3P9hkOfx@=7H>h%FSgCW+-B1U|`T>h6Dl|EF?4; zi#Qn=7>Yq!6^gh)VZ#w0UzA!<gz9XF2q^4|<si-$5}Traf!}0?$sD^2{3a_*)|g-5 zHvu6IlOkRQ28Lv~{R|8YAiKdX4}ruh!ve6&(1{wxWsD3At3i$dOT{oTFw`>DGM9k# zf<?gb&RoN|jG2L9HCz<tJEmK##RWN;B}E_^O_p2iIY~M3#U(|zn2S>jAU+3s0T%TT z4|As#<>!KwW#*+<3B#faNe~n)#hPGmKM<6dE;~tfM)5^K<tu{9oopRU9Zq-o#U>QZ zFq%<(kze@=zw!kRWk?9X{ec_;D&P<(L6S>hOku2HK=+X*liw|dm5dOtFcyJg3^|s# zQ*#SSDj|st;b<g50Z_DxfF1o5>b}a0{F+zzH7{^zg5Bq*$pK2Ed5O8H@$t8~;^TAk zQ%Z9{Y@Yb|!qUVXh)fX=D6#N^k_JyPD3c`Trj}&nrxbw<FOpzjU|7ijHV+({VE2Lv zkPnM9zz%3&fWQw-EUcm*7~ljCBdh5L1~|dSz$Wy8iHTL^0|OJQ%134fHldanhyVvz zijh?dq+AOw1rq>^LL32#dcPuZkeg*e1Sl<nUG|H^2I4`xB2W?rJI|bff#Cx)BO~Jn WCP7B64-A;ZN08VT5P>EOwhaI@j3uoA literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f8e4df612a26f2cf508b2bb5fa7e85648a86b36d GIT binary patch literal 13060 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 F2LP%J4k-Wt literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca3679ea018cddc145eefe45675c608e6475204d GIT binary patch literal 21064 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 WSQxE7FkmM?g2lgpNlZ215CH((uaNNo literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6b35816c4e91140d23f0a05ada4956a3eca4872 GIT binary patch literal 5132 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30e902912d8da97efe2c282ebdf01db36bf1e563 GIT binary patch literal 9798 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 G2O9u1fGt4) literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/models/const_label.py b/tania_scripts/supar/codelin/models/const_label.py new file mode 100644 index 0000000..1df73ca --- /dev/null +++ b/tania_scripts/supar/codelin/models/const_label.py @@ -0,0 +1,38 @@ +from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_RELATIVE_ENCODING, C_NONE_LABEL + +class C_Label: + def __init__(self, nc, lc, uc, et, sp, uj): + self.encoding_type = et + + self.n_commons = int(nc) + self.last_common = lc + self.unary_chain = uc if uc != C_NONE_LABEL else None + self.separator = sp + self.unary_joiner = uj + + def __repr__(self): + unary_str = self.unary_joiner.join([self.unary_chain]) if self.unary_chain else "" + return (str(self.n_commons) + ("*" if self.encoding_type==C_RELATIVE_ENCODING else "") + + self.separator + self.last_common + (self.separator + unary_str if self.unary_chain else "")) + + def to_absolute(self, last_label): + self.n_commons+=last_label.n_commons + if self.n_commons<=0: + self.n_commons = 1 + + self.encoding_type=C_ABSOLUTE_ENCODING + + @staticmethod + def from_string(l, sep, uj): + label_components = l.split(sep) + + if len(label_components)== 2: + nc, lc = label_components + uc = None + else: + nc, lc, uc = label_components + + et = C_RELATIVE_ENCODING if '*' in nc else C_ABSOLUTE_ENCODING + nc = nc.replace("*","") + return C_Label(nc, lc, uc, et, sep, uj) + \ No newline at end of file diff --git a/tania_scripts/supar/codelin/models/const_tree.py b/tania_scripts/supar/codelin/models/const_tree.py new file mode 100644 index 0000000..e546658 --- /dev/null +++ b/tania_scripts/supar/codelin/models/const_tree.py @@ -0,0 +1,414 @@ +from supar.codelin.utils.constants import C_END_LABEL, C_START_LABEL, C_NONE_LABEL +from supar.codelin.utils.constants import C_CONFLICT_SEPARATOR, C_STRAT_MAX, C_STRAT_FIRST, C_STRAT_LAST, C_NONE_LABEL, C_ROOT_LABEL +import copy + +class C_Tree: + def __init__(self, label, children=[], feats=None): + self.parent = None + self.label = label + self.children = children + self.features = feats + +# Adders and deleters + def add_child(self, child): + ''' + Function that adds a child to the current tree + ''' + if type(child) is list: + for c in child: + self.add_child(c) + elif type(child) is C_Tree: + self.children.append(child) + child.parent = self + + else: + raise TypeError("[!] Child must be a ConstituentTree or a list of Constituent Trees") + + def add_left_child(self, child): + ''' + Function that adds a child to the left of the current tree + ''' + if type(child) is not C_Tree: + raise TypeError("[!] Child must be a ConstituentTree") + + self.children = [child] + self.children + child.parent = self + + def del_child(self, child): + ''' + Function that deletes a child from the current tree + without adding its children to the current tree + ''' + if type(child) is not C_Tree: + raise TypeError("[!] Child must be a ConstituentTree") + + self.children.remove(child) + child.parent = None + +# Getters + def r_child(self): + ''' + Function that returns the rightmost child of a tree + ''' + return self.children[len(self.children)-1] + + def l_child(self): + ''' + Function that returns the leftmost child of a tree + ''' + return self.children[0] + + def r_siblings(self): + ''' + Function that returns the right siblings of a tree + ''' + return self.parent.children[self.parent.children.index(self)+1:] + + def l_siblings(self): + ''' + Function that returns the left siblings of a tree + ''' + return self.parent.children[:self.parent.children.index(self)] + + def get_root(self): + ''' + Function that returns the root of a tree + ''' + if self.parent is None: + return self + else: + return self.parent.get_root() + + def extract_features(self, f_mark = "##", f_sep = "|"): + # go through all pre-terminal nodes + # of the tree + for node in self.get_preterminals(): + + if f_mark in node.label: + node.features = {} + label = node.label.split(f_mark)[0] + features = node.label.split(f_mark)[1] + + node.label = label + + # add features to the tree + for feature in features.split(f_sep): + + if feature == "_": + continue + + key = feature.split("=")[0] + value = feature.split("=")[1] + + node.features[key]=value + + def get_feature_names(self): + ''' + Returns a set containing all feature names + for the tree + ''' + feat_names = set() + + for child in self.children: + feat_names = feat_names.union(child.get_feature_names()) + if self.features is not None: + feat_names = feat_names.union(set(self.features.keys())) + + return feat_names + +# Word and Postags getters + def get_words(self): + ''' + Function that returns the terminal nodes of a tree + ''' + if self.is_terminal(): + return [self.label] + else: + return [node for child in self.children for node in child.get_words()] + + def get_postags(self): + ''' + Function that returns the preterminal nodes of a tree + ''' + if self.is_preterminal(): + return [self.label] + else: + return [node for child in self.children for node in child.get_postags()] + +# Terminal checking + def is_terminal(self): + ''' + Function that checks if a tree is a terminal + ''' + return len(self.children) == 0 + + def is_preterminal(self): + ''' + Function that checks if a tree is a preterminal + ''' + return len(self.children) == 1 and self.children[0].is_terminal() + +# Terminal getters + def get_terminals(self): + ''' + Function that returns the terminal nodes of a tree + ''' + if self.is_terminal(): + return [self] + else: + return [node for child in self.children for node in child.get_terminals()] + + def get_preterminals(self): + ''' + Function that returns the terminal nodes of a tree + ''' + if self.is_preterminal(): + return [self] + else: + return [node for child in self.children for node in child.get_preterminals()] + +# Tree processing + def collapse_unary(self, unary_joiner="+"): + ''' + Function that collapses unary chains + into single nodes using a unary_joiner as join character + ''' + for child in self.children: + child.collapse_unary(unary_joiner) + if len(self.children)==1 and not self.is_preterminal(): + self.label += unary_joiner + self.children[0].label + self.children = self.children[0].children + + def inherit_tree(self): + ''' + Removes the top node of the tree and delegates it + to its firstborn child. + + (S (NP (NNP John)) (VP (VBD died))) => (NP (NNP John)) + ''' + self.label = self.children[0].label + self.children = self.children[0].children + + def add_end_node(self): + ''' + Function that adds a dummy end node to the + rightmost part of the tree + ''' + self.add_child(C_Tree(C_END_LABEL, [])) + + def add_start_node(self): + ''' + Function that adds a dummy start node to the leftmost + part of the tree + ''' + self.add_left_child(C_Tree(C_START_LABEL, [])) + + def path_to_leaves(self, collapse_unary=True, unary_joiner="+"): + ''' + Function that given a Tree returns a list of paths + from the root to the leaves, encoding a level index into + nodes to make them unique. + ''' + self.add_end_node() + + if collapse_unary: + self.collapse_unary(unary_joiner) + + paths = self.path_to_leaves_rec([],[],0) + return paths + + def path_to_leaves_rec(self, current_path, paths, idx): + ''' + Recursive step of the path_to_leaves function where we store + the common path based on the current node + ''' + # pass by value + path = copy.deepcopy(current_path) + + if (len(self.children)==0): + # we are at a leaf. store the path in a new list + path.append(self.label) + paths.append(path) + else: + path.append(self.label+str(idx)) + for child in self.children: + child.path_to_leaves_rec(path, paths, idx) + idx+=1 + return paths + + def fill_pos_nodes(self, postag, word, unary_chain, unary_joiner): + if self.label == postag: + # if the current level is already a postag level. This may happen on + # trees shaped as (NP tree) that exist on the SPMRL treebanks + self.children.append(C_Tree(word, [])) + return + + if unary_chain: + unary_chain = unary_chain.split(unary_joiner) + unary_chain.reverse() + pos_tree = C_Tree(postag, [C_Tree(word, [])]) + for node in unary_chain: + temp_tree = C_Tree(node, [pos_tree]) + pos_tree = temp_tree + else: + pos_tree = C_Tree(postag, [C_Tree(word, [])]) + + self.add_child(pos_tree) + + def renounce_children(self): + ''' + Function that deletes current tree from its parent + and adds its children to the parent + ''' + self.parent.children = self.l_siblings() + self.children + self.r_siblings() + for child in self.children: + child.parent = self.parent + + + def prune_nones(self): + """ + Return a copy of the tree without + null nodes (nodes with label C_NONE_LABEL) + """ + if self.label != C_NONE_LABEL: + t = C_Tree(self.label, []) + new_childs = [c.prune_nones() for c in self.children] + t.add_child(new_childs) + return t + + else: + return [c.prune_nones() for c in self.children] + + def remove_conflicts(self, conflict_strat): + ''' + Removes all conflicts in the label of the tree generated + during the decoding process. Conflicts will be signaled by -||- + string. + ''' + for c in self.children: + if type(c) is C_Tree: + c.remove_conflicts(conflict_strat) + if C_CONFLICT_SEPARATOR in self.label: + labels = self.label.split(C_CONFLICT_SEPARATOR) + + if conflict_strat == C_STRAT_MAX: + self.label = max(set(labels), key=labels.count) + if conflict_strat == C_STRAT_FIRST: + self.label = labels[0] + if conflict_strat == C_STRAT_LAST: + self.label = labels[len(labels)-1] + + def postprocess_tree(self, conflict_strat, clean_nulls=True, default_root="S"): + ''' + Returns a C_Tree object with conflicts in node labels removed + and with NULL nodes cleaned. + ''' + if clean_nulls: + if self.label == C_NONE_LABEL or self.label==C_ROOT_LABEL: + self.label = default_root + t = self.prune_nones() + else: + t = self + t.remove_conflicts(conflict_strat) + return t + + # print( fix_tree) + + def reverse_tree(self): + ''' + Reverses the order of all the tree children + ''' + for c in self.children: + if type(c) is C_Tree: + c.reverse_tree() + self.children.reverse() + +# Printing and python-related functions + def __str__(self): + if len(self.children) == 0: + label_str = self.label + + if self.features is not None: + features_str = "##" + "|".join([key+"="+value for key,value in self.features.items()]) + + label_str = label_str.replace("(","-LRB-") + label_str = label_str.replace(")","-RRB-") + else: + label_str = "(" + self.label + " " + if self.features is not None: + features_str = "##"+ "|".join([key+"="+value for key,value in self.features.items()]) + + label_str += " ".join([str(child) for child in self.children]) + ")" + return label_str + + def __repr__(self): + return self.__str__() + + def __eq__(self, other): + if isinstance(other, C_Tree): + return self.label == other.label and self.children == other.children + return False + + def __hash__(self): + return hash((self.label, tuple(self.children))) + + def __len__(self): + return len(self.children) + + def __iter__(self): + yield self.label + for child in self.children: + yield child + + def __contains__(self, item): + return item in self.label or item in self.children + + +# Tree creation + @staticmethod + def from_string(s): + s = s.replace("(","( ") + s = s.replace(")"," )") + s = s.split(" ") + + # create dummy label and append it to the stack + stack = [] + i=0 + while i < (len(s)): + if s[i]=="(": + # If we find a l_brk we create a new tree + # with label=next_word. Skip next_word. + w = s[i+1] + t = C_Tree(w, []) + stack.append(t) + i+=1 + + elif s[i]==")": + # If we find a r_brk set top of the stack + # as children to the second top of the stack + + t = stack.pop() + + if len(stack)==0: + return t + + pt = stack.pop() + pt.add_child(t) + stack.append(pt) + + else: + # If we find a word set it as children + # of the current tree. + t = stack.pop() + w = s[i] + c = C_Tree(w, []) + t.add_child(c) + stack.append(t) + + i+=1 + return t + +# Default trees + @staticmethod + def empty_tree(): + return C_Tree(C_NONE_LABEL, []) \ No newline at end of file diff --git a/tania_scripts/supar/codelin/models/deps_label.py b/tania_scripts/supar/codelin/models/deps_label.py new file mode 100644 index 0000000..ada0b83 --- /dev/null +++ b/tania_scripts/supar/codelin/models/deps_label.py @@ -0,0 +1,18 @@ +class D_Label: + def __init__(self, xi, li, sp): + self.separator = sp + + self.xi = xi # dependency relation + self.li = li # encoding + + def __repr__(self): + return f'{self.xi}{self.separator}{self.li}' + + @staticmethod + def from_string(lbl_str, sep): + xi, li = lbl_str.split(sep) + return D_Label(xi, li, sep) + + @staticmethod + def empty_label(separator): + return D_Label("", "", separator) diff --git a/tania_scripts/supar/codelin/models/deps_tree.py b/tania_scripts/supar/codelin/models/deps_tree.py new file mode 100644 index 0000000..4313026 --- /dev/null +++ b/tania_scripts/supar/codelin/models/deps_tree.py @@ -0,0 +1,371 @@ +from supar.codelin.utils.constants import D_ROOT_HEAD, D_NULLHEAD, D_ROOT_REL, D_POSROOT, D_EMPTYREL + +class D_Node: + def __init__(self, wid, form, lemma=None, upos=None, xpos=None, feats=None, head=None, deprel=None, deps=None, misc=None): + self.id = int(wid) # word id + + self.form = form if form else "_" # word + self.lemma = lemma if lemma else "_" # word lemma/stem + self.upos = upos if upos else "_" # universal postag + self.xpos = xpos if xpos else "_" # language_specific postag + self.feats = self.parse_feats(feats) if feats else "_" # morphological features + + self.head = int(head) # id of the word that depends on + self.relation = deprel # type of relation with head + + self.deps = deps if deps else "_" # enhanced dependency graph + self.misc = misc if misc else "_" # miscelaneous data + + def is_left_arc(self): + return self.head > self.id + + def delta_head(self): + return self.head - self.id + + def parse_feats(self, feats): + if feats == '_': + return [None] + else: + return [x for x in feats.split('|')] + + def check_cross(self, other): + if ((self.head == other.head) or (self.head==other.id)): + return False + + r_id_inside = (other.head < self.id < other.id) + l_id_inside = (other.id < self.id < other.head) + + id_inside = r_id_inside or l_id_inside + + r_head_inside = (other.head < self.head < other.id) + l_head_inside = (other.id < self.head < other.head) + + head_inside = r_head_inside or l_head_inside + + return head_inside^id_inside + + def __repr__(self): + return '\t'.join(str(e) for e in list(self.__dict__.values()))+'\n' + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + + @staticmethod + def from_string(conll_str): + wid,form,lemma,upos,xpos,feats,head,deprel,deps,misc = conll_str.split('\t') + return D_Node(int(wid), form, lemma, upos, xpos, feats, int(head), deprel, deps, misc) + + @staticmethod + def dummy_root(): + return D_Node(0, D_POSROOT, None, D_POSROOT, None, None, 0, D_EMPTYREL, None, None) + + @staticmethod + def empty_node(): + return D_Node(0, None, None, None, None, None, 0, None, None, None) + +class D_Tree: + def __init__(self, nodes): + self.nodes = nodes + +# getters + def get_node(self, id): + return self.nodes[id-1] + + def get_edges(self): + ''' + Return sentence dependency edges as a tuple + shaped as ((d,h),r) where d is the dependant of the relation, + h the head of the relation and r the relationship type + ''' + return list(map((lambda x :((x.id, x.head), x.relation)), self.nodes)) + + def get_arcs(self): + ''' + Return sentence dependency edges as a tuple + shaped as (d,h) where d is the dependant of the relation, + and h the head of the relation. + ''' + return list(map((lambda x :(x.id, x.head)), self.nodes)) + + def get_relations(self): + ''' + Return a list of relationships betwee nodes + ''' + return list(map((lambda x :x.relation), self.nodes)) + + def get_sentence(self): + ''' + Return the sentence as a string + ''' + return " ".join(list(map((lambda x :x.form), self.nodes))) + + def get_words(self): + ''' + Returns the words of the sentence as a list + ''' + return list(map((lambda x :x.form), self.nodes)) + + def get_indexes(self): + ''' + Returns a list of integers representing the words of the + dependency tree + ''' + return list(map((lambda x :x.id), self.nodes)) + + def get_postags(self): + ''' + Returns the part of speech tags of the tree + ''' + return list(map((lambda x :x.upos), self.nodes)) + + def get_lemmas(self): + ''' + Returns the lemmas of the tree + ''' + return list(map((lambda x :x.lemma), self.nodes)) + + def get_heads(self): + ''' + Returns the heads of the tree + ''' + return list(map((lambda x :x.head), self.nodes)) + + def get_feats(self): + ''' + Returns the morphological features of the tree + ''' + return list(map((lambda x :x.feats), self.nodes)) + +# update functions + def append_node(self, node): + ''' + Append a node to the tree and sorts the nodes by id + ''' + self.nodes.append(node) + self.nodes.sort(key=lambda x: x.id) + + def update_head(self, node_id, head_value): + ''' + Update the head of a node indicated by its id + ''' + for node in self.nodes: + if node.id == node_id: + node.head = head_value + break + + def update_relation(self, node_id, relation_value): + ''' + Update the relation of a node indicated by its id + ''' + for node in self.nodes: + if node.id == node_id: + node.relation = relation_value + break + + def update_word(self, node_id, word): + ''' + Update the word of a node indicated by its id + ''' + for node in self.nodes: + if node.id == node_id: + node.form = word + break + + def update_upos(self, node_id, postag): + ''' + Update the upos field of a node indicated by its id + ''' + for node in self.nodes: + if node.id == node_id: + node.upos = postag + break + +# properties functions + def is_projective(self): + ''' + Returns a boolean indicating if the dependency tree + is projective (i.e. no edges are crossing) + ''' + arcs = self.get_arcs() + for (i,j) in arcs: + for (k,l) in arcs: + if (i,j) != (k,l) and min(i,j) < min(k,l) < max(i,j) < max(k,l): + return False + return True + +# postprocessing + def remove_dummy(self): + self.nodes = self.nodes[1:] + + def postprocess_tree(self, search_root_strat, allow_multi_roots=False): + ''' + Postprocess the tree by finding the root according to the selected + strategy and fixing cycles and out of bounds heads + ''' + # 1) Find the root + root = self.root_search(search_root_strat) + + # 2) Fix oob heads + self.fix_oob_heads() + + # 3) Fix cycles + self.fix_cycles(root) + + # 4) Set all null heads to root and remove other root candidates + for node in self.nodes: + if node.id == root: + node.head = 0 + continue + if node.head == D_NULLHEAD: + node.head = root + if not allow_multi_roots and node.head == 0: + node.head = root + + def root_search(self, search_root_strat): + ''' + Search for the root of the tree using the method indicated + ''' + root = 1 # Default root + for node in self.nodes: + if search_root_strat == D_ROOT_HEAD: + if node.head == 0: + root = node.id + break + + elif search_root_strat == D_ROOT_REL: + if node.rel == 'root' or node.rel == 'ROOT': + root = node.id + break + return root + + def fix_oob_heads(self): + ''' + Fixes heads of the tree (if they dont exist, if they are out of bounds, etc) + If a head is out of bounds set it to nullhead + ''' + for node in self.nodes: + if node.head==D_NULLHEAD: + continue + if int(node.head) < 0: + node.head = D_NULLHEAD + elif int(node.head) > len(self.nodes): + node.head = D_NULLHEAD + + def fix_cycles(self, root): + ''' + Breaks cycles in the tree by setting the head of the node to root_id + ''' + for node in self.nodes: + visited = [] + + while (node.id != root) and (node.head !=D_NULLHEAD): + if node in visited: + node.head = D_NULLHEAD + else: + visited.append(node) + next_node = min(max(node.head-1, 0), len(self.nodes)-1) + node = self.nodes[next_node] + +# python related functions + def __repr__(self): + return "".join(str(e) for e in self.nodes)+"\n" + + def __iter__(self): + for n in self.nodes: + yield n + + def __getitem__(self, key): + return self.nodes[key] + + def __len__(self): + return self.nodes.__len__() + +# base tree + @staticmethod + def empty_tree(l=1): + ''' + Creates an empty dependency tree with l nodes + ''' + t = D_Tree([]) + for i in range(l): + n = D_Node.empty_node() + n.id = i + t.append_node(n) + return t + +# reader and writter + @staticmethod + def from_string(conll_str, dummy_root=True, clean_contractions=True, clean_omisions=True): + ''' + Create a ConllTree from a dependency tree conll-u string. + ''' + data = conll_str.split('\n') + dependency_tree_start_index = 0 + for line in data: + if len(line)>0 and line[0]!="#": + break + dependency_tree_start_index+=1 + data = data[dependency_tree_start_index:] + nodes = [] + if dummy_root: + nodes.append(D_Node.dummy_root()) + + for line in data: + # check if not valid line (empty or not enough fields) + if (len(line)<=1) or len(line.split('\t'))<10: + continue + + wid = line.split('\t')[0] + + # check if node is a comment (comments are marked with #) + if "#" in wid: + continue + + # check if node is a contraction (multiexp lines are marked with .) + if clean_contractions and "-" in wid: + continue + + # check if node is an omited word (empty nodes are marked with .) + if clean_omisions and "." in wid: + continue + + conll_node = D_Node.from_string(line) + nodes.append(conll_node) + + return D_Tree(nodes) + + @staticmethod + def read_conllu_file(file_path, filter_projective = True): + ''' + Read a conllu file and return a list of ConllTree objects. + ''' + with open(file_path, 'r') as f: + data = f.read() + data = data.split('\n\n') + # remove last empty line + data = data[:-1] + + trees = [] + for x in data: + t = D_Tree.from_string(x) + if not filter_projective or t.is_projective(): + trees.append(t) + return trees + + @staticmethod + def write_conllu_file(file_path, trees): + ''' + Write a list of ConllTree objects to a conllu file. + ''' + with open(file_path, 'w') as f: + f.write("".join(str(e) for e in trees)) + + @staticmethod + def write_conllu(file_io, tree): + ''' + Write a single ConllTree to a already open file. + Includes the # text = ... line + ''' + file_io.write("# text = "+tree.get_sentence()+"\n") + file_io.write("".join(str(e) for e in tree)+"\n") \ No newline at end of file diff --git a/tania_scripts/supar/codelin/models/linearized_tree.py b/tania_scripts/supar/codelin/models/linearized_tree.py new file mode 100644 index 0000000..1619b31 --- /dev/null +++ b/tania_scripts/supar/codelin/models/linearized_tree.py @@ -0,0 +1,179 @@ +from supar.codelin.utils.constants import BOS, EOS, C_NO_POSTAG_LABEL +from supar.codelin.models.const_label import C_Label +from supar.codelin.models.deps_label import D_Label + +class LinearizedTree: + def __init__(self, words, postags, additional_feats, labels, n_feats): + self.words = words + self.postags = postags + self.additional_feats = additional_feats + self.labels = labels + #len(f_idx_dict.keys()) = n_feats + + def get_sentence(self): + return "".join(self.words) + + def get_labels(self): + return self.labels + + def get_word(self, index): + return self.words[index] + + def get_postag(self, index): + return self.postags[index] + + def get_additional_feat(self, index): + return self.additional_feats[index] if len(self.additional_feats) > 0 else None + + def get_label(self, index): + return self.labels[index] + + def reverse_tree(self, ignore_bos_eos=True): + ''' + Reverses the lists of words, postags, additional_feats and labels. + Do not reverses the first (BOS) and last (EOS) elements + ''' + if ignore_bos_eos: + self.words = self.words[1:-1][::-1] + self.postags = self.postags[1:-1][::-1] + self.additional_feats = self.additional_feats[1:-1][::-1] + self.labels = self.labels[1:-1][::-1] + else: + self.words = self.words[::-1] + self.postags = self.postags[::-1] + self.additional_feats = self.additional_feats[::-1] + self.labels = self.labels[::-1] + + def add_row(self, word, postag, additional_feat, label): + self.words.append(word) + self.postags.append(postag) + self.additional_feats.append(additional_feat) + self.labels.append(label) + + def iterrows(self): + for i in range(len(self)): + yield self.get_word(i), self.get_postag(i), self.get_additional_feat(i), self.get_label(i) + + def __len__(self): + return len(self.words) + + def __repr__(self): + return self.to_string() + + def to_string(self, f_idx_dict=None, add_bos_eos=True): + if add_bos_eos: + self.words = [BOS] + self.words + [EOS] + self.postags = [BOS] + self.postags + [EOS] + if f_idx_dict: + self.additional_feats = [len(f_idx_dict.keys()) * [BOS]] + self.additional_feats + [len(f_idx_dict.keys()) * [EOS]] + else: + self.additional_feats = [] + + self.labels = [BOS] + self.labels + [EOS] + + tree_string = "" + for w, p, af, l in self.iterrows(): + # create the output line of the linearized tree + output_line = [w,p] + + # check for features + if f_idx_dict: + if w == BOS: + f_list = [BOS] * (len(f_idx_dict.keys())+1) + elif w == EOS: + f_list = [EOS] * (len(f_idx_dict.keys())+1) + else: + f_list = ["_"] * (len(f_idx_dict.keys())+1) + + if af != [None]: + for element in af: + key, value = element.split("=", 1) if len(element.split("=",1))==2 else (None, None) + if key in f_idx_dict.keys(): + f_list[f_idx_dict[key]] = value + + # append the additional elements or the placehodler + for element in f_list: + output_line.append(element) + + # add the label + output_line.append(str(l)) + tree_string+=u"\t".join(output_line)+u"\n" + + if add_bos_eos: + self.words = self.words[1:-1] + self.postags = self.postags[1:-1] + if f_idx_dict: + self.additional_feats = self.additional_feats[len(f_idx_dict.keys()):-len(f_idx_dict.keys())] + self.labels = self.labels[1:-1] + + return tree_string + + @staticmethod + def empty_tree(n_feats = 1): + temp_tree = LinearizedTree(labels=[], words=[], postags=[], additional_feats=[], n_feats=n_feats) + return temp_tree + + @staticmethod + def from_string(content, mode, separator="_", unary_joiner="|", n_features=0): + ''' + Reads a linearized tree from a string shaped as + -BOS- \t -BOS- \t (...) \t -BOS- \n + word \t postag \t (...) \t label \n + word \t postag \t (...) \t label \n + -EOS- \t -EOS- \t (...) \t -EOS- \n + ''' + labels = [] + words = [] + postags = [] + additional_feats = [] + + linearized_tree = None + for line in content.split("\n"): + if line=="\n": + print("Empty line") + # skip empty line + if len(line) <= 1: + continue + + # Separate the label file into columns + line_columns = line.split("\t") if ("\t") in line else line.split(" ") + word = line_columns[0] + + if BOS == word: + labels = [] + words = [] + postags = [] + additional_feats = [] + + continue + + if EOS == word: + linearized_tree = LinearizedTree(words, postags, additional_feats, labels, n_features) + continue + + if len(line_columns) == 2: + word, label = line_columns + postag = C_NO_POSTAG_LABEL + feats = "_" + elif len(line_columns) == 3: + word, postag, label = line_columns[0], line_columns[1], line_columns[2] + feats = "_" + else: + word, postag, *feats, label = line_columns[0], line_columns[1], line_columns[1:-1], line_columns[-1] + + # Check for predictions with no label + if BOS in label or EOS in label: + label = "1"+separator+"ROOT" + + words.append(word) + postags.append(postag) + if mode == "CONST": + labels.append(C_Label.from_string(label, separator, unary_joiner)) + elif mode == "DEPS": + labels.append(D_Label.from_string(label, separator)) + else: + raise ValueError("[!] Unknown mode: %s" % mode) + + additional_feats.append(feats) + + return linearized_tree \ No newline at end of file diff --git a/tania_scripts/supar/codelin/utils/__init__.py b/tania_scripts/supar/codelin/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e624705816d7181d4f932b5d47cf136958510862 GIT binary patch literal 162 zcmd1j<>g{vU|`^5Uz84_AA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_x$0-+ z=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>!uf!=;r39q~_=smlh;~L{n08GV}CHOEPnc k_2c6+^D;}~<Mj$EZ*kb<=BJeAq}qXuFJ@w3U|?YY0H7}>LjV8( literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d9b483a30076ad9fcf5cd79e963435945670210 GIT binary patch literal 192 zcmZ3^%ge>Uz`&q*Uo`_nKL!yn%m`(CW@BJrn9h*G5X_*-=(m!gh>3xL;WJ3`SFnCY zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB zK_W;^N@`AKo_=XbW=^qwe0*kJW=VX!UP0wA4x8Nkl+v73yCPNw1_qETiuoBB7(OsF PGBSQ(fDuK^3=9kaLEbTh literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-310.pyc b/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..653174b605a0b2dafa036c155f450c26128665e9 GIT binary patch literal 1112 zcmd1j<>g{vU|`^5UzEO^nStRkh=Yt785kHG7#J9edl(oPQW&BbQW&EcQ<$QdQkbKd zQ&^%{Qdpx{Q`n-|QrM%|Q#hhHQaGbHQ@EnIQn;hIQ+T3yQh1|yQ~09zQuw3zQv{*} zQUs#}Q-q>~QiP*~Q$(UfQuv}oQ`n-!QrM%!Q$(XAQpBPpQ^cdBQY50JQzWBgQlz3} zQv{;qQlz8gQ)HqPQe>kPQ{;jfH07&UbzS{~b*or)o&1A!Z?QW2`vr&GVsUW|2)@Pa z>gRlm*~Qg4irLXAIEp#Q)hCMCCDJd7+0)NCio3X^D6u3yEwiY&B#H~d$w@3Oxy1=# z=O$Lbg!A(AQmfc>{rvr0b*tEQ{rm$!R<h{^`TK`}takNt0f`5PI0l92R<Y>T)aXWW zx`g`rM#j7Px!ht7@DGk+b_(*2Vsi@ejyDR3Vs#I4b#;m23<&ZMaCCPJaRr+i<m#gf zvL@8WM>mQW;)?Xtl8n^ElqeoJw<tBoPgCg@v#WpbEoLYG;3!_Vc(AWMLqc8sLZW!w z;$2(=T>V^J{hTAC*!%<HUHzQFG$<s5o#P#yg8h9$LtH`P{w|(=?oq<d@j<RWjv=05 zNP<Gn@h*{mj=rAG2!&$K@t%IpL9V{8ej$!N2ytHL_~4Kr$B=k8&!FItC>|Ks$1yl0 ziW|oBb&NnrfdUi61JUt5j!v#Vw*;Nz{ruwt{DVUr-629C1)xBN^0+}xae;Ecb~*-y zK)E8$pipr0@pKM}4|WZ33~~(d4+7bZhzA~*c!X_H!Y<fC!Uao6@VS5-h48JAOT1H% zqqDbb2trI0Q!L&n;1-ulyiq_rIJR$bg4v)bkK%HPcl8Yji3FucPO#}9UxI}FLVbKZ zTpeAaxLx8wV)0-O7nBp^>a&ueh?ju@Li}>m&&bbB)h|gb$xO^k)Jw`qOvy|w(ofFM zEy&kRFDTK?%}+_q(JwA7NCb(dq~>Ji>6eyd<`nBE=jRodB<7VA>lIYq;;_lhPbtkw swFBk!ViyJm1{Nk3MmT0+VFW{v7>EVqgV>BLEMRpIHb@0TmWhKA0Gn+mj{pDw literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-311.pyc b/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee60e7632471dbdadeb0deae1b865ffba40f7ef2 GIT binary patch literal 1260 zcmZ3^%ge>Uz`&q*Uo~SlGXuk85C?`Cp^VRc3=9m@8B!Rc7*ZIc7*m*{m{ORdm{VAy zSW;M{SX0=d*izV|*i$&7I8r#HI8(TyxKg;IxKntdcv5(ycvJYI_)_?z_)`R;1X2W} z1XF~fgi?f~gi}PKL{j*oL{r$J#8TL!#8X70BvQnpBvZtrq*5fJq*ElLWKyJ}WK#s9 z<Wi)g<Wpp#6jEfP6jS7a88qdqSan_fgLSJ|b)Ec!b#Jjc`}+ll++uNY4G6x)?CR%y zi`m81`4+RIQ}8Y3AXlGT%r23Bx0pTsoNsX#mlP$I#HVEz6_?!Nf^c#Yi%V{CLfE;9 z6)@qv{JhjEHeEk|KUdu<c3nUJ0Faezx<UT_At0+={aire!6A-8A-Yv8x-~Vrw>Vuw zeSIV2UHx2cF$eeu-(q$O^1j996yzOm6mW~xJ;>G7<rZf^kbi)qyJLte*wi3bA6<|& zp*}vkw|F70NKY-vNKH(+#RKOSrRMl)D&1ms1sm!ge2dpD9_(w+kWg2@kXt-%@h+|b zu6{1Ae$J7%*!%<HLBRl`K_MaR9Pj89?C%pA;tCS?ck%Rdza{J(ALQ!e7~&a*Bq-z@ z?-J?f=<Df>P$=dc@9F0p<m&6{7vkuH5a)G{4-N@(42gI13<?gp#RKE|I0lE@;)d~j z9U~A@puhz2Ky<v1qm!%8EkWmaKmYgu|KJcucc>7Lb37=Jp*(JoQ(T}Nu$_)UAyBS} zGbj|?d_0{);)7iS9D^J~{DVMtBjSO_B_7E(VHa#6;esV3_*_7aLikq5CEh8>(b?NI z1R*AhDF%vYE|++tfOu$ZgV~@czs2Pe@9G;65(!F?oM6*Iz61&Th5Gn-xH`Jr;&y@f z9L(W@a)MlaRx*4B<;Pzk`WgATsrn^}C7FqNiF!#ni7A<>Mf%D4xdr*UC8-r9x~XM} zIr=4ud6|jv#mPmP1trD$#ia#_AT=qeIhlF-r6rj;#rnzldBr7(c_qbq1(m-zY;yBc zN^?@}imVwJ7(h9{_&5Ut!v|(YM#c|p4D5Uj%s1G08<-ymh&S-w;1_M+dBDlnz;**f zeBfXZm$|?od_zncM2bpXU=X??DR+TE>;a#21Mdx9$p)SqJmL-9VAcl?1_6l%o*N>v z7Z?O@@QXL_+~5;!;JzUs*}!{4T=oKk$PGTp25zXb2M{wMq@Y*>-wlZI5(*a>L?7^q nG;o1T=KR3Hz$Xr3i!^ZF;1zA)dcY?OvQN5!3j~WS85kG<BE5f{ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/codelin/utils/constants.py b/tania_scripts/supar/codelin/utils/constants.py new file mode 100644 index 0000000..66b0745 --- /dev/null +++ b/tania_scripts/supar/codelin/utils/constants.py @@ -0,0 +1,54 @@ +# COMMON CONSTANTS + +EOS = "-EOS-" +BOS = "-BOS-" + +F_CONSTITUENT = "CONST" +F_DEPENDENCY = "DEPS" + +OP_ENC = "ENC" +OP_DEC = "DEC" + +# CONSTITUENT ENCODINGS + +C_ABSOLUTE_ENCODING = 'ABS' +C_RELATIVE_ENCODING = 'REL' +C_DYNAMIC_ENCODING = 'DYN' +C_INCREMENTAL_ENCODING = 'INC' + +C_STRAT_FIRST="strat_first" +C_STRAT_LAST="strat_last" +C_STRAT_MAX="strat_max" +C_STRAT_NONE="strat_none" + +# CONSTITUENT MISC + +C_NONE_LABEL = "-NONE-" +C_NO_POSTAG_LABEL = "-NOPOS-" +C_ROOT_LABEL = "-ROOT-" +C_END_LABEL = "-END-" +C_START_LABEL = "-START-" +C_CONFLICT_SEPARATOR = "-||-" +C_DUMMY_END = "DUMMY_END" + +# DEPENDENCIY ENCODINGS + +D_NONE_LABEL = "-NONE-" + +D_ABSOLUTE_ENCODING = 'ABS' +D_RELATIVE_ENCODING = 'REL' +D_POS_ENCODING = 'POS' +D_BRACKET_ENCODING = 'BRK' +D_BRACKET_ENCODING_2P = 'BRK_2P' + +D_2P_GREED = 'GREED' +D_2P_PROP = 'PROPAGATE' + +# DEPENDENCY MISC + +D_EMPTYREL = "-NOREL-" +D_POSROOT = "-ROOT-" +D_NULLHEAD = "-NULL-" + +D_ROOT_HEAD = "strat_gethead" +D_ROOT_REL = "strat_getrel" diff --git a/tania_scripts/supar/codelin/utils/extract_feats.py b/tania_scripts/supar/codelin/utils/extract_feats.py new file mode 100644 index 0000000..be867de --- /dev/null +++ b/tania_scripts/supar/codelin/utils/extract_feats.py @@ -0,0 +1,41 @@ +import argparse +from supar.codelin.models.const_tree import C_Tree +from supar.codelin.models.deps_tree import D_Tree + +def extract_features_const(in_path): + file_in = open(in_path, "r") + feats_set = set() + for line in file_in: + line = line.rstrip() + tree = C_Tree.from_string(line) + tree.extract_features() + feats = tree.get_feature_names() + + feats_set = feats_set.union(feats) + + return sorted(feats_set) + +def extract_features_deps(in_path): + feats_list=set() + trees = D_Tree.read_conllu_file(in_path, filter_projective=False) + for t in trees: + for node in t: + if node.feats != "_": + feats_list = feats_list.union(a for a in (node.feats.keys())) + return sorted(feats_list) + + +''' +Python script that returns a ordered list of the features +included in a conll tree or a constituent tree +''' + +# parser = argparse.ArgumentParser(description='Prints all features in a constituent treebank') +# parser.add_argument('form', metavar='formalism', type=str, choices=['CONST','DEPS'], help='Grammar encoding the file to extract features') +# parser.add_argument('input', metavar='in file', type=str, help='Path of the file to clean (.trees file).') +# args = parser.parse_args() +# if args.form=='CONST': +# feats = extract_features_const(args.input) +# elif args.form=='DEPS': +# feats = extract_features_conll(args.input) +# print(" ".join(feats)) diff --git a/tania_scripts/supar/model.py b/tania_scripts/supar/model.py new file mode 100644 index 0000000..f2d5277 --- /dev/null +++ b/tania_scripts/supar/model.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence + +from supar.modules import (CharLSTM, ELMoEmbedding, IndependentDropout, + SharedDropout, TransformerEmbedding, + TransformerWordEmbedding, VariationalLSTM) +from supar.modules.transformer import (TransformerEncoder, + TransformerEncoderLayer) +from supar.utils import Config +#from supar.vector_quantize import VectorQuantize + +from vector_quantize_pytorch import VectorQuantize + + +class Model(nn.Module): + + def __init__(self, + n_words, + n_tags=None, + n_chars=None, + n_lemmas=None, + encoder='lstm', + feat=['tag', 'char'], + n_embed=300, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=45, + n_char_hidden=100, + char_pad_index=0, + char_dropout=0, + elmo_bos_eos=(True, True), + elmo_dropout=0.5, + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + encoder_dropout=.33, + pad_index=0, + + n_decoder_layers: int = 2, + bidirectional: bool = False, + + use_vq=False, + vq_passes: int = 300, + codebook_size=512, + vq_decay=0.3, + commitment_weight=3, + + **kwargs): + super().__init__() + + self.args = Config().update(locals()) + + if encoder == 'lstm': + self.word_embed = nn.Embedding(num_embeddings=self.args.n_words, + embedding_dim=self.args.n_embed) + + n_input = self.args.n_embed + + if self.args.n_pretrained != self.args.n_embed: + n_input += self.args.n_pretrained + if 'tag' in self.args.feat: + self.tag_embed = nn.Embedding(num_embeddings=self.args.n_tags, + embedding_dim=self.args.n_feat_embed) + n_input += self.args.n_feat_embed + + if 'char' in self.args.feat: + self.char_embed = CharLSTM(n_chars=self.args.n_chars, + n_embed=self.args.n_char_embed, + n_hidden=self.args.n_char_hidden, + n_out=self.args.n_feat_embed, + pad_index=self.args.char_pad_index, + dropout=self.args.char_dropout) + n_input += self.args.n_feat_embed + + + if 'lemma' in self.args.feat: + self.lemma_embed = nn.Embedding(num_embeddings=self.args.n_lemmas, + embedding_dim=self.args.n_feat_embed) + n_input += self.args.n_feat_embed + if 'elmo' in self.args.feat: + self.elmo_embed = ELMoEmbedding(n_out=self.args.n_plm_embed, + bos_eos=self.args.elmo_bos_eos, + dropout=self.args.elmo_dropout, + finetune=self.args.finetune) + n_input += self.elmo_embed.n_out + if 'bert' in self.args.feat: + self.bert_embed = TransformerEmbedding(name=self.args.bert, + n_layers=self.args.n_bert_layers, + n_out=self.args.n_plm_embed, + pooling=self.args.bert_pooling, + pad_index=self.args.bert_pad_index, + mix_dropout=self.args.mix_dropout, + finetune=self.args.finetune) + n_input += self.bert_embed.n_out + self.embed_dropout = IndependentDropout(p=self.args.embed_dropout) + self.encoder = VariationalLSTM( + input_size=n_input, + hidden_size=self.args.n_encoder_hidden//2 if self.args.bidirectional else self.args.n_encoder_hidden, + num_layers=self.args.n_encoder_layers, bidirectional=self.args.bidirectional, + dropout=self.args.encoder_dropout) + self.encoder_dropout = SharedDropout(p=self.args.encoder_dropout) + elif encoder == 'transformer': + self.word_embed = TransformerWordEmbedding(n_vocab=self.args.n_words, + n_embed=self.args.n_embed, + pos=self.args.pos, + pad_index=self.args.pad_index) + self.embed_dropout = nn.Dropout(p=self.args.embed_dropout) + self.encoder = TransformerEncoder(layer=TransformerEncoderLayer(n_heads=self.args.n_encoder_heads, + n_model=self.args.n_encoder_hidden, + n_inner=self.args.n_encoder_inner, + attn_dropout=self.args.encoder_attn_dropout, + ffn_dropout=self.args.encoder_ffn_dropout, + dropout=self.args.encoder_dropout), + n_layers=self.args.n_encoder_layers, + n_model=self.args.n_encoder_hidden) + self.encoder_dropout = nn.Dropout(p=self.args.encoder_dropout) + elif encoder == 'bert': + self.encoder = TransformerEmbedding(name=self.args.bert, + n_layers=self.args.n_bert_layers, + n_out=self.args.n_encoder_hidden, + pooling=self.args.bert_pooling, + pad_index=self.args.pad_index, + mix_dropout=self.args.mix_dropout, + finetune=self.args.finetune) + self.encoder_dropout = nn.Dropout(p=self.args.encoder_dropout) + self.args.n_encoder_hidden = self.encoder.n_out + + self.passes_remaining = vq_passes + if use_vq: + self.vq = VectorQuantize(dim=self.args.n_encoder_hidden, codebook_size=codebook_size, decay=vq_decay, + commitment_weight=commitment_weight, eps=1e-5) #, wait_steps=0, observe_steps=vq_passes) + else: + self.vq = nn.Identity() + + def load_pretrained(self, embed=None): + if embed is not None: + self.pretrained = nn.Embedding.from_pretrained(embed) + if embed.shape[1] != self.args.n_pretrained: + self.embed_proj = nn.Linear(embed.shape[1], self.args.n_pretrained) + nn.init.zeros_(self.word_embed.weight) + return self + + def forward(self): + raise NotImplementedError + + def vq_forward(self, x: torch.Tensor): + if not self.args.use_vq: + return x, torch.tensor(0) + + if self.passes_remaining > (self.args.vq_passes / 2): + _, _, commit_loss, _ = self.vq(x) + self.passes_remaining -= 1 + elif 0 < self.passes_remaining < (self.args.vq_passes / 2): + x_quantized, _, commit_loss, _ = self.vq(x) + x = torch.lerp(x, x_quantized, (self.passes_remaining - self.passes) / self.passes) + self.passes_remaining -= 1 + else: + x, _, commit_loss, _ = self.vq(x) + qloss = commit_loss.squeeze() + + return x, qloss + + def loss(self): + raise NotImplementedError + + def embed(self, words, feats=None):#feats=None + ext_words = words + # set the indices larger than num_embeddings to unk_index + if hasattr(self, 'pretrained'): + ext_mask = words.ge(self.word_embed.num_embeddings) + ext_words = words.masked_fill(ext_mask, self.args.unk_index) + + # get outputs from embedding layers + word_embed = self.word_embed(ext_words) + if hasattr(self, 'pretrained'): + pretrained = self.pretrained(words) + if self.args.n_embed == self.args.n_pretrained: + word_embed += pretrained + else: + word_embed = torch.cat((word_embed, self.embed_proj(pretrained)), -1) + feat_embed = [] + + if 'tag' in self.args.feat: + feat_embed.append(self.tag_embed(feats.pop(0))) + if 'char' in self.args.feat: + + feat_embed.append(self.char_embed(feats.pop(0))) + if 'elmo' in self.args.feat: + feat_embed.append(self.elmo_embed(feats.pop(0))) + if 'bert' in self.args.feat: + feat_embed.append(self.bert_embed(feats.pop(0))) + if 'lemma' in self.args.feat: + feat_embed.append(self.lemma_embed(feats.pop(0))) + if isinstance(self.embed_dropout, IndependentDropout): + if len(feat_embed) == 0: + raise RuntimeError(f"`feat` is not allowed to be empty, which is {self.args.feat} now") + embed = torch.cat(self.embed_dropout(word_embed, torch.cat(feat_embed, -1)), -1) + else: + embed = word_embed + if len(feat_embed) > 0: + embed = torch.cat((embed, torch.cat(feat_embed, -1)), -1) + embed = self.embed_dropout(embed) + return embed + + def encode(self, words, feats):#=None): + if self.args.encoder == 'lstm': + x = pack_padded_sequence(self.embed(words, feats), words.ne(self.args.pad_index).sum(1).tolist(), True, False) + + x, _ = self.encoder(x) + x, _ = pad_packed_sequence(x, True, total_length=words.shape[1]) + elif self.args.encoder == 'transformer': + x = self.encoder(self.embed(words, feats), words.ne(self.args.pad_index)) + else: + x = self.encoder(words) + return self.encoder_dropout(x) + + def decode(self): + raise NotImplementedError + + def vq_forward(self, x: torch.Tensor): + if not self.args.use_vq: + return x, torch.tensor(0) + + if self.passes_remaining > (self.args.vq_passes / 2): + _, _, commit_loss = self.vq(x) + self.passes_remaining -= 1 + elif 0 < self.passes_remaining < (self.args.vq_passes / 2): + x_quantized, _, commit_loss = self.vq(x) + x = torch.lerp(x, x_quantized, (self.passes_remaining - self.passes) / self.passes) + self.passes_remaining -= 1 + else: + x, indices, commit_loss = self.vq(x) + qloss = commit_loss.squeeze() + return x, qloss + + @property + def device(self): + if self.args.device == 'cpu': + return 'cpu' + else: + return f'cuda:{self.args.device}' diff --git a/tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py b/tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py new file mode 100644 index 0000000..e54ae9f --- /dev/null +++ b/tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from .const import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos, CRFConstituencyParser, + TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser) +from .dep import (BiaffineDependencyParser, CRF2oDependencyParser, + CRFDependencyParser, VIDependencyParser, + SLDependencyParser, ArcEagerDependencyParser) +from .sdp import BiaffineSemanticDependencyParser, VISemanticDependencyParser + +__all__ = ['BiaffineDependencyParser', + 'CRFDependencyParser', + 'CRF2oDependencyParser', + 'VIDependencyParser', + 'AttachJuxtaposeConstituencyParser', + 'CRFConstituencyParser', + 'TetraTaggingConstituencyParser', + 'VIConstituencyParser', + 'SLConstituentParser', + 'BiaffineSemanticDependencyParser', + 'VISemanticDependencyParser', + 'SLDependencyParser', + 'ArcEagerDependencyParser'] \ No newline at end of file diff --git a/tania_scripts/supar/models/__init__.py b/tania_scripts/supar/models/__init__.py new file mode 100644 index 0000000..e54ae9f --- /dev/null +++ b/tania_scripts/supar/models/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from .const import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos, CRFConstituencyParser, + TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser) +from .dep import (BiaffineDependencyParser, CRF2oDependencyParser, + CRFDependencyParser, VIDependencyParser, + SLDependencyParser, ArcEagerDependencyParser) +from .sdp import BiaffineSemanticDependencyParser, VISemanticDependencyParser + +__all__ = ['BiaffineDependencyParser', + 'CRFDependencyParser', + 'CRF2oDependencyParser', + 'VIDependencyParser', + 'AttachJuxtaposeConstituencyParser', + 'CRFConstituencyParser', + 'TetraTaggingConstituencyParser', + 'VIConstituencyParser', + 'SLConstituentParser', + 'BiaffineSemanticDependencyParser', + 'VISemanticDependencyParser', + 'SLDependencyParser', + 'ArcEagerDependencyParser'] \ No newline at end of file diff --git a/tania_scripts/supar/models/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c56ad26f856966acabe985c3781a35035bb4d79 GIT binary patch literal 742 zcmd1j<>g{vU|`^5UzC2FnStRkh=Yuo7#J8F7#J9eBN!MMQW#Pga~N_NqZo6UqL^}- zqnLA9qF8cSqgWY1a!fgFx$IHwxg1d(xtvj)xm;0Px!h6Qxja!kV0q>o-dw&YzFht& zeny6Lh7^`Xj8Ot9ticSLY%duZ7#K8JZz(#Klq4o+c$HR^Bo^csr#k276_;d|l&0n- zR|X^&6{i;65_Jx8!y+sfl3G%f7?PNto|%`9MP4M#6N{*Dun$7C1Y(0G+bs#F%*3>` z%)C^W)PmH!6g1n7@-c*korByk1ckypF~x#?FvKJri;`Uv(^HGkWi**?DZpG3oSK`M zSCW~GuI83hm?thdP2M7Q1_p*AP7uKXB0!N{1d7ulW)PPJM6iMgHW0xJBKSZAH;CY2 zU|{gm6uiZn42lJu+HNtYq!vId0^0$$4QvtIlv~WjDFsDv<8QIY$0z3G#K*5>C=v$Q z1R{Rf>1X8Urs|g@mSiU8CF&*RB&KAh7U?JF=N9DarWcgx=H{oQ=I9rf79<wwgW1LU n@$s2?nI-Y@dIgoYIBatBQ%ZAE?LcX%7~~WgCIuz|W*#O0YAw@< literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9521805749c757cbf900e8dbd4ebb1339359dd88 GIT binary patch literal 1043 zcmZ3^%ge>Uz`&q*Up3<mGXuk85C?{tpp4IP3=9m@8B!Qh7;_kM8KW3;nWC6-nWLC< zS)y2SS)*8U*`nAOLGnyF?719K9J!oPoVi?4T)Es)+_^kaJh{A4ykL3e9KKxsDE?f5 zC;>)>bcPg`MT}8`DXhT^nrtr_85kHe*={L1mXstWXLyxXlq4497pFSs=M|S^mXxOE zC07O{78R!!-BKZ_Bp|=|mZ)=(8y3xSA*m%ri6M#U>6v-ySmZ^*Jh6xh2m2sIOCavh zWV<Edl$n^8mYJ98l3I|OmxAO*knKkK7{bENL2ej=LSdemV!=KbViJx;$*zg%sYU2A znoPG8U@i$x%}vZJ$xKF9b4x1B6PKJOZxJU0149uvhybOBA|4Qn8APyx2sRMG4k9=} z1V4xn01><(f{%fL!B11@7Hcvnu8P3gSU?h3^xk4lNiBfb2DS)nCD=B&QMZ_jQwoaU zcHCl*k5A0WiH~2&@EMdKfBEQV<maa9mn4>CCgvsTCFLZhWTqDBC+FuD<m;BCR+Q+b zmL=xsmn7z8CdL;h7iAWd6zdn479<ww=jNxR<`nD4$7kkcmc+;F6;%G>u*uC&Da}c> zE0SPfU;rh;;;#%03?G;o85uvYF*3$8eqf*($->0w!1#fIW+WQ}qaWi12476{frW=# R{R0DxXkZ7yA~6OA1^~TRC5iw5 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/models/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ca2e6217fc9a781a4fd1f5df3b0ce2c9a6ddf79 GIT binary patch literal 731 zcmYe~<>g{vU|`_PGe|$q%)sy%#6iYP3=9ko3=9m#5ey6rDGVu$ISjdsQH;4vQB1ka zQOvn4Q7pNvQLKz0Ii?)8T=ppTT#hJ?T+S%YT&^gtT<$3DT%IT%usm}PZ!TXHUoL+X zKO;jrLki0x#wdXl)?fxrwwH_y3=EpAw-g;qN)nSZyh<xd5)1N+Q=Rkkic2y}N>lTa zD+3aXic^bji8=?lVG))KNi8W#3`tB+&&*55A}<o=iA7X6*asn60<l4p?Usa7W@1`e zW?rgGYC&pV3YzUk`53~&&OvS%f<j@Qm}0>`7-ABRMaiy->8VBNGMY@c6ksk1PR&is zE6GeoS941$%oCTKCT|ft0|P@5Cy3wx5unH}0>x<&Gl<IqB3MBL8;IZq5quzm8$|Fh zFfjOO3f^K(2E_tSZMT?HQVSp!f$ad>2DS)pN)&T(N<k6a_*?Ap@rgM(@$oAeiiAKm zfrwwG`WgATsrn^}C7FqNiF!#ni7A<>Mf#a}$pwi;`o*OnGB-aZHK$lVK0Y%qvm`!V dub}c4hfQvNN@-529mq$;Ab-d(DKHB#0RX63&w2m= literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/__init__.py b/tania_scripts/supar/models/const/__init__.py new file mode 100644 index 0000000..1a15c16 --- /dev/null +++ b/tania_scripts/supar/models/const/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +from .aj import (AttachJuxtaposeConstituencyModel,AttachJuxtaposeConstituencyModelPos, + AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos) +from .crf import CRFConstituencyModel, CRFConstituencyParser +from .tt import TetraTaggingConstituencyModel, TetraTaggingConstituencyParser +from .vi import VIConstituencyModel, VIConstituencyParser +from .sl import SLConstituentParser, SLConstituentModel + +__all__ = ['AttachJuxtaposeConstituencyModel', 'AttachJuxtaposeConstituencyModelPos', 'AttachJuxtaposeConstituencyParser', 'AttachJuxtaposeConstituencyParserPos', + 'CRFConstituencyModel', 'CRFConstituencyParser', + 'TetraTaggingConstituencyModel', 'TetraTaggingConstituencyParser', + 'VIConstituencyModel', 'VIConstituencyParser', + 'SLConstituentModel', 'SLConstituentParser'] diff --git a/tania_scripts/supar/models/const/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d250b33146033de8f6e222867a4f01c6f2d8a54 GIT binary patch literal 758 zcmd1j<>g{vU|{h1`zJk<nStRkh=Yuo7#J8F7#J9eQy3T+QW#Pga~N_NqZo6UqL^}- zqnLA9qF5L~;!HWLxolBvx$IHwU_NsWM=oa+XD(M17nskI!=1|$#goe$#S7-M=J4h6 zNAc$hL<ul5q%)+jEn<ukOkodZ(Byc@$iTp$$#P4<v7{t1Im4^8q9m~(zc|%7Kd-nX zv!paNFS*h;KP5HimNFp~0r|zZ6!9nuNGvK&ExM&bP)R_3u_n_k5$7N`Ojn4ai9!t3 zWV$6Al3G%f7?PNto|%`9sZS1<G~58;Fi%WvBB+80#lb!Z#U&8oTS6#;;84@#DFQ`m z5i<h=LlFyzU<DCuAc7r4aDWI-5CKXWMcg13FNok_U|{gm6pCU>%)(~GE#~B+v?91U zx0p&wir{A5Vk*llf}3}XsW_(yWLy!*;9KnR@rgM(@$oAeiiANHfrww$`WgATsrn^} zC7FqNiF!#ni7A<>Mf#a}$pwi;`o*OnG8dE#iuIF0DMLR#J~J<~BtBlRpz;=nO>TZl XX-=vgC@mF(Y?5FSU=m;iK^`UmF%R03 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24326643d82fa6033432ee9bbd7ebf061b74a4d0 GIT binary patch literal 966 zcmZ3^%ge>Uz`&q%Uo|6>nStRkhy%k+P{!vp1_p-d3@HpLj5!Rsj8TlaOi@g^%u&p_ zEKw|sAaSM~)?BtIwp{iob}*kgha;CWiZhohiVMtV$>GlBiQ>uSjp7CKS#$Vu`J?!A z1)>BP8PXY2*cLHH38t_IGiY+WWMp7q&}6x#;8;?Un4IBNT2Yc%kYAkYoS#=*l37xk znwMPZo1c=Jb4!_!ih%s$TZ(uT1tb;~rxx8(A*duEzgUy$mWXqZ8>TBn(L^DJYBJrD z4M{C2N(@O%PtVLt$J8f>OB!x~aF{2iHW5@ogyLWygyIs2@GT(}L2#&P@)R*MFfbIc zfCyF)!3HAOK?Dbg-~<t%G*QG2V)1|oJ`lmnz`)?ADRhe|F$<d!x0sWQ(u&~b++r#z zDT14Ii>WLVVcspK;+!IoaYZ15Z?VV6C+6hD$FF4g3`%gng7h=;b5r$85=$}@^Ah!v zauQQAQ;YPI^K%RGbxTq!N_11p5_9xR67w<><BOAvG7CzI^@~dj5{vY6K?$Q+KN*x( z^yA|*^D;}~<Mj$Ee{tC4=BJeAq}mlpFfcHHl34K}1_p)?%#4hTAJ`ZfqZmIhP)a^v su(^N@-C*#&fDPSXu)Kf`-C!`kfDL_MVd1v;zyKo}*g>#JjDdjx07BIrcmMzZ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/models/const/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19a59b8eb7ae83aa8e4089626004ec916d1b1ec8 GIT binary patch literal 653 zcmYe~<>g{vU|`_PGe|$j#K7<v#6iYP3=9ko3=9m#F$@e0DGVu$ISjdsQH;4vQA~^= zK2r{JE=v?kE^8Dkn9rQUmdhT+p34!%0p_#haOQGFapiJHafA7+IXt<%QM|c)QGARH z=?p1six{K$Q`mzUG&x=}GB7Y`GTl;eEGbD$&hRR&C`l~HFHUvN&nqs;EGbRRORn_I zPf5+WrHDsGKw?pGYLO<>EfMD+H%zUfXrgfCvLUG@MTsGa>FJqy>6rTDa7n`r5DxRi z)Fy%|h)^8tgHT)o5xymaA_(@XCRY(C28x&&7#NCJKm;p@U;`2CAc6x#aDoVK5CMuz zKTUxsro=3S##_wEMQI4#QA{NzMQ{_Mn94GX;HE?|73UOz3@HK`cZ)qfJ~1aJK7J)b z5g*8S5b?`eKO;XkRlg*$Br`EDQ7<VcF(os#NIx?#xgfDfzqk}c=7Qp>SU(vQb^7t~ jnR%Hd@$q^EmA5!-a`RJ4b5iX<J}L&;B)}xV2!>1mws5rH literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py new file mode 100644 index 0000000..1fe4855 --- /dev/null +++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos +from .parser import AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos + +__all__ = ['AttachJuxtaposeConstituencyModel', 'AttachJuxtaposeConstituencyModelPos', 'AttachJuxtaposeConstituencyParser', 'AttachJuxtaposeConstituencyParserPos'] diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py new file mode 100644 index 0000000..30de07c --- /dev/null +++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py @@ -0,0 +1,786 @@ +# -*- coding: utf-8 -*- + +from typing import List, Tuple + +import torch +import torch.nn as nn +from supar.model import Model +from supar.models.const.aj.transform import AttachJuxtaposeTree +from supar.modules import GraphConvolutionalNetwork, MLP, DecoderLSTM +from supar.utils import Config +from supar.utils.common import INF +from supar.utils.fn import pad + +class DecoderLSTMPos(nn.Module): + def __init__(self, input_dim, hidden_dim, output_dim, num_layers, dropout, device): + super().__init__() + self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=num_layers, + batch_first=True, dropout=dropout) + self.classifier = nn.Linear(hidden_dim, output_dim) + + def forward(self, x): + # x: [batch_size, seq_len, input_dim] + output, _ = self.lstm(x) + logits = self.classifier(output) + return logits + +class AttachJuxtaposeConstituencyModel(Model): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layers. Default: .33. + n_gnn_layers (int): + The number of GNN layers. Default: 3. + gnn_dropout (float): + The dropout ratio of GNN layers. Default: .33. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_gnn_layers=3, + gnn_dropout=.33, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + # the last one represents the dummy node in the initial states + self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden) + self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden, + n_layers=self.args.n_gnn_layers, + dropout=self.args.gnn_dropout) + + self.node_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 1), + ) + self.label_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels), + ) + + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1), + n_out=self.args.n_encoder_hidden, dropout=gnn_dropout) + + self.criterion = nn.CrossEntropyLoss() + + def forward( + self, + words: torch.LongTensor, + feats: List[torch.LongTensor] + ) -> Tuple[torch.Tensor]: + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor: + Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input. + """ + x = self.encode(words, feats) + + # adjust lengths to allow delay predictions + if self.args.delay != 0: + x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i)] for i in range(self.args.delay + 1)], dim=2) + x = self.delay_proj(x) + + # pass through vector quantization + x, qloss = self.vq_forward(x) + + return x, qloss + + def loss( + self, + x: torch.Tensor, + nodes: torch.LongTensor, + parents: torch.LongTensor, + news: torch.LongTensor, + mask: torch.BoolTensor + ) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + nodes (~torch.LongTensor): ``[batch_size, seq_len]``. + The target node positions on rightmost chains. + parents (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of terminals. + news (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of juxtaposed targets and terminals. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor: + The training loss. + """ + + spans, s_node, x_node = None, [], [] + actions = torch.stack((nodes, parents, news)) + for t, action in enumerate(actions.unbind(-1)): + if t == 0: + x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1) + s_node.append(self.node_classifier(x_rightmost).squeeze(-1)) + # we found softmax is slightly better than sigmoid in the original paper + s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0) + x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1)) + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index) + s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1) + s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1) + s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1) + s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1) + node_loss = self.criterion(s_node[mask], nodes[mask]) + label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask]) + return node_loss + label_loss + + def decode( + self, + x: torch.Tensor, + mask: torch.BoolTensor, + beam_size: int = 1 + ) -> List[List[Tuple]]: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + beam_size (int): + Beam size for decoding. Default: 1. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + tokenwise_predictions = [] + spans = None + batch_size, *_ = x.shape + n_labels = self.args.n_labels + # [batch_size * beam_size, ...] + x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:]) + mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:]) + # [batch_size] + batches = x.new_tensor(range(batch_size)).long() * beam_size + # accumulated scores + scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1) + for t in range(x.shape[1]): + if t == 0: + x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1) + s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1) + # we found softmax is slightly better than sigmoid in the original paper + x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1) + s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1) + s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1) + if t == 0: + s_parent[:, self.args.nul_index] = -INF + s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF + s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1) + s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1) + s_new, news = s_new.topk(min(n_labels, beam_size), -1) + s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1) + s_action = s_action.view(x.shape[0], -1) + k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1] + # [batch_size * beam_size, k_beam] + scores = scores.unsqueeze(-1) + s_action + # [batch_size, beam_size] + scores, cands = scores.view(batch_size, -1).topk(beam_size, -1) + # [batch_size * beam_size] + scores = scores.view(-1) + beams = cands.div(k_beam, rounding_mode='floor') + nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor')) + indices = (batches.unsqueeze(-1) + beams).view(-1) + + #print('indices', indices) + parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent) + news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent) + action = torch.stack((nodes, parents, news)).view(3, -1) + tokenwise_predictions.append([t, [x[0] for x in action.tolist()]]) + spans = spans[indices] if spans is not None else None + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + #print("SPANS", spans) + mask = mask.view(batch_size, beam_size, -1)[:, 0] + # select an 1-best tree for each sentence + spans = spans[batches + scores.view(batch_size, -1).argmax(-1)] + span_mask = spans.ge(0) + span_indices = torch.where(span_mask) + span_labels = spans[span_indices] + chart_preds = [[] for _ in range(x.shape[0])] + for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()): + chart_preds[i].append(span) + kk = [chart_preds + tokenwise_predictions] + return kk + + def rightmost_chain( + self, + x: torch.Tensor, + spans: torch.LongTensor, + mask: torch.BoolTensor, + t: int + ) -> torch.Tensor: + x_p, mask_p = x[:, :t], mask[:, :t] + lens = mask_p.sum(-1) + span_mask = spans[:, :-1, 1:].ge(0) + span_lens = span_mask.sum((-1, -2)) + span_indices = torch.where(span_mask) + span_labels = spans[:, :-1, 1:][span_indices] + x_span = self.label_embed(span_labels) + x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]] + node_lens = lens + span_lens + adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max()))) + x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1]))) + span_mask = ~x_mask & adj_mask + # concatenate terminals and spans + x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p]) + x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span) + adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1]) + adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1) + adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:])) + adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0] + adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2)) + # set the parent of root as itself + adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1)) + adj_parent = adj_parent & span_mask.unsqueeze(1) + # closet ancestor spans as parents + adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1) + adj.scatter_(-1, adj_parent.unsqueeze(-1), 1) + adj = (adj | adj.transpose(-1, -2)).float() + x_tree = self.gnn_layers(x_tree, adj, adj_mask) + span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1)) + span_lens = span_mask.sum(-1) + x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree) + return x_span + + +class AttachJuxtaposeConstituencyModelPos(Model): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layers. Default: .33. + n_gnn_layers (int): + The number of GNN layers. Default: 3. + gnn_dropout (float): + The dropout ratio of GNN layers. Default: .33. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=16, + n_chars=None, + encoder='lstm', + feat=['char', 'tag'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_gnn_layers=3, + gnn_dropout=.33, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + # the last one represents the dummy node in the initial states + self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden) + self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden, + n_layers=self.args.n_gnn_layers, + dropout=self.args.gnn_dropout) + + self.node_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 1), + ) + self.label_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels), + ) + self.pos_classifier = DecoderLSTMPos( + self.args.n_encoder_hidden, self.args.n_encoder_hidden, self.args.n_tags, + num_layers=1, dropout=encoder_dropout, device=self.device + ) + + #self.pos_tagger = nn.Identity() + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1), + n_out=self.args.n_encoder_hidden, dropout=gnn_dropout) + + self.criterion = nn.CrossEntropyLoss() + + def encoder_forward(self, words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]: + """ + Applies encoding forward pass. Maps a tensor of word indices (`words`) to their corresponding neural + representation. + Args: + words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay] + feats: List[torch.Tensor] + lens: List[int] + + Returns: x, qloss + x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + qloss: torch.FloatTensor ~ 1 + + """ + + x = super().encode(words, feats) + s_tag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :]) + + # adjust lengths to allow delay predictions + # x ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + if self.args.delay != 0: + x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay + 1)], dim=2) + x = self.delay_proj(x) + + # pass through vector quantization + x, qloss = self.vq_forward(x) + return x, s_tag, qloss + + + def forward( + self, + words: torch.LongTensor, + feats: List[torch.LongTensor] + ) -> Tuple[torch.Tensor]: + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor: + Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input. + """ + x, s_tag, qloss = self.encoder_forward(words, feats) + + return x, s_tag, qloss + + def loss( + self, + x: torch.Tensor, + nodes: torch.LongTensor, + parents: torch.LongTensor, + news: torch.LongTensor, + mask: torch.BoolTensor, s_tags: torch.LongTensor, tags: torch.LongTensor + ) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + nodes (~torch.LongTensor): ``[batch_size, seq_len]``. + The target node positions on rightmost chains. + parents (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of terminals. + news (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of juxtaposed targets and terminals. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor: + The training loss. + """ + + spans, s_node, x_node = None, [], [] + actions = torch.stack((nodes, parents, news)) + for t, action in enumerate(actions.unbind(-1)): + if t == 0: + x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1) + s_node.append(self.node_classifier(x_rightmost).squeeze(-1)) + # we found softmax is slightly better than sigmoid in the original paper + s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0) + x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1)) + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index) + s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1) + s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1) + #s_postag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :]).chunk(2, -1) + s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1) + s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1) + node_loss = self.criterion(s_node[mask], nodes[mask]) + #print('node loss', node_loss) + label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask]) + #print('label loss', label_loss) + + #print(s_tag[mask].shape, tags[mask].shape) + tag_loss = self.criterion(s_tags[mask], tags[mask]) + #print('tag loss', tag_loss) + #tag_loss = self.pos_loss(s_tags, tags, mask) + print("node loss, label loss, tag loss", node_loss, label_loss, tag_loss, node_loss + label_loss + tag_loss) + return node_loss + label_loss + tag_loss + + def decode( + self, + x: torch.Tensor, + mask: torch.BoolTensor, + beam_size: int = 1 + ) -> List[List[Tuple]]: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + beam_size (int): + Beam size for decoding. Default: 1. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + tokenwise_predictions = [] + spans = None + batch_size, *_ = x.shape + n_labels = self.args.n_labels + # [batch_size * beam_size, ...] + x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:]) + mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:]) + # [batch_size] + batches = x.new_tensor(range(batch_size)).long() * beam_size + # accumulated scores + scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1) + for t in range(x.shape[1]): + if t == 0: + x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1) + s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1) + # we found softmax is slightly better than sigmoid in the original paper + x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1) + s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1) + s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1) + if t == 0: + s_parent[:, self.args.nul_index] = -INF + s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF + s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1) + s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1) + s_new, news = s_new.topk(min(n_labels, beam_size), -1) + s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1) + s_action = s_action.view(x.shape[0], -1) + k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1] + # [batch_size * beam_size, k_beam] + scores = scores.unsqueeze(-1) + s_action + # [batch_size, beam_size] + scores, cands = scores.view(batch_size, -1).topk(beam_size, -1) + # [batch_size * beam_size] + scores = scores.view(-1) + beams = cands.div(k_beam, rounding_mode='floor') + nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor')) + indices = (batches.unsqueeze(-1) + beams).view(-1) + + #print('indices', indices) + parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent) + news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent) + action = torch.stack((nodes, parents, news)).view(3, -1) + tokenwise_predictions.append([t, [x[0] for x in action.tolist()]]) + spans = spans[indices] if spans is not None else None + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + #print("SPANS", spans) + mask = mask.view(batch_size, beam_size, -1)[:, 0] + # select an 1-best tree for each sentence + spans = spans[batches + scores.view(batch_size, -1).argmax(-1)] + span_mask = spans.ge(0) + span_indices = torch.where(span_mask) + span_labels = spans[span_indices] + chart_preds = [[] for _ in range(x.shape[0])] + for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()): + chart_preds[i].append(span) + kk = [chart_preds + tokenwise_predictions] + return kk + + def rightmost_chain( + self, + x: torch.Tensor, + spans: torch.LongTensor, + mask: torch.BoolTensor, + t: int + ) -> torch.Tensor: + x_p, mask_p = x[:, :t], mask[:, :t] + lens = mask_p.sum(-1) + span_mask = spans[:, :-1, 1:].ge(0) + span_lens = span_mask.sum((-1, -2)) + span_indices = torch.where(span_mask) + span_labels = spans[:, :-1, 1:][span_indices] + x_span = self.label_embed(span_labels) + x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]] + node_lens = lens + span_lens + adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max()))) + x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1]))) + span_mask = ~x_mask & adj_mask + # concatenate terminals and spans + x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p]) + x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span) + adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1]) + adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1) + adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:])) + adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0] + adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2)) + # set the parent of root as itself + adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1)) + adj_parent = adj_parent & span_mask.unsqueeze(1) + # closet ancestor spans as parents + adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1) + adj.scatter_(-1, adj_parent.unsqueeze(-1), 1) + adj = (adj | adj.transpose(-1, -2)).float() + x_tree = self.gnn_layers(x_tree, adj, adj_mask) + span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1)) + span_lens = span_mask.sum(-1) + x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree) + return x_span + + + def pos_loss(self, pos_logits: torch.Tensor, pos_tags: torch.LongTensor, mask: torch.BoolTensor) -> torch.Tensor: + """ + Args: + pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags]. + pos_tags (~torch.LongTensor): [batch_size, seq_len]. + mask (~torch.BoolTensor): [batch_size, seq_len]. + + Returns: + torch.Tensor: The POS tagging loss. + """ + loss_fn = nn.CrossEntropyLoss() + return loss_fn(pos_logits[mask], pos_tags[mask]) + + def decode_pos(self, s_tag: torch.Tensor): + """ + Decode the most likely POS tags. + + Args: + pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags] + mask (~torch.BoolTensor): [batch_size, seq_len] + + Returns: + List[List[int]]: POS tags per token for each sentence in the batch. + """ + pos_preds = pos_logits.argmax(-1) + #return [seq[mask[i]].tolist() for i, seq in enumerate(pos_preds)] + return pos_preds diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py new file mode 100644 index 0000000..543e828 --- /dev/null +++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py @@ -0,0 +1,534 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Dict, Iterable, Set, Union + +import torch + +from supar.models.const.aj.model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos +from supar.models.const.aj.transform import AttachJuxtaposeTree +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, EOS, NUL, PAD, UNK +from supar.utils.field import Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import SpanMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch +from torch.nn.utils.rnn import pad_sequence + + +logger = get_logger(__name__) + + +def compute_pos_accuracy(pos_gold, pos_preds): + correct = 0 + total = 0 + for gold_seq, pred_seq in zip(pos_gold, pos_preds): + for g, p in zip(gold_seq, pred_seq): + if g == p: + correct += 1 + total += len(gold_seq) + return correct, total + + + + +class AttachJuxtaposeConstituencyParser(Parser): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + """ + + NAME = 'attach-juxtapose-constituency' + MODEL = AttachJuxtaposeConstituencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TREE = self.transform.TREE + self.NODE = self.transform.NODE + self.PARENT = self.transform.PARENT + self.NEW = self.transform.NEW + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + print("here") + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + verbose: bool = True, + **kwargs + ): + + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + #print("TRAIN STEP") + words, *feats, trees, nodes, parents, news = batch + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + #print("s_tag", s_tag) + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + #print("EVAL STEP") + words, *feats, trees, nodes, parents, news = batch + #print("WORDS", words.shape, words) + mask = batch.mask[:, (2+self.args.delay):] + x, qloss = self.model(words, feats) + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #print("CHART PREDS") + #print("self new vocab", self.NEW.vocab.items()) + #print() + preds = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds)] + + for tree, chart in zip(trees, chart_preds): + print(tree, chart) + + print() + for tree in trees: + print("ORIG TREE", tree) + print() + for tree in preds: + print("PRED TREE", tree) + + print("=========================") + + return SpanMetric(loss, + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees]) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask = batch.mask[:, (2+self.args.delay):] + x, _ = self.model(words, feats) + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + chart_preds = chart_preds[0] + batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds)] + if self.args.prob: + raise NotImplementedError("Returning action probs are currently not supported yet.") + + new_tokenwise_preds = [] + for k, y in chart_preds[1:]: + new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]]) + + chart_preds = [[[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]]] + new_tokenwise_preds + #for x in chart_preds[1:]: + # new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]] + + return chart_preds #batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR = None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay) + TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + TREE = RawField('trees') + NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK) + transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if CHAR is not None: + CHAR.build(train) + TAG.build(train) + PARENT, NEW = PARENT.build(train), NEW.build(train) + PARENT.vocab = NEW.vocab.update(PARENT.vocab) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(NEW.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'eos_index': WORD.eos_index, + 'nul_index': NEW.vocab[NUL] + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser + +def flatten(x): + result = [] + for el in x: + if isinstance(el, list): + result.extend(flatten(el)) + else: + result.append(el) + return result + + + + +class AttachJuxtaposeConstituencyParserPos(Parser): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + """ + + NAME = 'attach-juxtapose-constituency' + MODEL = AttachJuxtaposeConstituencyModelPos + + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TREE = self.transform.TREE + self.NODE = self.transform.NODE + self.PARENT = self.transform.PARENT + self.NEW = self.transform.NEW + self.TAG = self.transform.POS + + #print(self.TAG) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + verbose: bool = True, + **kwargs + ): + + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + #print("TRAIN STEP") + words, *feats, postags, nodes, parents, news = batch + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + tags = feats[-1] + #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits + #loss = loss.mean() + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss + + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + + #print("EVAL STEP") + words, *feats, trees, nodes, parents, news = batch + + tags = feats[-1] + #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits + #loss = loss.mean() + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #print('CHART PREDS', chart_preds[0]) + + pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)] + trimmed_tags = [tag_seq[1:-1] for tag_seq in tags] + trimmed_tags_list = [x.cpu().tolist() for x in trimmed_tags] + pos_gold = [[self.TAG.vocab[p] for p in sent] for sent in trimmed_tags_list] + + pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds) + pos_acc = pos_correct/pos_total + print(pos_acc) + + """ + tags = [*feats[-1:]] + trimmed_tags = [tag_seq[1:-1] for tag_seq in tags[0]] + gtags = [*feats[-1:]][0].cpu().tolist() + gtags = [x[1:-1] for x in gtags] + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + + tag_tensor = pad_sequence(trimmed_tags, batch_first=True, padding_value=self.TAG.pad_index).to(s_tag.device) + + assert s_tag.shape[:2] == tag_tensor.shape[:2] + print("s_tag shape", s_tag.shape[:2], "tag_tensor shape", tag_tensor.shape[:2]) + + + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tag_tensor) + qloss + + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)] + + for tag_seq in gtags: + for pos in tag_seq: + assert 0 <= pos < len(self.TAG.vocab) + + pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)] + pos_gold = [[self.TAG.vocab[pos] for pos in tag_seq] for tag_seq in gtags] + + #print("357!", len(pos_gold), len(pos_preds)) + pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds) + print("358!", pos_correct, pos_total, pos_correct/pos_total) + + + #print('%%% POS preds', pos_preds) + #print('%%%% POS gold', pos_gold) + """ + + #batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + # for tree, chart in zip(trees, chart_preds)] + #print(batch.trees) + + preds = [AttachJuxtaposeTree.build(tree, [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds[0])] + #print('POS preds', s_tag.argmax(-1)) + #print("PREDS", len(preds)) + + + """ + span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0][0]] + #print("new SPAN preds", span_preds) + verbalized_preds = [] + + + for x in chart_preds[1:]: + new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]] + #print(new_item) + verbalized_preds.append(new_item) + """ + + print("424", loss, pos_acc) + return SpanMetric(loss, + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees], pos_acc) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #print('VHART PREDS: ', chart_preds) + #print('LEN VHART PREDS: ', len(chart_preds)) + + chart_preds = chart_preds[0] + batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds)] + if self.args.prob: + raise NotImplementedError("Returning action probs are currently not supported yet.") + + new_tokenwise_preds = [] + #for pred in chart_preds: + # print("PRED", pred) + # new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]]) + + + span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]] + new_tokenwise_preds + #print("new chart preds", span_preds) + verbalized_preds = [] + for x in chart_preds[1:]: + new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]] + #print(new_item) + verbalized_preds.append(new_item) + #print('POS preds', s_tag.argmax(-1)) + pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)] + return span_preds, verbalized_preds, pos_preds #batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR = None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay) + TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + TREE = RawField('trees') + NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK) + transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if CHAR is not None: + CHAR.build(train) + TAG.build(train) + #print("203 TAG VOCAB", [x for x in TAG.vocab.items()]) + PARENT, NEW = PARENT.build(train), NEW.build(train) + PARENT.vocab = NEW.vocab.update(PARENT.vocab) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(NEW.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'eos_index': WORD.eos_index, + 'nul_index': NEW.vocab[NUL] + }) + logger.info(f"{transform}") + + #print('TAG VOCAB', TAG.vocab.items()) + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser \ No newline at end of file diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py new file mode 100644 index 0000000..56e0f51 --- /dev/null +++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union + +import nltk +import torch + +from supar.models.const.crf.transform import Tree +from supar.utils.common import NUL +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class AttachJuxtaposeTree(Tree): + r""" + :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class, + supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`. + + Attributes: + WORD: + Words in the sentence. + POS: + Part-of-speech tags, or underscores if not available. + TREE: + The raw constituency tree in :class:`nltk.tree.Tree` format. + NODE: + The target node on each rightmost chain. + PARENT: + The label of the parent node of each terminal. + NEW: + The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children. + ``NUL`` represents the `Attach` action. + """ + + fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW'] + + def __init__( + self, + WORD: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + TREE: Optional[Union[Field, Iterable[Field]]] = None, + NODE: Optional[Union[Field, Iterable[Field]]] = None, + PARENT: Optional[Union[Field, Iterable[Field]]] = None, + NEW: Optional[Union[Field, Iterable[Field]]] = None + ) -> Tree: + super().__init__() + + self.WORD = WORD + self.POS = POS + self.TREE = TREE + self.NODE = NODE + self.PARENT = PARENT + self.NEW = NEW + + @property + def src(self): + return self.WORD, self.POS, self.TREE + + @property + def tgt(self): + return self.NODE, self.PARENT, self.NEW + + @classmethod + def tree2action(cls, tree: nltk.Tree): + r""" + Converts a constituency tree into AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + A constituency tree in :class:`nltk.tree.Tree` format. + + Returns: + A sequence of AttachJuxtapose actions. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ Arthur)) + (VP + (_ is) + (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons))))) + (_ .))) + ''') + >>> tree.pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + >>> AttachJuxtaposeTree.tree2action(tree) + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')] + """ + + def isroot(node): + return node == tree[0] + + def isterminal(node): + return len(node) == 1 and not isinstance(node[0], nltk.Tree) + + def last_leaf(node): + pos = () + while True: + pos += (len(node) - 1,) + node = node[-1] + if isterminal(node): + return node, pos + + def parent(position): + return tree[position[:-1]] + + def grand(position): + return tree[position[:-2]] + + def detach(tree): + last, last_pos = last_leaf(tree) + siblings = parent(last_pos)[:-1] + + if len(siblings) > 0: + last_subtree = last + last_subtree_siblings = siblings + parent_label = NUL + else: + last_subtree, last_pos = parent(last_pos), last_pos[:-1] + last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1] + parent_label = last_subtree.label() + + target_pos, new_label, last_tree = 0, NUL, tree + if isroot(last_subtree): + last_tree = None + + elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]): + new_label = parent(last_pos).label() + new_label = new_label + target = last_subtree_siblings[0] + last_grand = grand(last_pos) + if last_grand is None: + last_tree = targetistermina + else: + last_grand[-1] = target + target_pos = len(last_pos) - 2 + else: + target = parent(last_pos) + target.pop() + target_pos = len(last_pos) - 2 + action = target_pos, parent_label, new_label + return action, last_tree + if tree is None: + return [] + action, last_tree = detach(tree) + return cls.tree2action(last_tree) + [action] + + @classmethod + def action2tree( + cls, + tree: nltk.Tree, + actions: List[Tuple[int, str, str]], + join: str = '::', + ) -> nltk.Tree: + r""" + Recovers a constituency tree from a sequence of AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + An empty tree that provides a base for building a result tree. + actions (List[Tuple[int, str, str]]): + A sequence of AttachJuxtapose actions. + join (str): + A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains. + Default: ``'::'``. + + Returns: + A result constituency tree. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.action2tree(tree, + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')]).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + """ + + def target(node, depth): + node_pos = () + for _ in range(depth): + node_pos += (len(node) - 1,) + node = node[-1] + return node, node_pos + + def parent(tree, position): + return tree[position[:-1]] + + def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree: + target_pos, parent_label, new_label, post = action + #print(target_pos, parent_label, new_label) + new_leaf = nltk.Tree(post, [terminal[0]]) + + # create the subtree to be inserted + new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf]) + # find the target position at which to insert the new subtree + target_node = tree + if target_node is not None: + target_node, target_pos = target(target_node, target_pos) + + # Attach + if new_label == NUL: + # attach the first token + if target_node is None: + return new_subtree + target_node.append(new_subtree) + # Juxtapose + else: + new_subtree = nltk.Tree(new_label, [target_node, new_subtree]) + if len(target_pos) > 0: + parent_node = parent(tree, target_pos) + parent_node[-1] = new_subtree + else: + tree = new_subtree + return tree + + tree, root, terminals = None, tree.label(), tree.pos() + for terminal, action in zip(terminals, actions): + tree = execute(tree, terminal, action) + # recover unary chains + nodes = [tree] + while nodes: + node = nodes.pop() + if isinstance(node, nltk.Tree): + nodes.extend(node) + if join in node.label(): + labels = node.label().split(join) + node.set_label(labels[0]) + subtree = nltk.Tree(labels[-1], node) + for label in reversed(labels[1:-1]): + subtree = nltk.Tree(label, [subtree]) + node[:] = [subtree] + return nltk.Tree(root, [tree]) + + @classmethod + def action2span( + cls, + action: torch.Tensor, + spans: torch.Tensor = None, + nul_index: int = -1, + mask: torch.BoolTensor = None + ) -> torch.Tensor: + r""" + Converts a batch of the tensorized action at a given step into spans. + + Args: + action (~torch.Tensor): ``[3, batch_size]``. + A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels. + spans (~torch.Tensor): + Spans generated at previous steps, ``None`` at the first step. Default: ``None``. + nul_index (int): + The index for the obj:`NUL` token, representing the Attach action. Default: -1. + mask (~torch.BoolTensor): ``[batch_size]``. + The mask for covering the unpadded tokens. + + Returns: + A tensor representing a batch of spans for the given step. + + Examples: + >>> from collections import Counter + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab + >>> from supar.utils.common import NUL + >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL), + (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL), + (0, NUL, NUL)]) + >>> vocab = Vocab(Counter(sorted(set([*parents, *news])))) + >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1) + >>> spans = None + >>> for action in actions.unbind(-1): + ... spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL]) + ... + >>> spans + tensor([[[-1, 1, -1, -1, -1, -1, -1, 3], + [-1, -1, -1, -1, -1, -1, 4, -1], + [-1, -1, -1, 1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, 2, -1], + [-1, -1, -1, -1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1]]]) + >>> sequence = torch.where(spans.ge(0)) + >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]])) + >>> sequence + [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')] + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + + """ + + # [batch_size] + target, parent, new = action + if spans is None: + spans = action.new_full((action.shape[1], 2, 2), -1) + spans[:, 0, 1] = parent + return spans + if mask is None: + mask = torch.ones_like(target, dtype=bool) + juxtapose_mask = new.ne(nul_index) & mask + # ancestor nodes are those on the rightmost chain and higher than the target node + # [batch_size, seq_len] + rightmost_mask = spans[..., -1].ge(0) + ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1 + # should not include the target node for the Juxtapose action + ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1)) + target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1] + # the right boundaries of ancestor nodes should be aligned with the new generated terminals + spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1) + spans[..., -2].masked_fill_(ancestor_mask, -1) + spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask] + spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask] + # [batch_size, seq_len+1, seq_len+1] + spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1) + return spans + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ) -> List[AttachJuxtaposeTreeSentence]: + r""" + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + + Returns: + A list of :class:`AttachJuxtaposeTreeSentence` instances. + """ + + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + if data.endswith('.txt'): + data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1) + else: + data = open(data) + else: + if lang is not None: + data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + + index = 0 + for s in data: + + try: + tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root) + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + except ValueError: + logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!") + continue + except IndexError: + tree = nltk.Tree.fromstring('(S ' + s + ')') + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + else: + yield sentence + index += 1 + self.root = tree.label() + + +class AttachJuxtaposeTreeSentence(Sentence): + r""" + Args: + transform (AttachJuxtaposeTree): + A :class:`AttachJuxtaposeTree` object. + tree (nltk.tree.Tree): + A :class:`nltk.tree.Tree` object. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + """ + + def __init__( + self, + transform: AttachJuxtaposeTree, + tree: nltk.Tree, + index: Optional[int] = None + ) -> AttachJuxtaposeTreeSentence: + super().__init__(transform, index) + + words, tags = zip(*tree.pos()) + nodes, parents, news = None, None, None + if transform.training: + oracle_tree = tree.copy(True) + # the root node must have a unary chain + if len(oracle_tree) > 1: + oracle_tree[:] = [nltk.Tree('*', oracle_tree)] + oracle_tree.collapse_unary(joinChar='::') + if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree): + oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]]) + nodes, parents, news = zip(*transform.tree2action(oracle_tree)) + tags = [x.split("##")[0] for x in tags] + self.values = [words, tags, tree, nodes, parents, news] + + def __repr__(self): + return self.values[-4].pformat(1000000) + + def pretty_print(self): + self.values[-4].pretty_print() diff --git a/tania_scripts/supar/models/const/aj/__init__.py b/tania_scripts/supar/models/const/aj/__init__.py new file mode 100644 index 0000000..1fe4855 --- /dev/null +++ b/tania_scripts/supar/models/const/aj/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos +from .parser import AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos + +__all__ = ['AttachJuxtaposeConstituencyModel', 'AttachJuxtaposeConstituencyModelPos', 'AttachJuxtaposeConstituencyParser', 'AttachJuxtaposeConstituencyParserPos'] diff --git a/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf09a38138e561426e88c74ad582913e27d79d0e GIT binary patch literal 415 zcmd1j<>g{vU|`7k^C!KCk%8ech=Yuo7#J8F7#J9ebr={JQW#Pga~N_NqZo6UqL>&# ze5M@cT$U)7T-GR7Muv2T6y`;YQEVwJ!3>(LFBusa7&Mt~DL9stBqnEgl~$A_7UUPF zI_KvVmt>ZdrsgGA`sSyk=G;;yq#_`{Sd;0NA|7P{iABY!MYmK4DghbAQUvl=5i<h= zLlFyzU}a!n@Y7_!#hMFp4?^}9TLIWygsNNY@$rc{Iq~r;8HzYTT0z7wJN=CO+*JLN z#FEU!yhOdEoWzvO)FS=NyySw!BK_i05D7NASU(x$d;P>L{rLFIyv&mLc)fzkTO2mI Y`6;D2sdk_sD`sP0U=UyuVB}!}01#Yv+W-In literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bd79cb4caac4fa72e4cd50659aee9fc13dcc3d4 GIT binary patch literal 515 zcmZ3^%ge>Uz`&q%Up1qMk%8echy%k+P{wCH1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL zb1q91OD<~^D<eZXLkjaE#wfNFmS6@=)|ZS73=En~w-g*pN)nSZyh<xd5)1N+Q=Rkk zic2y}N>lTaD}D1*Qgd!86H*b7U#!V=OA(K<fW)HW)S_D|1eJh{Vku%~U|=X>0THYq zf{lTJ!B3O@7HclZJqX!bYz1I*i{PqmvB$?J=H$f3uVnZP3Y=e|`WgATsrn^}C7FqN ziF!#ni7A<>Mf%D4xdr*UC8-r9x~XM}Ir=4ud6|jv#mPmP1trD$#ia#_MfzaNiuIF0 z;h~?Hr5_)knU`4-AFo$X`HRCQH$SB`C)KWqmw|x+6q3aO3=9k(m>C%vKd><{MlxPt gh`>ZQ7@{v=LmyZexRaSaFd)bVb`UJ$W?*0d0O``3g8%>k literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb0340d7a5173f1782e452ef95c2faf9025e674d GIT binary patch literal 308 zcmYe~<>g{vU|`_PGf2O|z`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$ zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9W3XUZuiOCsWr4=QK1^LCP&iQ%8C7C6q zsd>qjzWFJsIhu^O6!EADNGvK&Eh+-Jpop1)fx%CcHHtMCq!BE3i>&~n03>&dJw84$ zCnr9BB|{M#0|SKkWv8E!pPQ;*l30?Nn3t%Rl#`f}nOdZunU`FUSfpQE3L?P<7V9U2 q9H*a{r5_)knU`4-AFo$Xd5gm)H$SB`C)EyQMKKEl0|O5u4-)_uyi)N1 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4da15ae58bc418dda6f19b8e44874d984ba30fda GIT binary patch literal 22080 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 U1Vz9k52Fy1053y5L%m2m01eenIRF3v literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a76052d5e93b7b2ce0a33eae863662d4a4a1438 GIT binary patch literal 47523 zcmZ3^%ge>Uz`&q%Uo|6YDg(n~5C?`?p^VQr7#J9)Go&!2Fy=7iGDb1xGDR^lg7{21 z%u&oK3@J=GEV-;vtY9(b9JXBcD0VQLC5I!IGl~<;X3gQs<&NUc<%#0S<&EM6i?QYK z<?=`IgW2pk0=a@wf?zgBj!>>}lrSR$6N5WL3TF#L3Rfy?mI%~649l1q7*;dGcu}HY zRopEMDLkp{XmVm;Io=kA6g~_&@f4<D22K8#AcHiSZn5}e7MI*&4Jj?iN%hlYyv6F9 zpOTuR$#_fHv7{t1Im4^8q9m~(zc@9dC^c1+`Ie-6QDQ-cbADb~eokpgW`15`j$dj? zd45s$EoNVzfLq)ysmb{%sYO1)A-<Z7x7eKX^U^ZYH5qR)d-}P7sDi|lWRTr3%mih8 zR$*XZXlIztkjfCnn8Fan)WML(n8Mh?5yhOs)WQ(O(!o%{7{waQpvioT56O~%{NiMG zs2Ly%#0G`Z=N$|T3{x4WGn6obgdunt0|Ucq2$O+<VF8j1T#x}(4I@JdEJZLdFl2#D z1}m*$tYNBQNnxyEUBk4Dm4RV3TvZK2JPTL}0|TmFgbJn_=4DI_469*&XQ*L_XM^cU zVF3BjFGQ317FS+rZhTH+Wol9JE$*bmlH`o|w9KO7l3VO4MfnB!r6ro|w^)ly3sQ@2 zam2@G=4F<|$KPVg%e%z_3jSLxImIQpx7d6#^HLLwZgC~&Bo-HEre&rUX>#0RDNfBv zyTzHAS5R6KpOTq-iz_2DB_%Zv!p<)(fr=LiFfcF_2{AA*++s^fEz3+!y~P<H4>l@3 zzL<l7fk6QR8h!=oXXNLm>X#&zWG3b%>LukQrevlT=_lvs7Ub)eq*j#Zrj{k<=$9ns zWhTZKCl_TFloab1mlh-z>F0tHU9o<0eqM2jeqt7cuUAl61WNr?;;7NB2lFaF0|P^G zFara_j|PUj9K4<EJ?z&xBrb7CT;!0t!Xb5mL+Y-G*cA5}o(rmWWZlrv*^vH$nNigK zBLkzT{TC3?!P3L|R7z%!<^rz`To<LRuSi*Uu=MbE@OSWk21Q3QJc1Y)7(h`E!k-hs z1w#$P0+136T*J7Gk%3_~JZZ%+F)-9J)iT%MNNzPusOoE3YFL69G#ULgnTo_gVK2$R zz@W)mBn65B#)?~Pkhr<U7=Mc`CqF&2q_`NAu)vW}qySRHo|a!!o>-JpC59GmP;pUE zuxT?eFf=ec5RsVfImvTI;zXY*KAoH$Y!eu72#QXZpCrFP?4qE?6+w*-wj2DS9lS+~ zAXl(~l38A2Zfbn|Ew1?Z-29Z%91xo)KEALtF$W?8j<X_lkV|->DJ3~ICnr9BC1a61 z$ZAl~IDnm6#0T;qhydYYcSuw=FhJl3CKgtk4-8lc9u`(HkOXc5>|U_(D20tQG`c?b zF`^bWDU6_ECWR@5IfW&iF@+Tj*-}_j*i$%CI8&HXxKg-Ncv9F?cvIL@_)_>&1XB3G zm_0=>O&VNO3AJ!Wv7`v6vSuN&vPddBG9MI`5ErC~rgEgRW^qDz3=9aFG`1A67M3Wk z6mewv6bWQ=QY2A$QYbv>RMsqRn7JvU$fl(6q{y_eMDcJkq$r`8kE%;Hl{ZB+l|7X` zl>^~21S^drMXrT4iVw{Uc|7h=0Go*9<20@m#TJ$*esHla5X_*dd`khX%5er22bm?M zsd>qj;A-h1s5IgNCH0VuRE5mkf}GUc)I3mulb@%MpN6hq0oeeBfW)HW)FK6|<jj&( ztAxtLymZ}^)Vy?EBLgD?-NdW}Jua}xjz#IkR$vy$p1k<-{Gya%1&z$S5>13KNDAbH z;>@a4ki{h#sR|&43T64piAkk7iA9xqNM__DCZ*=!G$gMyHz~CUWDHbYW}X7bz>=cW z)TG3`Y-E#464Qw=C%`{g0i;q#p(wSmG_xo*MIkdy0V=AHnwylGl9HL1UaXK<l&Vl# zoSLGi;F6k_SejE}rI3)|m!FrKkbrD!az<hi5!Ql~B_@}o78Rpf3>VkUNi9pwQ7B3+ zC`v7cMI4c?NX-McD-<+}ON!89!WAl2k`M9>!r`D;N=Q%#)q?5?304YDnLfcGz6wy2 zFw`Zb7L`EMxdw&k=4584Dijo@mJ}ss=B1`6<Rs>$mnNpCDuC-M1&y@)B89ZfywsA? zyv)3GO&x_)y>vYtg@gokkU6?ZiN&e9$%)0ODeA~!333urP{Z7Ya7$WhVu^wVs8JSO zTv8N^=2OR%luSsYO97;?v?#S$0pe@a5Kl;edeRot29OgH64Xl))4`s_Oce;nK$U{x z53JTXBe4h^!8jr^wW0(ppQ4adsQ^+83U3VKK;Z*6&dD_>1U)h6DCC!9q!!^0`C<id z%mn3wbSHvSaAHnzJ}5kjGm~;sQLTfAb#y|4I@BMr2qk&(;LJcMdxNt!SS2{yAmtWA z0|R8!kkSi*5(7yk(WZl<oHz%ARF)Q{q6aQ+hl7HKIHN%-!D#@w94SsMD$C4ES4b>Y z0JkWML8Tci0iY($(qfQ8m>iOeOi@A-WKBGzNlGYopsI>X5=&Cau^1%|!S)s;ro?CF zrKDEivKk_pp9U_c3lhPlsX|G9c50piwD1O*0|_QXl|W=bAcaF}PHsN763;I&7hdlm zr6gA$-+YCl)bz~al2mY^pQn%j5_5%>_<H^UA)fwz2}r@7kf5Gll$oBHmzWc8nuJnV zfozXY$}f&j%`aBa0Cy3ilk)R(FiItb5>WRM6z3)7`3fK<sfl?CWr;bZsh|Xrl9`-X z0*dwWj8t&uF3DHOPE9RPC@x7XD$!5POHoM5FU?CyEXssLAjo0`NISO}k-b2r5j;O9 zBxr;bm8R+_xFzNkr)naXv7qt=Tc8COq$Y#9Kg9~=8JWo$3fY-?DIhnamF%$cl<4w2 zBqOs}A+s2zu0<+<LC#T6NKnWxQh=m=P{9Q%u1Y|~x1Iv19g$X=lcSK6SzMx!oS3JO zl&X*h3J*|PN+>Bx%qvdIFUn0VDo%*U85)?CHppIR=Mh^nMubL2ez`(!VqT>}PGWJ1 z0;Ic1s8#_Pj>l8*wht)Iz#aspFIbc+l;@Y`q=39xo|>7SQIeXXP+Xb|iV9G(2O~R| zWTY0SLfwVK|0W3W+{}u2Xzy4-BP}OC5nH<rrl2UXBr_jmF*r^jUPsNPBt#@UZR#QA zU{FBC7v$&XfYLvfwo3q1sywk06z1uvCD3vNsk%W4&4dK-5CEt>Q<9jS3NC@bA_~Q& zN#G(#Paz=z6qP7SKmsT#a#IuY;3^UoKwO3VveY7l#GD*G6dU3GN=N{yLeFaP6qc6Y zpvP565+D57os1L{(8gM-f(EF7LTgxgrYR&OfQyoZ1RaI6qSVx?)M8LjC=?_XCFZ7L zHfkYx8L9Avq#l%#6>1<NIP>BQa&n2QX9IkEk!n~y1<y1E107KNwiq1c$UP4vN5E4J zq?wB38l;c_D<UJ4fU9;CN5PYZp0P2qFQKhZA}esHY6X;>kK}X<)J7ImIi9i&RN^3d zRZ#V?5(LrJL2@!w4H<y~)ro03T9BmY<q_>-cRxQ&^N?H%G7DCO5nsk(H5J8`6y{`5 z=?!koB62fQEFvYq(!6XE+E=A{*?IZpdC+nZ+P=bVk0G=pucxOFk6d{odhZz}B?ZM+ z`ugdaB^jkjddc~@`WdC^>6v-yX^F|H`pBBVrHUVTAnq0ms7?1Wg@J+Lr4eY{3N$!) ziyNu&w2~<#<RxhA_c?6%<rWL5#B_Tu-}*Xmhul^BmkP`b3@<^Wh%Z5-V99bYg$xV~ zpeYH^xXtGZ7RbOg6P}^#ERc4v<`lL}lwoGn;p+t;yTIy@i4yp@69d|CH|kjA62?A8 zMurlQtDxEuV_P*$DU4MN3=B04S)d_zuzVJ1JQ&Qv7~Y24SOOY;1gpWN7sW)l-6*0w zPy-m&FriL;)G);J!sJlg4H{qsOQ48?Mv%dxDa<J5!~Idkip!NL%vDSb45<D@F&i{+ z4mKOR$x!_$W5p=?1;Lsb&|?Ti4cz_s>_}lmb>%V^28Pw3WD2&Rh9Mp_x({Zfm_3q1 zjJbvh6!QeaO&A<#=y?D%WdW8*VaW#Pz9Q=q&}chY3|DGGi9du1;2Z{W35q;Cb=F9) zVZ})QVo-}v^DSs90W5)9KGZP8OMrzL7#P44Pwak0)(i{`E17Sx=Ya<JQ*&-{z$z~A zG|)>>u~!5lRx;mW$&1g-yTzIppI=%6mR-r9DOm&x7sxCCs7$-XR$7pfSdt2wu1HSI zDJ}vP0Jk{debQSjiACwfw*>Oyp;alg)o_a&JRAyXEfs;vm|Hw~@t~>?($c!c4Pry9 z!CPD)4pf3GIJK}eHLoNyF{cRRyIY(-pgA<Z{G!}jEJ3M0p||++@>5bFvsj=WVbLuC zh+W`$Er<wfN@`AGWf3T>Z*hUy@dZWsS+@k7i}H($UGqwc@(U_`@{5aaaV8gKmZTPC z=I5<cfK1b{Lx+taL6?-8Q+$gpFCH`^3kp?GHBx+w9qQX#ETF*}kT|$m2J$1KJqO}} zq#=O-;(;_ndAxb?U>>B|bc+wnfmh+TSU|n#TRb2V)``Ex0_u+3;?0W((a`3|EpDVP z(=8sb479^?ix0ws4Ts#~fHk6TaU(TlZ}Ebi4r@FWd4lGCkm3^>E&Na)!_|3%YEd7M zVorp!IpK|iTWs0opriqrH3Cg-fqIj8a06sg36y=RGzrZmz-JNjKyy+T7{RlMAM6-7 zC3{&xGl^F?Brb56Uf?jDYc|tjj>UZYS@vtqR$8pFxF~IMMcM=+cY(w7D;tB1+#H(~ z92*2za&2(g;(5iy@1nH-6>0wtmMa_*ccqMXxa{$~ViR`5)^Shd72Dt&HVz<u;0IPF z>0ri>3?T9gm;}u|e&t|LP?}SFmxr&%b3)<_l{uPMq)aY~nQTbel6l1};6g~~MYGV0 zJYiRO!a!<#W{Av@ydr75q41)l#YG;=D?FAUVfRkY9#0U%b3)3L%qwCB8yqi+nQkbA zsQAdqs=)PyfmMME<V2aTJPeA;OL!s5scz*Ci;XoGd0ejWxP0VfRRme92)0)Cg8&1M zK#ygQ{fxv*-0~N=<?qTVE+|=2c}3mvK**8EBk>nP!!EjpT~rUhp=-D%@`|qeg}|5( z%#8AJj2{_5<QFj6;nL&(m5o74=8B}wMM=FYl6oC1J$xN}9em(9z+0@KmSXWOR!}x7 zzQtCQT2fk+mkchLp#>kPXaVs*>wzZ)+gYYFbmE-ctzkl~6uMYC84!)JEKs=!Ha3M3 zTKET*fXoMrF)(DotKANU4wf{g6s8sq<VqKZS<Ik@7HZSX1+C$h!m@@H(`5_bQ;|>y zfT>OvRI@;SSb*e8up%<`anv-NjPN+{seIoCaD)!uHURiGcy!N(N<2)X6iD2src= zH0nz7i;^?+eDd?sLsIjK^NTb=GfmNuH4Vj?RjE1(#i@nyIjMQE$m0tj6F@jTzbHi^ zGcP4GITdX{5FD-02@?!U&<83(Mma*p+49rCLvYv)1*rq|AwdoUjqIgnf`=^=60kW~ zM<Fe<0_t+mG+ROf$V~|eAdQGg2hi{zbZ$sJAwdToVj!zPIKM~%yYaE0p+k`M<(b83 zlN%s?@E$l~-VSbd5IC(P&1Ql$Km!R93y3}uND73V^YcJUHA)k6GOJQkpd)suJ#)}_ zS#d^UK`IUx>nK254q&H4#>l}#2Z#{@aQh({-iKjeU;rgQP`lxC5@^{D({zS(h8l)g z?OMi8&{8XgR;C)pPUb9dq685sjELFjP9|&_u!@U;p$6Q3YGq1eLa3g|)T0y3u#ySh z&S3@nrN{$R8G#m)tYo>xq-Su8F%w*u7b%0P2T-<EP-uWuFu%BLKtr{lbuD&PHU#S# z=&B1no1A=5^T$pPq5A;HYzN4yhYM0!5OhLuhT)7r5M02xz;KEA3d1E<8(6k*ZsEVE zY=1!UqO$V^1(yr5E?1;oAsQ}7Wr2%2aKo(#WZX)|Tg)k$xtbie*r0VT+;_KFOF%jC z7ISi9$t~8R#Ju#>q7YCO%vDwx4|OVZwMkJiC`d{`lB|U}`NhSMumG(#Nl;KwfG*(x zE%d0;AT|_Mf_yv|<l`R=3?I}Ocm?~tyS!(x&M3Xeqk4r$wS(~k8+x@MAUcKf0xWbO zjI*T|LL;w)#$5?bxsaZ5F*M_%f94hc%nMRk7p1bUNM&6pD7+w0bWxz_ia=3^;|&3k z>HL%U7cgEFP`V<Z)ZzGnjX^|Wy8R^k1%?-eRj&xEc5-wuc9=fk7nq>hQPIH<2~JSV z-(m%|6pL@M7bF&?=9LuRV#!M_FTTZ+n^>Hkj9j>a`nTXpgozWpY>+XXA)TR?qn5pv z4S4|?BBj<a)iBqvq%orw#kHKs%gt&y7l6zJC3qB^!i1^|mFL1Rfho2eR8-e;)pFNx zr7&lMtED3U8ioa+l#F5)h*QJ402HerCJL@$MD+Jlm=Sp>g(Zy%dyfRQ3PN>PEl&+= z3S$amD^m(%3JYqktmVyHUc;~e6pAP=0C8#<YuIX7Yq(JRt+hNgY;e<<TA5Oq(vV!Z z0MzpUX-2^*Xra9TKDvOc3_Wyf`D*wUz(*YLsayabdq7rI!?*z6mqr#Z0j-9D3e@l| zfR7hIg}@YQZw)m(@$qVTQBoazETM*{h7l5KHC)K0A`btdH53-WM+(4>gAz47s4f9D zYf#fcEq@LB0#NA=)q$XD7#4t<>j(iTtA-!d%mtuMBUBDSp~n=e9!7>5_7tR&e*wH_ zj4*+Lp@x^Ap+pZM!i_ejvjEhCL`XwfHM|QD*#RmBqR?H0BV5t)FF!*H`hrmQ6eb(c z$N~rUa6^e*DUi(|jOJfykQh29(uHU-U&DhMqd4LNO&5B6lvpBMlO+pd*KpUcp_C@@ zQBhcVftps)$^o_sOg)uE<uU9dl_(={s4iZBltW>zMH|6^yA@Sutw4z*k`8vfDGao> z5}_E%0<A<u4Re$@hqs+-I8s<p)q!fA8ioZ*P=in?6f+Q|0%HvaX0Ao`(E?C)h+-Cq zlfs&U)*%AdJA$=BIBXJxls=d>0FHbnfG^}~V5YHvY8B-2ER6{xR0MIjNQhJy;V&<0 zVCE6yCZQUJ1)z2BprAy-HS9I4hytdD37Ll$+rl`_5Jc8h!;H*BH3O#!Ldbe*Sde+B zCV)DqwIVgbH6kEZFvCi=#1Hs8h86HmA*3sUvqOm7oj~*;Kz$VuCZfNBstMelgWFAR zhZNL1EJ-W^P1l1AR4B+V1~1GjR>;p&C;}~N$jt|>=Ez9Q%tPz3LR*qlaRS6F1+Wvq zBbeazPbH~ExuEqHXcmK7t~9hY3${}vMFA2r#R`deDGE3o18P9S9pjXrpF<!OU>z0! z#RAwM&|=JF(CP)yDhtpwWN98~RaR;WWYQ3{2uUF|F*!p4G)7tiogf4yA9A|LAX~w! zLP3^+`bCHY=J)dd|NsBNy<4Q-m}*foxD!=el9-%*i!(K^G&i*fJR)A2mz0^8Qsf1a z=EzGej|VLTDyjzcyTCoRNRR|SJUxNNdo%NHF{P*8VlFPty~SCYS6o;MTB~r2DZS(t z7s!MX@bF4eD@Z4EZem4I3y8&;T2YXgmlB^?e2Xoypdd9br6>?2&JNSh0}98~l=!sF zoSgU~P`mgRH<HjT=ES_pTg*whxwqJh^V3Q|27|gkx409NK?_oiiVG6+ZgJ+7=0GNP zZ!x777J=H#w>ZJmsh}N1ML{4NS(7tL^RkP=K>G<q5nb$}4v?oiK|~jb=mx6=nOb~{ ztvDW(!f&xvKxlS|oyE5pOK!12*dRHO;#-^`G9Kh|C^IKDulN>sMLawZZ*eDrcQ!#3 zaTLcxGSMy8;`qGO@>`rBtKvb?dW#F3rNHcBQ2P^<U@$Ov%=s1zNJEt>!EP`}*$Ge| zn2m*jp@HFp34@~Qf}|Bn6UsWuI#}-tiBHj<QMw>~Macy@lZ!&8SA<ME*zZazEihkh zx5#dT(nV#{E6S!9CC#o#ntfp4<xFAx2qrr{I~+U8Ztx3CaO^7UD7zskdtFlVlBDJe z_3K(zm$a;QIPP&j;JC-@1mh0-6E0^wulU4W)QZ2N6@O7O;fiF!1hyM83JV0m&}l*7 z0;dI{bG#>TPT+h1GD!E5r0$Bu4Wc_(b|hYubhskv08+2G00M&-BrOPDp|n8jij3}c z8G}nQ1{(w~${1gfF}^Nieo4lB2h&9v>nk$W6F6_ks9u-Rza*o-feEI-?2?SxhQjSN zn`(}_p3pq6drJ4D{u%v?E>TxpqAr?8UonrqC=+u<CT0TXT`BoFnhU~K1g<Cq!3~Nl zO4fv5*R{K(Yqz8DqORi=UB~OX-j{T}Pq<yw4Zflqd_g7TLRiE_smLo*ksaPQc!c_W zyL@M;T$j?jB&D~a`XYF@&vhy1OH$4UoGwbaUy*XZ$m4N^$KwKz#{)_E1x$0Ku1gwR zk~G+$xj|}g@{W*;l1^77ovuszU6S;>5D<AiAofx~?1i|5ivfvO0urwWWM2x%zL1l5 zF(Cg+K>h{){0oIe7bT0YNEUavO)%>8g1TU?>Kx4lZYzwIcwJX9yQE^aq3EKD)fE-1 z>nbjnR9p@OUQ}_vqT+r+?4ne_6{&#hQW2M=A}&NmU6hKxA{Bj+C*}%I%mtp9yCUjW zM2t7M?QlI{a>VkAbJ&H5m<zFSP?V5(AvW<!MAAi(<SQb{9j=|OH^juJ=S<33YPv#X zjpP+g>x;@ZSCnloirHQfv%N0na7oPJfXETaD~=%-#X_%$g?4b?m6VwgwlsM`$VEx5 zE0S8*B~30#nrsN%!FW;9>WZY*Ue`U|C)h3o1YWcWx?&SFfvtn>hLqfODg8@Q`deAI zaPBbNk+wtoK+#15uPX*#7p1(fNO@nE3cMs0cp)hGLTLC!sfa655uN-U91~RU3QJ6} zoRP7h5Cm5!tuS1nw4iiO{&hLaOLCSww9hghD7h%-b4AYQM8<{i2q=n*z7Q1yLg6uI z@-N87T}Vj0D4cXfIH`l<E@-@HhAB8P3od{qXPfKN#+RgxH$-pnIcj`B<)XCv6>0Yq zq9+PL5ag(!kPAT}CrZ!AT#yR85D|G%AnJ-hR0rz~5sB%3ll&H#tx#EFvq5x2$rkC0 zBDPmVY&$q_h)Pb6n-sUeV@1dkzYXp?T(<aL6m_~H>U1FFc-*153n7sgqT;TE#9v5E zy^xl5B{BP=Yt9wdoQtA49b7l~C1zM%<X64Gp$Z;sy2Y84nwT388gNcV9-;vah=7KG zKK~N{4J)NH)Uu>7*0R<xB8Eca7;D*T*=w-QLez3FG1M>;H;9CNXefoLhB<{Pg$cFO zl?5LzN?}fCM0QOI6R0VUXu2+93}WbGsAXhgs9~bq9jKGtXs%#Fgb5B;Fx4<(pAjj6 zFQi~#s9{6x_@MF@fF^`dn(819>M%_WGib`bma~Qt$AA_aX!fK8Y2X86&;e8dgA7K& zDa^RspMuu$CdQR1EU2N0eFzYJ$gGwNC9IIrA@WcQYM8k&Okj&utL3iYPGNx#MY`57 zU>_Q(;lvSU$TqPc(pL&o8dD7iYG(x1_F5j$QYBETOkqr6!aD4TW7w{SwT7vN8#U#l z3}Q03GNmx13_D^S=);H|q|}CpV2qFk4LgGJK0*nUg{~6&&>^n0f)amx3*dtQP{Y9# zYI;TuPkg*u-WrAlSO*D9K=TA(vl$o=d)kqPBe{{g??jdqphg+gOaz5xI1+7e4b=zO zhXv8YxR$?$e*t_E4Z=3)03yD;Oxge<`VciyDS)2=eYj%*d{7YCt(d+-i5K{QVGaKR z8DxDhHfp*cE|xHc4zUiyq7O^f3e+$xfDaME><7^(E{2CYd{`SL9n}b=F`*BwqQ$-( z$V_yc!iug7Hmp@6NL<L)2oa~QR;X4Gsa(uQtrcJcTqw0Wd{8nCJVcD913LUvBSb_^ zhqcXs8a}AJ1)x<p=z#@V0tz3F%!0cPRVT!)HT(;(4tAEfA`GqJN2<q>rgYHHOu!mL z{I$Y0f<)NCL6m8NwIVe_R5MMeR<wp6N1kCt4XqkMBGn1uP=_|b02-9TUcaNX-B9Y) z6lT=+0mzJ6u^KTF%|R=BK_=jcUlAPQqS(bjZLAs`a<!7R61CzrTsT4pt&FV^1N)7u zh6{(^*wE7&_B2t$jIIt`YH-y`;W8PcJm#vA!amSmBc8&xh8?w?Q!8B~Otg!!4l}1P z<Fro#(>^rYg>g<#qld3FD15QI6e9#=YD8*e5bZncx@s_EgjD}YV*0N}vWg9TNq4PC zjVN{9gVh#Mlv+&{RvLl^)N4f17YSewlN1j0)K@E8!?HjPW)?DC!wouLs77`HQmYIh zk6O#4uQW?XD_a;DYFHaNYFLp&DUT7<ODzEnF+z>a(u6V?YGi9zvDas?c6tp;9gf!i zW}U#+qfx_zJq&8tz<Chmq$KF{4hwSovX-fawT2T{uEdhMv|z4BrqR<bD3v2pZY^sK zEB1+h^!`9CFG}pg7mL^MqSgwvay6_qa!5AFr*O3}ptR?4^pa4`L66Z|g%Z#}Gt_J8 z3@O|#3^j7-sunTU$P<%ZCW3qXE)22qag4Q!wMsP#HHru~<4BK6s4iq==uxOqs9^zx zXgXu9a*c8@gC@_zON@Be8V=Ny5@@t};N~)rN2K9{ND5ev9{?$IN=?jF0F5#!fTm1R zKxcJj=A|R;(t_=t0x8BiIRZYK0!)B6gvZ8Wt|5dhzfXqj<xWdXF3B$fFD3*Jr-SBX zic*o6aY9z&74<PNFhFKbKug$ev8LtZ=NGMHyv17t+6$eTmk!>JP-Mlxz<{!H5Hwr{ zT3hlN)RKp;8|12GtYJ(+I#p*PQxA7A!%9Yo1umc+4opS0AR9r`+Qp#tQ3?v+q5PtH z1_p*IYl0*B;IK=@wyMvLk%8eesQc8wa6#7xf;JScNZi1<CI!N~pz8x3^+WLosG|q= z2dMuH^#@BWV>-h`rXJQ{h9Z!o!Nf|a%R#jSbzSZOayh8G+Q4u@%oKuVBu*%Tur7$1 zV!9e0`eqD}0m>SNSTRuOV?P}WwQ8Bj)FTe{*-FM+Y$f@ib(K)>-C``JuID^Ko&)t? z8W=9f+C$Kaz!{12GiGJX%$k!05xF315BB6rU9@SqqUoR+DYl~2g4D#4TP$UnspUm8 zK?w*v)5emMpO;=V8N>$--QD5_pAZ3^O#@Bu6-@!jO$8CtK*S6XF$+Y1DoOAJA$X>) zXf{X;v_i6I9*8v`M1aEb7I#j5dOU3IZ6U}p%&8Rx;7PTj<sel{Kw?aJskc~4@(Z$W zG3RFHftG=m-C|2m1T7#gngCKY2SgkP5uo|IqQxLhY>7qbxrr6GSj#g~i&AefS7jEg zR6&}X15L&ifzH#rB?{hQ4qA#FUr>~qk_n#tD=u0AGKCAVn!5;;Hj6-&$}M)VXewwH zFFC&`wYX>v$nJF@Vm*l103txkLW@>`Serq_77&3tA$W_UI370DmmLo(=WelOL#6{c zvf)#B$%%O>#kW{N(#5yfp$o=~)`DEe1D+U!3f<xc^S}jC@hxuftT5O^#YJ@>#VjD{ zTTI#6#h_*-s4OIe!DR>Nh&<3KMOErV79YPE7#KdUX9rIOsxc@kU*M3vAt2JhdP7ob zj(7)O2iJta8^YpKEUyTwc5po4vFdOHFPCNP^y~4v&ZBsV2Q&v4xq)$m;YA+PD<EXG z!{`E!&jH3G>?ascFr8pJ!hM0q2ZA~nZ}8i8l=Rni)y+t}$ggmPU*S5x`Xzq#6^tt^ zHzZ!<x3~gAwmXt8@CO|*IbwAp@kG*zq$740_=6y*gXMvc@N}I?I&(`GL|v3OxFT<G zQONL$kl}S9vr9r|7lkaY2wCi~yeQ<-!Tvx{Xu8xSsTol#BrnJqZ%y71a#7IgilEhX zLAOhSZU>4^7@oH|Wpg1S@}&J4`|IBEm%QUIdM94-PP~wua#1k#ieTz>!K_PySr@W% zFAC;e5zOmgyDKO*p>Rt1jKV2Z7X_8B2r7MGPzO(eg2)a>BBwt+E^38d(F(mN8Foc7 z3^bED$Y(xph)P};)x0FCxmI<J=7z8xfjbI8@POiul0D(qZT&9U`kg4eXd8INHt@P_ z^d;Nq3o%I-ZIiFqCSNc~xsaA|Q7iL`R^~;~tSh2f*F}pii56WbF1;vPc15(T!|jHs z^mS2<OQISpG*?K0BT3Ziim26fQMXH?ZYMa;^Pb`b&7yilUh#;$?vZ@SBl$u~+C`7_ zD<0_=+|w^)W?dA`z9O1^U9|j?X!(VTs*9r4S468j+@6X`O^KXQHot0C)y$eXHP_`$ zFUgy3NW3U-aYf!@huTF^$19?a*F`-qiF%$;yeR5(MbxLm?S`Dvbvffpa>iR-w|MR- zJRk^$jt4~cl%HU`VCR1!F!-WL$Q6^2i*lh?<U+5@MPHJOz7P|8AwKb<T+$V}q)z`1 zj|r(a<kYUq8C{Yy+F*21&g_bu*$&q07M_<ZJWnWHwD7%R;X5I<!vmgJ?wXiyFqyzH zLl6vI=6GI_(Z3+6e^J2TZeq%Xgp>)a6B0pihA3o8eXS~JG5!?;r;A$7SG1fjO1fN; zbh$3+eo4~(1j`xDD<07oC1b8g##|7KxhN2OLq=)7_bl(V%q!g1`0Nn6qGPio^P+~w z6%CIQN*85(ugLgz`gXWYaJ`|Rv7C1i@7m-I8aq5M>bYIfb34IwQNjC)g7-xp*$$5h z={Kb0=WET<S{l4UVuR&HRog47wmXV0N;zGTa_aQ%aGhXsLtOT{xcVh=^%aa4#kH=8 zYpuw*uIF$`&*6aJMLp*$dd>$@kLMrCzYrFF(JkVNTf{}Zi0is>mvrMU#3x*dPrHzw zaV0+ULUzuDyn>6mg;#V7FNzm-c-#<|pI$quc0u5h@D+heqBaO!6gRmdZqng#LtTGK z-G-zq>Xtjq_t>5gx?=5fqU21~g{YV_br-E;FT^K<jLXWo5}!N6V}e_U+XGNiQ@tdr zx*+MIsOA+>%@rOOMNK-~9zcR<1=j|ri!$a{WX!M2*j$pa*%5hy>7tDH6&Y_x2t5#$ zo*q3ZdV$cy_$l!nZZ||E!6#RyZE&C9c~QjXiik~zD@f35lGlu?6-F0D^sb2LT^BLE zBx1TDX@}~5&0U%Y+%7~V?$Eqwm2|}lJ~@6vT<*HK#wBr$6+#!qb*_l(tSG%GZgO4B z>XMk%4x@`=c2~sgI@~|7F^J2}NWUVcc3n*Sl9=`iuN_Pm#jLN0Szi}(x+Law!015f z@ybJ$7Xl+MWELE#yy#wd#l7%CNzFy~nu}t!SHx;N+;0er&tRWodtF%dlCbK6tPM&R zg-x#rn_d^Txg>0}Bj|wW35ko2fft2?t_TNpxZD+$ni9Q0b%po_l?#gI7ey_uh+141 zwY?;2yCd;{&_z*~E21tPZZ~)ouk&bJ;?Y>42x(gGaNF;@%Xg>$9{&rvJ{NU;uITz) z(Dc2?<9CI}?*fnC4K?ixYUUGMXQ)r{o8Y%2q{Efer34T7h5IYJDrZP7h}^(*k>B_V zzwrh~Ff82Qa)sZrgXMvM=!EnIY|FV9af5?N!TO4V^>qcOOA1a0j4mp;T~TnmDCTxW zz#TNZE;-#}lE;j|iQZGZJ2>x(%S@?WV0lqo_lme~2hR;L=@~v(#56m&Z-85)OHEe@ zt`XlLxJK%tvdI-?lM7;|7sX7kh?#b9-<6QQAQ1*>!fnvGAZve7*8YmD{RN4z1Jc(W zgD*J-Uvvz;;us22BoTH&BJ2YLBc}$K=<w)poWOE}M|=h&yi!%U$fJIRNBsgA-QbhF zAY*uu&+r1TQ3ulve!&h-a1#;S>H#-rl3AgBXAp&$vgZP|h(Z036oyu&6owiW)XB#h z=*}ignOe45)*3cYs}E!#Do#N=U$&OLhAD*sVgq=RlL^E|nUsVN&Lf+IK6p{fQNw}5 zMzqOg)IBOlM<R2ecH(Qf2)V3=3o$TI%Z+n)3OAa$JfLYq(7qOg?iw!S>1X7jo*G6B zl}IaVkyU~Q8>)C27;1TH*lRdJyjtEGUhD%+=&^u(vZaO*`?kswq)FErUhEUzs68dr z5WvT)<*Q+*xtsa2;QMQkcjDo57pfd+I+dTHhOdf|fdR5eB@5JV0w>UPh8iUE7lD?S zV6_c0(1c?d0Y7nJP{UfohDb$d1Ka{N0ys?PAkuWST@$qeObj*5C_WWH3P}b~{zbTE z5n~OqEYeOEh|g;UYuJfMUpUM_jSo~F_I*sCWk4y6sFOlC1~@?rln`--G>Mmjc3w-Z zP>m3YVT?ApfV^KW3%;-dR33oJK}2Yx`VcLqh0+;ngs?B8K+T7X7;A)(OPU%X<b83V zJ*S|!iD717s1>disTIXFL4#3#U@fC@>c+c7sYZmj)QNrR2Tt91?F8pz(BvR!@CuxZ zk%<)05;C-tO0e&1su9JpAB-i12^6|$v52yFhmoO1tOi%kM4PmLx>poONTK<)2A4Xt zx)|g_>^q}s#P}I%(Dv!zSa^bFX02F_AohhPDU7%#W6@I=dah$+s1d9Y#J=Mug)xN< zHFs38GcaJ^?S`5+Y6WW;urGS35vUQY;X^GsY6WUI7Qh#rAg7iZjvB5Mq&k|U6oGQB z0-iPvdMI<&2-F~*b&hLCEPBXNQ19bd=!P1m_|iM7TrCH<c40)RT{sZ63z_vOuKa`+ zel-H9X{MH^h9{U|CA%MFSRZtx5P0ZalL;*F@*ilM1ZbSU=sjpGUZw~<C<-1P1?`n6 z0$siW-WCBKb}a&rmcmC{i@@Wipj{HTI6+$;s#1&ci*NCRreRW3;)|0LOG;9U;)~9L zMiI||2=Kt?B+$SfQ%>qFj+D&AbkM~mw^)<&3o7G_mV(rPMq6)z2SPLRZgId30YwLR zE+Vm{$QNV+AF4Gg#gWEILBpU$;K5SRAm=USiui(CY#{aV1-Dp08xe{SL!Qq-mVyq7 zD*}y$!nPfNHY;!>rewu~bb&TCz-Z86@VA%~Q?hPxf}}y?lf}1KLChQoRRp2RZ*hSH zA$uB%K?~M!j9h{TEWxAFRR#n{E8&|bAUja}Ktt)ElkOTAKJYP!OUz&dL!%jvGmK`i zPRUrnvLFxyS1_#*T*0&;bP0DySO@bBe$oD_uBsVIopn8R9V|CQBxfjsVepKk8Nmw_ z7bq=InxS<?MD@Ce#w8Jr6@nK<w6BP0cW~Yik)7^4$#;PUOaMzi(QyU{7B66$QM|x$ zfztw~8D3Y!)K~C;dxtj!MXw7gUJ_JXpnXwL?~0&a2ipw}z6pvGd=>~!@m~<LL2*g^ z1rd`gLZ&+ycjz1_+@pU2G%|U{{(@E16^rPLLeUpFqC41bh)B$^yeOj5!FfYi=DM)j zC1JG%MHhv&t_W*g7uLNbth*v{ea@<!y`~2wkINpCJt%)f{-Sl@73;u@dO=t8f-VXN zUl9)O-~ipQAvZ~G0n<f6<tu{9*9Fxs392n9Twb%NW~=KCjXioNgsxcmTr}~$V&Z#I z-S3LJ-$g<HD}w$VY&S%uC%DhZxG195!TCT?W`f`p=?j8ZGcxAnT@bWdk+>#(L(-b; z3xZY<bY0NvlAzZKv+Lf`m%O7d#Kc|nj=$m^e<3mDLTdJv#GH$QxmN^pJJ@arieDF0 zza*%>g7dnD^(77K9ZnZD?5}9p9}v4J=y65Rql4`RpG-$ePu>MS#~EpJa#k3xa9Uw} zMNa<$pW_CxEiyY2x5!`MbA+G{X3&y(|4IH!U00~B(b-VAMjx`n;i8E36%p&}A`X{C z91aK`a6C|SQN-(th}U(Iz)K>KeF0%tLP6UYu7t*4NQ4d0fMWl;i0&m3-4&VF^&Bth zIUZ2FsONG;&*f<9k?adWpy8_v@rf7W6R!j%U35#n;+A|-B;|@oN(bi+Ilmc|*X8vu z$?IQ~H@qTmctOr@gXNCEEj9-<PdFaYxoGTnK@Nm2a!7Zuc9c#?y&)<!J$_RBf}o3{ z8dpR$u8V4464hSey54`4{|={%I`&s|>@SKsToH9RV0zsCko|?=(2LGtSDeGHJ4aq} zj=T^Re?2PmQdH)JtelHcxmTicFFNO4an8Fan%BYgfJ5jyhx8>5=^2hQ3Ku9|<WRZ7 zp>mx=>k^073e)u#t1LD+?qJ;Ly3&4){Y4JzD;(ArIIM4o$}iBou4H;i2{d-9WN}5w z;-aWU2iF5J>FN2C@)sms6w|ySritc2G5hPHzL!LOPgI@Az7QRAQ8f07XzX>-luM#1 z7gEzNie_99&FJ8|!NJ|n)5S9(Xol2vN$?h*q>GY<S0oKL7+&Nsy#hY^>IT2igy8A1 zlVTSbEhxGus&z$F>mt9_bw0yOe1;eKjIZz+cQAueGx)xk6~ZerE()4o5i|$o6xr({ zI+sLrRz&XLIS{yq|GI_OB@3?;h9?S7nqIUBykZe}Q6%V!NDv}(D_s;(y&|I8!FfYQ zX@TVx8Qm3?*Y%w)>4V0M^xdxLyIt4!yrl1WLh-!LDV?j~F&ARfuE%Cwip{zhn{y>L z=VEy7mGIn)UU^r%@-FJ<U(wH>zzIs)&`e@IBXdsv1wrc-g=@+;6s@VgAZQIi*9E;V z33{LKyzUc!$tV6oLefQ_<SRbO7gDn?3g%o9%t5~YW+fwdQ=g__kp`&n2CZl*0xb-= z#U3A@lAjzO4>|M>RDs>%LhLLp0?q6efhJ0Cu|ak@LT<<5LTr01+77B(m^1TAie7_^ zo&q93>p+ThK%2!todf7`E1;7Kia-RY=~Vn0a%>sozMKYz4@?1!tQ;R0z+@H^gQV;Y z5R$(kE;}LPhNR35IYls1xFN4}LqYL|nDPxdts7!eH{=y=$jaZ4QvnG|$={Hb11V5a zy`iLhLs8|1ocs-0g&Wc`H>71gSX;8{e_+5xlrhS(N<82fxxz31fmN1O;sYClfXD>b zD<Uda_*Fl!gG4wOxcECtdupz5%6#Ai2{51%c808K54Z(-Y(B6WvZ{d$5CxgW4&rby z2#H@2RQ$jR;&3tWi(KK8`@jw2@IX1dAPye`7k`h;2YwKn0hP#OWRQ~nz!}KMD)fN? zL_)0sF+Z?D4PgiKI2c64p(?o;xcE9!CYbhQU*VMczzvoL>xP&CCDWMHS;e5{sk4e9 zoDSk}K+Wa^akv<G_&;!iSUeD?@`Bh51PREnBPjN<-)a=Vg!NV<<`k9`))cmMrWAHC z<Vayp;RN4k#GJyD!kfaE!kNOK!kHqFBA6nSA^^smDZ<cujYPor8iDQ+0!<h*fIx~E z&U=l-!S@=$RU-P|X>8zIk|bJqqBy~~5+TM1Ag00j2t6ryOiPh$VTs~S!MytjZcd6! zDl4M>n<9(ClS^gI0_{%)d50kdbaN3xp8|?X&^=6W|D*|kZ!O~GWJu9Lvm4b!rBu-E zNce70Qf^_5;zu(>1;u7m6IH<`BHb>P#+9Ph!V)ErqK<O!k_H|#Q2oM@qS?X{C77ax ztUrw@MZ1M1N(g)}lW;JDrtU3eLhZwV{Nf^g(7DK<Gi)HIB^MchOSF>2^ddu0VFo`j zxyTsAH31Q(AOf^*q{y6sfx)fF0>lR$5dvQ111@W^pOE~Cv=frqM^8vbTpT%iLNWsb z;+$&8Da<LOCnST*K@fp7hKlvP9B7D<ctUassIdex9(1M=R&!BK0D^C_L=hE*8o-dk zSR+}(kOkjJw1#CF8w0~?cqv`O5D)74f|a9~09xAy7ENJ=9?xlA0xFNdVrVD(V0Qz; z1n}8{;7thF{Ug1G4Ryq;h9MrlDXRoN+rhw)1!~HHT>u(vKwM8+!w?TzMF^GwpUunx zT`6e`DknjMCz{Nl3-KV=a~8>gL_rG~i$Et2fmaG@$`*lE6hfM%p!%%{w9lr<4Wtqj zm_?u)7a=Dfg3j!P47h+!Vl09m%?lp%DDng80C~O0AH)g(5#V)epd%f?*DMxAfy6*= zxW!kHUyO9NauMiI#UfB>f)5%j3I!<y9sf`i4r<$iR^;IrqJRlEK*lOSd%dc3h^UL; zNBf>;WMC-fU>ZHzmo}#f<2>5;D-VOb?hOHvDV$dXv{tyR@w}qr23Z^vaYI^WLH>@E zJ=q^vndSLDGBC^YeE|`mlZd51@S&gmNQ)zZ5$9SKm4X%%gSuznOa?uM6vY3$juCVT zLpwt|>vTNVFkrty7<4x<>TqZmYbV13P~L>u1E)J-M<Oz%Fm)o`FPsJHFM?HpCZf4P z3kbkRCn8VmqYVHvW7nU;3@z${PzoJ*VcEgZ!3sJqtAzu3Cjkz#m_V*UwHJM#Knm*` zv<U>T??D9s*gwcbC)&O@uu9MZ3S>oKHo8jC&Z;ifT9!^$$T6D144UkTXHfPB6cprS zrWPxJPe277)dM}<RG}cTxL8lYH?g2tAyENxTn^|+ThK|xu;YLgG!j7E;sj05rA#Fm zshLFz$@xV^sl^5Pd7wK074lL`ixP9-NA03sX^A)x$Pwi>QBZ*fHrGm_1au0ko@ZVO zWJExrP66d?;iUXx1#N|b#1swavB;VV+6tg+*t8YEXVJ&PZ3dYMI&iqyN&&noA7U`X zR8&=<0cfbA%)F9V$aSY6?Lp9Uf)y%s6u<|)q8MHQbF3TaGA)R~#5z|8a$6ASQfXAT zfUUu9upz=>(E1LPaZr}ZgQ_S{#r8P^`LJNUTB;ltoC01<gPhMMGWF;OGZa;VDlSm^ zFRB4mT%ZgJKNA?TYrvhD$_bnvQ;T4S?PA+OpuohyPz<W2e>5;$kjjOi6M;mW3w$6E z1TV<CUy=5JXuBYl3mG;5H5iH-7#J8dxgf2ACXjzb7#SEKEdX#e4H~<GtV0JaYll?W zZ6H1DkZBI2BY}%S7aA0`gA4)fp@5vy4~iMk;lK(GkV^X&{Lp`B?yE8;BaFB~;c*Xq zYVeN+hOcrAyh5GsJ?{N}U4Ao67pPw3(YV5+(ZP5_K;*iB@+AS~1&#|6L2!lOiog{m zYbw{&U(~g`plyFa(;mE}RPchD(-jrxivliJ1Y9~;KX9N|JD?+E;K2uBTn!4p5D{}F zBJoN@`h~3QixJrugL19}<y?@;y(pD?MJo3~amfXN(u)G6R|HClKXVwg4pnuAXh;18 z4mof<p&U&QN@L*a2o!nK8F1e@UW0xLBWMKzb1h3PxOl8#O=AY#DPB|#ib}>J2}TA6 zO*XU`1)uI*Bo0asphztSRS=-k0k$s&v{kT5o0!;xMzsbg)<A=p;FF%E<)KF}m2ODA zC}nd+%BGVabm;N~Rq(OP$Uy*c3F`WP@U$A}BrxzT8Z00(8M#UURT|)s@<Bd-nX8tw zmILM7N6=6zxI)2k{xWw7(ptV6ZX6qk(N+_nSBUWQmw9S=Yj}t_f0-NmIs_`8zsv_a zPZjg@&02oE=P!e{ck-ZZ#N?~tNC7uVAjhiE@cd<*>#$PL;sN`*r5Z-;tCUdAUlt%{ z^$%)1<Kxxxqog|cdcPVz_(2ss$ZHR=uYp3}D2n}Pl^Q-&mtdacS}Rz?iDSJDuJe}# zQO(4@ss%m#QS~q~)NmrNmBPN>rG_8>d8*h~snqaeUy*|DA{^n0mTs_|zsw0ef0+w= zxS_-@yjPFrUwFSBT;M<nB3+2K=C+0pwL^g;KG1Zb#|Mt{mw9VAP)12Wy?C%|VdX^) zN?JuL2RH`h`O88m=Pz^OJ4JW_)+0%XK7W}D{pg)qu3Ao#&tK-k%(bYohy7Rx9Oo|! z*NUK|P(=A73@@|MR-@y{XF~Wwt_EfrF=rhM<8YA(sV>4_Uev(MBgRc4I8Q$2L_X^n z@A=E3IL#17F@v1*mqk!aAawq+7*3b4p_s#t%tI|#YQ<|rA;+QAh=aO1!3;&cpcZ~V zsNpC9X)%IZ`&e3MMN*))qcn&BFN8vD>I98xf;UQlw_<`9JRz-w+6b~>6No@;{@e=U zZUaprag-#cLylktjXy#fq?jaRgb*}~PWUd8fc#=T&^fI3p!TWO=sB#$*JaE`&tV<$ z=deB<s^_pipx_+V4;-MIfb1sOEl^t_vP5SC%Z89GTo;9{uLxUraD3ok5Re2P)4GD= zBEP`}4g+ux9lR5M^psX`3lWWgoED2Z?KOHzD=d&Ox^u__7%)W)sFQ%Br?fIKKre?H zJ*5?%Mj#B-l!Dq_z{eXsrImpJ<HTi9>k<;INF>f{p3pX-;TR@FQ#E=@D}3+^<%GA< zQ(BRd9GHnb6N_?I9%w2ItO8&D9zCTM97GHZ3@GQy5_jh7=qarX3=E^Ew8Bylh{iZ7 zVf2(%nbA{Pvp{E@fszNq=qarX3}}-Aqo=fjQwE5r9bu=m7VTnSV1TaN=>rYpg4!(L zYpIKNgSdM@1SO|<7VQU_-~uAR7ifdbhb>Y7AKqz4%pwKc=XdU7Vqhpb2r?ctF@&=4 z2(-cgyzmHg%mKbLI*Sg2mIzVXWhX!`JA&0^pp_zEmx1<EKwU=8Ih;kuK*ocwD5JLP zPl8;33S>MeT#HVFShqmIMA8|H;0<zBTEs_jHOSgGAj`nkf~O`x+p|XxZ32}}HKT_% zfr0@Ej~?2z8oo#hwU;@1XcH)zq%)u#%QSju6DUxi80YajXd_|Bi|mj#9C4+953fUP z07XrIXj9drhc-b&oq=KW&?W|kl+i<*7*>PYY~WNedT0|k7{J8np-tdmU_cKC?1wfL zy#uwCKY)l|pw>BPCne^B8?Xpu)eY#d3gVXaqa7o34%9N|0Ie4SwajmEf%XmN<fmtr z6yM?ivB8VHK^+^2^BEXGOS3^;u+I?;prch$7L*~{EDQ_`pan+|O|>jc3^gn@j5SDy z5Q3I|Bh@h|M}~ox$tTL8>?6Y1!UJ*}#GUY4KOoy;G_6o~@j&<PfNrn{`6U*yF9;NT zAY(wna6=GBhTt#=%>dBZP;kwN!$fdvhVScv?f8KUfZT(;bI3{objx{wf3QMHVtP7g z_Y`Qw6vF+QOhw=gq@c~5nyk=uVW5~)0TG}hux_z~bi}9S6@y|8WIp764M^02<cQnL z2?`~U>K~xhTDlCNqw>FsFbIoY5mLP<q<%$6y@UM*zgS24gsKH9SH#s<NNiA9BL_Ll z{sM;uWWfe#Q$sSmXk=hu03{+2{tOz2n9fiFNh@Fy`<6cRtW(QW!xYS*$&{#yoK##u z_o<{RfG(iV%`Yxd$jQu3&8bv?24gYOz4Ms+!XW+xC4P965|^k@;*i87f!Jz=HAR3o zlz|D*hOt;HxK9)cQi~M8S3!X9kx5NV&QK^$%_~XGOHNhD%mar2_}&LZiUFVdrpZ*K z3`!u^LCXo5A;|_5Ikz}L-Ur<%QCtj)7X|2e&Mhv;Fim_xesPr^@qK=fdRArzhGNhS zk_`-B#TZ28uZyT&5&<1PE~0rwM6-kQ0l&lr4hcvC;RJ1n5kWiFr-%#WRM4(t$n_jN zATG#t;In+dn`nx-L1LhtF-5!}7H9!t5g&+!IL1dE#MJ^3puI2{2l@zrWI#j(XtVMv z$Yy1n2l`0E5A>N)Iw7A*NBY=-j`YDrI50`E$}b3A67zvUidBAx%8t@KHCL>Bz`P5A zVHd(<u7oFF2}}VC;3lj@S><5|1BtTAgAT_*Iv5Bff^skrNPq#A(6eGSgr2Tr#cBvL z0CF%8hyy<u2*iOO3<To94+es8H1)1%SbX4xa2y%k7_T@4K)A3&gFsRYsDuO4kU2Cc zgpr%oa)Id*n-2`!td=`WuULD7Sr>vMt^_ATm>IcOGD^TqbV7=kRdNCA5}pqXysVN$ z5Rl9RO1zp9x7bQ53o`T45vN^&bImOdNVSre2d*$~aTk{sBo^uA=BK3Q6oG1nTk=RE z#d^v4dBr7qiCKCjMTvREY57IDMWBsnw|L>IN^??+i$MDfA!iDJHh#fOEiK8+DJ}vX zbZ|=uq8==wmz<xQo1a$%I&<L`AF@PRUJ>XJpj&Ld`6;D2sgRQlK<6tJfjk91LjmGP z&?yDKIBask%Iu0v7#SEq4US@eMh1ot%#4hTAJ`Ze<u5SEVWI~NJPlxYgF*BHD!RcS zdjS>QV6eY{if%BtUcilRVAyzrLFoc2!c_Btg_}|A0|O>8A!thEN09gz5CKsk6~zit pjGbIi`jG)7^94+PfRI&OQEZHo9~iKcD^x#%Wxjw(OjY0j2LS!@xZMB% literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-39.pyc b/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d40ac4f8b95a668781a063d3ee4aa591fe26927 GIT binary patch literal 13878 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 YR69^)6@%7b2rzLl@_?ZLnB-vw0Lc>K>;M1& literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..080b0dba88ea7c05edcde2a12f2d5e17b2756b70 GIT binary patch literal 14431 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b58212f55501521f49a41f39da967e6efed3566 GIT binary patch literal 32140 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..731814f0b914ad90ae5e604f6a0883b85690c09e GIT binary patch literal 17396 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aba0194d23a0b3d6f8024b35018c2b00be0c9752 GIT binary patch literal 24903 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 Cl!Jx< literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/aj/model.py b/tania_scripts/supar/models/const/aj/model.py new file mode 100644 index 0000000..8f4a8ce --- /dev/null +++ b/tania_scripts/supar/models/const/aj/model.py @@ -0,0 +1,786 @@ +# -*- coding: utf-8 -*- + +from typing import List, Tuple + +import torch +import torch.nn as nn +from supar.model import Model +from supar.models.const.aj.transform import AttachJuxtaposeTree +from supar.modules import GraphConvolutionalNetwork, MLP, DecoderLSTM +from supar.utils import Config +from supar.utils.common import INF +from supar.utils.fn import pad + +class DecoderLSTMPos(nn.Module): + def __init__(self, input_dim, hidden_dim, output_dim, num_layers, dropout, device): + super().__init__() + self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=num_layers, + batch_first=True, dropout=dropout) + self.classifier = nn.Linear(hidden_dim, output_dim) + + def forward(self, x): + # x: [batch_size, seq_len, input_dim] + output, _ = self.lstm(x) + logits = self.classifier(output) + return logits + +class AttachJuxtaposeConstituencyModel(Model): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layers. Default: .33. + n_gnn_layers (int): + The number of GNN layers. Default: 3. + gnn_dropout (float): + The dropout ratio of GNN layers. Default: .33. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_gnn_layers=3, + gnn_dropout=.33, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + # the last one represents the dummy node in the initial states + self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden) + self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden, + n_layers=self.args.n_gnn_layers, + dropout=self.args.gnn_dropout) + + self.node_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 1), + ) + self.label_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels), + ) + + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1), + n_out=self.args.n_encoder_hidden, dropout=gnn_dropout) + + self.criterion = nn.CrossEntropyLoss() + + def forward( + self, + words: torch.LongTensor, + feats: List[torch.LongTensor] + ) -> Tuple[torch.Tensor]: + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor: + Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input. + """ + x = self.encode(words, feats) + + # adjust lengths to allow delay predictions + if self.args.delay != 0: + x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i)] for i in range(self.args.delay + 1)], dim=2) + x = self.delay_proj(x) + + # pass through vector quantization + x, qloss = self.vq_forward(x) + + return x, qloss + + def loss( + self, + x: torch.Tensor, + nodes: torch.LongTensor, + parents: torch.LongTensor, + news: torch.LongTensor, + mask: torch.BoolTensor + ) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + nodes (~torch.LongTensor): ``[batch_size, seq_len]``. + The target node positions on rightmost chains. + parents (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of terminals. + news (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of juxtaposed targets and terminals. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor: + The training loss. + """ + + spans, s_node, x_node = None, [], [] + actions = torch.stack((nodes, parents, news)) + for t, action in enumerate(actions.unbind(-1)): + if t == 0: + x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1) + s_node.append(self.node_classifier(x_rightmost).squeeze(-1)) + # we found softmax is slightly better than sigmoid in the original paper + s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0) + x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1)) + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index) + s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1) + s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1) + s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1) + s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1) + node_loss = self.criterion(s_node[mask], nodes[mask]) + label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask]) + return node_loss + label_loss + + def decode( + self, + x: torch.Tensor, + mask: torch.BoolTensor, + beam_size: int = 1 + ) -> List[List[Tuple]]: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + beam_size (int): + Beam size for decoding. Default: 1. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + tokenwise_predictions = [] + spans = None + batch_size, *_ = x.shape + n_labels = self.args.n_labels + # [batch_size * beam_size, ...] + x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:]) + mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:]) + # [batch_size] + batches = x.new_tensor(range(batch_size)).long() * beam_size + # accumulated scores + scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1) + for t in range(x.shape[1]): + if t == 0: + x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1) + s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1) + # we found softmax is slightly better than sigmoid in the original paper + x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1) + s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1) + s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1) + if t == 0: + s_parent[:, self.args.nul_index] = -INF + s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF + s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1) + s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1) + s_new, news = s_new.topk(min(n_labels, beam_size), -1) + s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1) + s_action = s_action.view(x.shape[0], -1) + k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1] + # [batch_size * beam_size, k_beam] + scores = scores.unsqueeze(-1) + s_action + # [batch_size, beam_size] + scores, cands = scores.view(batch_size, -1).topk(beam_size, -1) + # [batch_size * beam_size] + scores = scores.view(-1) + beams = cands.div(k_beam, rounding_mode='floor') + nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor')) + indices = (batches.unsqueeze(-1) + beams).view(-1) + + #print('indices', indices) + parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent) + news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent) + action = torch.stack((nodes, parents, news)).view(3, -1) + tokenwise_predictions.append([t, [x[0] for x in action.tolist()]]) + spans = spans[indices] if spans is not None else None + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + #print("SPANS", spans) + mask = mask.view(batch_size, beam_size, -1)[:, 0] + # select an 1-best tree for each sentence + spans = spans[batches + scores.view(batch_size, -1).argmax(-1)] + span_mask = spans.ge(0) + span_indices = torch.where(span_mask) + span_labels = spans[span_indices] + chart_preds = [[] for _ in range(x.shape[0])] + for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()): + chart_preds[i].append(span) + kk = [chart_preds + tokenwise_predictions] + return kk + + def rightmost_chain( + self, + x: torch.Tensor, + spans: torch.LongTensor, + mask: torch.BoolTensor, + t: int + ) -> torch.Tensor: + x_p, mask_p = x[:, :t], mask[:, :t] + lens = mask_p.sum(-1) + span_mask = spans[:, :-1, 1:].ge(0) + span_lens = span_mask.sum((-1, -2)) + span_indices = torch.where(span_mask) + span_labels = spans[:, :-1, 1:][span_indices] + x_span = self.label_embed(span_labels) + x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]] + node_lens = lens + span_lens + adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max()))) + x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1]))) + span_mask = ~x_mask & adj_mask + # concatenate terminals and spans + x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p]) + x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span) + adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1]) + adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1) + adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:])) + adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0] + adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2)) + # set the parent of root as itself + adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1)) + adj_parent = adj_parent & span_mask.unsqueeze(1) + # closet ancestor spans as parents + adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1) + adj.scatter_(-1, adj_parent.unsqueeze(-1), 1) + adj = (adj | adj.transpose(-1, -2)).float() + x_tree = self.gnn_layers(x_tree, adj, adj_mask) + span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1)) + span_lens = span_mask.sum(-1) + x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree) + return x_span + + +class AttachJuxtaposeConstituencyModelPos(Model): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layers. Default: .33. + n_gnn_layers (int): + The number of GNN layers. Default: 3. + gnn_dropout (float): + The dropout ratio of GNN layers. Default: .33. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=16, + n_chars=None, + encoder='lstm', + feat=['char', 'tag'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_gnn_layers=3, + gnn_dropout=.33, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + # the last one represents the dummy node in the initial states + self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden) + self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden, + n_layers=self.args.n_gnn_layers, + dropout=self.args.gnn_dropout) + + self.node_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 1), + ) + self.label_classifier = nn.Sequential( + nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2), + nn.LayerNorm(self.args.n_encoder_hidden // 2), + nn.ReLU(), + nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels), + ) + self.pos_classifier = DecoderLSTMPos( + self.args.n_encoder_hidden, self.args.n_encoder_hidden, self.args.n_tags, + num_layers=1, dropout=encoder_dropout, device=self.device + ) + + #self.pos_tagger = nn.Identity() + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1), + n_out=self.args.n_encoder_hidden, dropout=gnn_dropout) + + self.criterion = nn.CrossEntropyLoss() + + def encoder_forward(self, words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]: + """ + Applies encoding forward pass. Maps a tensor of word indices (`words`) to their corresponding neural + representation. + Args: + words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay] + feats: List[torch.Tensor] + lens: List[int] + + Returns: x, qloss + x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + qloss: torch.FloatTensor ~ 1 + + """ + + x = super().encode(words, feats) + s_tag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :]) + + # adjust lengths to allow delay predictions + # x ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + if self.args.delay != 0: + x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay + 1)], dim=2) + x = self.delay_proj(x) + + # pass through vector quantization + x, qloss = self.vq_forward(x) + return x, s_tag, qloss + + + def forward( + self, + words: torch.LongTensor, + feats: List[torch.LongTensor] + ) -> Tuple[torch.Tensor]: + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor: + Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input. + """ + x, s_tag, qloss = self.encoder_forward(words, feats) + + return x, s_tag, qloss + + def loss( + self, + x: torch.Tensor, + nodes: torch.LongTensor, + parents: torch.LongTensor, + news: torch.LongTensor, + mask: torch.BoolTensor, s_tags: torch.LongTensor, tags: torch.LongTensor + ) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + nodes (~torch.LongTensor): ``[batch_size, seq_len]``. + The target node positions on rightmost chains. + parents (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of terminals. + news (~torch.LongTensor): ``[batch_size, seq_len]``. + The parent node labels of juxtaposed targets and terminals. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor: + The training loss. + """ + + spans, s_node, x_node = None, [], [] + actions = torch.stack((nodes, parents, news)) + for t, action in enumerate(actions.unbind(-1)): + if t == 0: + x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1) + s_node.append(self.node_classifier(x_rightmost).squeeze(-1)) + # we found softmax is slightly better than sigmoid in the original paper + s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0) + x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1)) + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index) + s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1) + s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1) + #s_postag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :]).chunk(2, -1) + s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1) + s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1) + node_loss = self.criterion(s_node[mask], nodes[mask]) + #print('node loss', node_loss) + label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask]) + #print('label loss', label_loss) + + #print(s_tag[mask].shape, tags[mask].shape) + tag_loss = self.criterion(s_tags[mask], tags[mask]) + #print('tag loss', tag_loss) + #tag_loss = self.pos_loss(s_tags, tags, mask) + #print("node loss, label loss, tag loss", node_loss, label_loss, tag_loss, node_loss + label_loss + tag_loss) + return node_loss + label_loss + tag_loss + + def decode( + self, + x: torch.Tensor, + mask: torch.BoolTensor, + beam_size: int = 1 + ) -> List[List[Tuple]]: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, n_model]``. + Contextualized output hidden states. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + beam_size (int): + Beam size for decoding. Default: 1. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + tokenwise_predictions = [] + spans = None + batch_size, *_ = x.shape + n_labels = self.args.n_labels + # [batch_size * beam_size, ...] + x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:]) + mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:]) + # [batch_size] + batches = x.new_tensor(range(batch_size)).long() * beam_size + # accumulated scores + scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1) + for t in range(x.shape[1]): + if t == 0: + x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels)) + span_mask = mask[:, :1] + else: + x_span = self.rightmost_chain(x, spans, mask, t) + span_lens = spans[:, :-1, -1].ge(0).sum(-1) + span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1) + s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1) + # we found softmax is slightly better than sigmoid in the original paper + x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1) + s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1) + s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1) + if t == 0: + s_parent[:, self.args.nul_index] = -INF + s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF + s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1) + s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1) + s_new, news = s_new.topk(min(n_labels, beam_size), -1) + s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1) + s_action = s_action.view(x.shape[0], -1) + k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1] + # [batch_size * beam_size, k_beam] + scores = scores.unsqueeze(-1) + s_action + # [batch_size, beam_size] + scores, cands = scores.view(batch_size, -1).topk(beam_size, -1) + # [batch_size * beam_size] + scores = scores.view(-1) + beams = cands.div(k_beam, rounding_mode='floor') + nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor')) + indices = (batches.unsqueeze(-1) + beams).view(-1) + + #print('indices', indices) + parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent) + news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent) + action = torch.stack((nodes, parents, news)).view(3, -1) + tokenwise_predictions.append([t, [x[0] for x in action.tolist()]]) + spans = spans[indices] if spans is not None else None + spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t]) + #print("SPANS", spans) + mask = mask.view(batch_size, beam_size, -1)[:, 0] + # select an 1-best tree for each sentence + spans = spans[batches + scores.view(batch_size, -1).argmax(-1)] + span_mask = spans.ge(0) + span_indices = torch.where(span_mask) + span_labels = spans[span_indices] + chart_preds = [[] for _ in range(x.shape[0])] + for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()): + chart_preds[i].append(span) + kk = [chart_preds + tokenwise_predictions] + return kk + + def rightmost_chain( + self, + x: torch.Tensor, + spans: torch.LongTensor, + mask: torch.BoolTensor, + t: int + ) -> torch.Tensor: + x_p, mask_p = x[:, :t], mask[:, :t] + lens = mask_p.sum(-1) + span_mask = spans[:, :-1, 1:].ge(0) + span_lens = span_mask.sum((-1, -2)) + span_indices = torch.where(span_mask) + span_labels = spans[:, :-1, 1:][span_indices] + x_span = self.label_embed(span_labels) + x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]] + node_lens = lens + span_lens + adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max()))) + x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1]))) + span_mask = ~x_mask & adj_mask + # concatenate terminals and spans + x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p]) + x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span) + adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1]) + adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1) + adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:])) + adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0] + adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2)) + # set the parent of root as itself + adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1)) + adj_parent = adj_parent & span_mask.unsqueeze(1) + # closet ancestor spans as parents + adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1) + adj.scatter_(-1, adj_parent.unsqueeze(-1), 1) + adj = (adj | adj.transpose(-1, -2)).float() + x_tree = self.gnn_layers(x_tree, adj, adj_mask) + span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1)) + span_lens = span_mask.sum(-1) + x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max()))) + x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree) + return x_span + + + def pos_loss(self, pos_logits: torch.Tensor, pos_tags: torch.LongTensor, mask: torch.BoolTensor) -> torch.Tensor: + """ + Args: + pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags]. + pos_tags (~torch.LongTensor): [batch_size, seq_len]. + mask (~torch.BoolTensor): [batch_size, seq_len]. + + Returns: + torch.Tensor: The POS tagging loss. + """ + loss_fn = nn.CrossEntropyLoss() + return loss_fn(pos_logits[mask], pos_tags[mask]) + + def decode_pos(self, s_tag: torch.Tensor): + """ + Decode the most likely POS tags. + + Args: + pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags] + mask (~torch.BoolTensor): [batch_size, seq_len] + + Returns: + List[List[int]]: POS tags per token for each sentence in the batch. + """ + pos_preds = pos_logits.argmax(-1) + #return [seq[mask[i]].tolist() for i, seq in enumerate(pos_preds)] + return pos_preds diff --git a/tania_scripts/supar/models/const/aj/parser.py b/tania_scripts/supar/models/const/aj/parser.py new file mode 100644 index 0000000..543e828 --- /dev/null +++ b/tania_scripts/supar/models/const/aj/parser.py @@ -0,0 +1,534 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Dict, Iterable, Set, Union + +import torch + +from supar.models.const.aj.model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos +from supar.models.const.aj.transform import AttachJuxtaposeTree +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, EOS, NUL, PAD, UNK +from supar.utils.field import Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import SpanMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch +from torch.nn.utils.rnn import pad_sequence + + +logger = get_logger(__name__) + + +def compute_pos_accuracy(pos_gold, pos_preds): + correct = 0 + total = 0 + for gold_seq, pred_seq in zip(pos_gold, pos_preds): + for g, p in zip(gold_seq, pred_seq): + if g == p: + correct += 1 + total += len(gold_seq) + return correct, total + + + + +class AttachJuxtaposeConstituencyParser(Parser): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + """ + + NAME = 'attach-juxtapose-constituency' + MODEL = AttachJuxtaposeConstituencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TREE = self.transform.TREE + self.NODE = self.transform.NODE + self.PARENT = self.transform.PARENT + self.NEW = self.transform.NEW + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + print("here") + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + verbose: bool = True, + **kwargs + ): + + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + #print("TRAIN STEP") + words, *feats, trees, nodes, parents, news = batch + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + #print("s_tag", s_tag) + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + #print("EVAL STEP") + words, *feats, trees, nodes, parents, news = batch + #print("WORDS", words.shape, words) + mask = batch.mask[:, (2+self.args.delay):] + x, qloss = self.model(words, feats) + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #print("CHART PREDS") + #print("self new vocab", self.NEW.vocab.items()) + #print() + preds = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds)] + + for tree, chart in zip(trees, chart_preds): + print(tree, chart) + + print() + for tree in trees: + print("ORIG TREE", tree) + print() + for tree in preds: + print("PRED TREE", tree) + + print("=========================") + + return SpanMetric(loss, + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees]) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask = batch.mask[:, (2+self.args.delay):] + x, _ = self.model(words, feats) + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + chart_preds = chart_preds[0] + batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds)] + if self.args.prob: + raise NotImplementedError("Returning action probs are currently not supported yet.") + + new_tokenwise_preds = [] + for k, y in chart_preds[1:]: + new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]]) + + chart_preds = [[[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]]] + new_tokenwise_preds + #for x in chart_preds[1:]: + # new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]] + + return chart_preds #batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR = None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay) + TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + TREE = RawField('trees') + NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK) + transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if CHAR is not None: + CHAR.build(train) + TAG.build(train) + PARENT, NEW = PARENT.build(train), NEW.build(train) + PARENT.vocab = NEW.vocab.update(PARENT.vocab) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(NEW.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'eos_index': WORD.eos_index, + 'nul_index': NEW.vocab[NUL] + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser + +def flatten(x): + result = [] + for el in x: + if isinstance(el, list): + result.extend(flatten(el)) + else: + result.append(el) + return result + + + + +class AttachJuxtaposeConstituencyParserPos(Parser): + r""" + The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`. + """ + + NAME = 'attach-juxtapose-constituency' + MODEL = AttachJuxtaposeConstituencyModelPos + + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TREE = self.transform.TREE + self.NODE = self.transform.NODE + self.PARENT = self.transform.PARENT + self.NEW = self.transform.NEW + self.TAG = self.transform.POS + + #print(self.TAG) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + beam_size: int = 1, + verbose: bool = True, + **kwargs + ): + + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + #print("TRAIN STEP") + words, *feats, postags, nodes, parents, news = batch + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + tags = feats[-1] + #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits + #loss = loss.mean() + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss + + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + + #print("EVAL STEP") + words, *feats, trees, nodes, parents, news = batch + + tags = feats[-1] + #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits + #loss = loss.mean() + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #print('CHART PREDS', chart_preds[0]) + + pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)] + trimmed_tags = [tag_seq[1:-1] for tag_seq in tags] + trimmed_tags_list = [x.cpu().tolist() for x in trimmed_tags] + pos_gold = [[self.TAG.vocab[p] for p in sent] for sent in trimmed_tags_list] + + pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds) + pos_acc = pos_correct/pos_total + print(pos_acc) + + """ + tags = [*feats[-1:]] + trimmed_tags = [tag_seq[1:-1] for tag_seq in tags[0]] + gtags = [*feats[-1:]][0].cpu().tolist() + gtags = [x[1:-1] for x in gtags] + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + + tag_tensor = pad_sequence(trimmed_tags, batch_first=True, padding_value=self.TAG.pad_index).to(s_tag.device) + + assert s_tag.shape[:2] == tag_tensor.shape[:2] + print("s_tag shape", s_tag.shape[:2], "tag_tensor shape", tag_tensor.shape[:2]) + + + loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tag_tensor) + qloss + + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)] + + for tag_seq in gtags: + for pos in tag_seq: + assert 0 <= pos < len(self.TAG.vocab) + + pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)] + pos_gold = [[self.TAG.vocab[pos] for pos in tag_seq] for tag_seq in gtags] + + #print("357!", len(pos_gold), len(pos_preds)) + pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds) + print("358!", pos_correct, pos_total, pos_correct/pos_total) + + + #print('%%% POS preds', pos_preds) + #print('%%%% POS gold', pos_gold) + """ + + #batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + # for tree, chart in zip(trees, chart_preds)] + #print(batch.trees) + + preds = [AttachJuxtaposeTree.build(tree, [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds[0])] + #print('POS preds', s_tag.argmax(-1)) + #print("PREDS", len(preds)) + + + """ + span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0][0]] + #print("new SPAN preds", span_preds) + verbalized_preds = [] + + + for x in chart_preds[1:]: + new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]] + #print(new_item) + verbalized_preds.append(new_item) + """ + + print("424", loss, pos_acc) + return SpanMetric(loss, + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees], pos_acc) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask = batch.mask[:, (2+self.args.delay):] + x, s_tag, qloss = self.model(words, feats) + chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size) + #print('VHART PREDS: ', chart_preds) + #print('LEN VHART PREDS: ', len(chart_preds)) + + chart_preds = chart_preds[0] + batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL}) + for tree, chart in zip(trees, chart_preds)] + if self.args.prob: + raise NotImplementedError("Returning action probs are currently not supported yet.") + + new_tokenwise_preds = [] + #for pred in chart_preds: + # print("PRED", pred) + # new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]]) + + + span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]] + new_tokenwise_preds + #print("new chart preds", span_preds) + verbalized_preds = [] + for x in chart_preds[1:]: + new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]] + #print(new_item) + verbalized_preds.append(new_item) + #print('POS preds', s_tag.argmax(-1)) + pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)] + return span_preds, verbalized_preds, pos_preds #batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR = None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay) + TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + TREE = RawField('trees') + NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK) + transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if CHAR is not None: + CHAR.build(train) + TAG.build(train) + #print("203 TAG VOCAB", [x for x in TAG.vocab.items()]) + PARENT, NEW = PARENT.build(train), NEW.build(train) + PARENT.vocab = NEW.vocab.update(PARENT.vocab) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(NEW.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'eos_index': WORD.eos_index, + 'nul_index': NEW.vocab[NUL] + }) + logger.info(f"{transform}") + + #print('TAG VOCAB', TAG.vocab.items()) + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser \ No newline at end of file diff --git a/tania_scripts/supar/models/const/aj/transform.py b/tania_scripts/supar/models/const/aj/transform.py new file mode 100644 index 0000000..56e0f51 --- /dev/null +++ b/tania_scripts/supar/models/const/aj/transform.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union + +import nltk +import torch + +from supar.models.const.crf.transform import Tree +from supar.utils.common import NUL +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class AttachJuxtaposeTree(Tree): + r""" + :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class, + supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`. + + Attributes: + WORD: + Words in the sentence. + POS: + Part-of-speech tags, or underscores if not available. + TREE: + The raw constituency tree in :class:`nltk.tree.Tree` format. + NODE: + The target node on each rightmost chain. + PARENT: + The label of the parent node of each terminal. + NEW: + The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children. + ``NUL`` represents the `Attach` action. + """ + + fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW'] + + def __init__( + self, + WORD: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + TREE: Optional[Union[Field, Iterable[Field]]] = None, + NODE: Optional[Union[Field, Iterable[Field]]] = None, + PARENT: Optional[Union[Field, Iterable[Field]]] = None, + NEW: Optional[Union[Field, Iterable[Field]]] = None + ) -> Tree: + super().__init__() + + self.WORD = WORD + self.POS = POS + self.TREE = TREE + self.NODE = NODE + self.PARENT = PARENT + self.NEW = NEW + + @property + def src(self): + return self.WORD, self.POS, self.TREE + + @property + def tgt(self): + return self.NODE, self.PARENT, self.NEW + + @classmethod + def tree2action(cls, tree: nltk.Tree): + r""" + Converts a constituency tree into AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + A constituency tree in :class:`nltk.tree.Tree` format. + + Returns: + A sequence of AttachJuxtapose actions. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ Arthur)) + (VP + (_ is) + (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons))))) + (_ .))) + ''') + >>> tree.pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + >>> AttachJuxtaposeTree.tree2action(tree) + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')] + """ + + def isroot(node): + return node == tree[0] + + def isterminal(node): + return len(node) == 1 and not isinstance(node[0], nltk.Tree) + + def last_leaf(node): + pos = () + while True: + pos += (len(node) - 1,) + node = node[-1] + if isterminal(node): + return node, pos + + def parent(position): + return tree[position[:-1]] + + def grand(position): + return tree[position[:-2]] + + def detach(tree): + last, last_pos = last_leaf(tree) + siblings = parent(last_pos)[:-1] + + if len(siblings) > 0: + last_subtree = last + last_subtree_siblings = siblings + parent_label = NUL + else: + last_subtree, last_pos = parent(last_pos), last_pos[:-1] + last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1] + parent_label = last_subtree.label() + + target_pos, new_label, last_tree = 0, NUL, tree + if isroot(last_subtree): + last_tree = None + + elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]): + new_label = parent(last_pos).label() + new_label = new_label + target = last_subtree_siblings[0] + last_grand = grand(last_pos) + if last_grand is None: + last_tree = targetistermina + else: + last_grand[-1] = target + target_pos = len(last_pos) - 2 + else: + target = parent(last_pos) + target.pop() + target_pos = len(last_pos) - 2 + action = target_pos, parent_label, new_label + return action, last_tree + if tree is None: + return [] + action, last_tree = detach(tree) + return cls.tree2action(last_tree) + [action] + + @classmethod + def action2tree( + cls, + tree: nltk.Tree, + actions: List[Tuple[int, str, str]], + join: str = '::', + ) -> nltk.Tree: + r""" + Recovers a constituency tree from a sequence of AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + An empty tree that provides a base for building a result tree. + actions (List[Tuple[int, str, str]]): + A sequence of AttachJuxtapose actions. + join (str): + A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains. + Default: ``'::'``. + + Returns: + A result constituency tree. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.action2tree(tree, + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')]).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + """ + + def target(node, depth): + node_pos = () + for _ in range(depth): + node_pos += (len(node) - 1,) + node = node[-1] + return node, node_pos + + def parent(tree, position): + return tree[position[:-1]] + + def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree: + target_pos, parent_label, new_label, post = action + #print(target_pos, parent_label, new_label) + new_leaf = nltk.Tree(post, [terminal[0]]) + + # create the subtree to be inserted + new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf]) + # find the target position at which to insert the new subtree + target_node = tree + if target_node is not None: + target_node, target_pos = target(target_node, target_pos) + + # Attach + if new_label == NUL: + # attach the first token + if target_node is None: + return new_subtree + target_node.append(new_subtree) + # Juxtapose + else: + new_subtree = nltk.Tree(new_label, [target_node, new_subtree]) + if len(target_pos) > 0: + parent_node = parent(tree, target_pos) + parent_node[-1] = new_subtree + else: + tree = new_subtree + return tree + + tree, root, terminals = None, tree.label(), tree.pos() + for terminal, action in zip(terminals, actions): + tree = execute(tree, terminal, action) + # recover unary chains + nodes = [tree] + while nodes: + node = nodes.pop() + if isinstance(node, nltk.Tree): + nodes.extend(node) + if join in node.label(): + labels = node.label().split(join) + node.set_label(labels[0]) + subtree = nltk.Tree(labels[-1], node) + for label in reversed(labels[1:-1]): + subtree = nltk.Tree(label, [subtree]) + node[:] = [subtree] + return nltk.Tree(root, [tree]) + + @classmethod + def action2span( + cls, + action: torch.Tensor, + spans: torch.Tensor = None, + nul_index: int = -1, + mask: torch.BoolTensor = None + ) -> torch.Tensor: + r""" + Converts a batch of the tensorized action at a given step into spans. + + Args: + action (~torch.Tensor): ``[3, batch_size]``. + A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels. + spans (~torch.Tensor): + Spans generated at previous steps, ``None`` at the first step. Default: ``None``. + nul_index (int): + The index for the obj:`NUL` token, representing the Attach action. Default: -1. + mask (~torch.BoolTensor): ``[batch_size]``. + The mask for covering the unpadded tokens. + + Returns: + A tensor representing a batch of spans for the given step. + + Examples: + >>> from collections import Counter + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab + >>> from supar.utils.common import NUL + >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL), + (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL), + (0, NUL, NUL)]) + >>> vocab = Vocab(Counter(sorted(set([*parents, *news])))) + >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1) + >>> spans = None + >>> for action in actions.unbind(-1): + ... spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL]) + ... + >>> spans + tensor([[[-1, 1, -1, -1, -1, -1, -1, 3], + [-1, -1, -1, -1, -1, -1, 4, -1], + [-1, -1, -1, 1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, 2, -1], + [-1, -1, -1, -1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1]]]) + >>> sequence = torch.where(spans.ge(0)) + >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]])) + >>> sequence + [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')] + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + + """ + + # [batch_size] + target, parent, new = action + if spans is None: + spans = action.new_full((action.shape[1], 2, 2), -1) + spans[:, 0, 1] = parent + return spans + if mask is None: + mask = torch.ones_like(target, dtype=bool) + juxtapose_mask = new.ne(nul_index) & mask + # ancestor nodes are those on the rightmost chain and higher than the target node + # [batch_size, seq_len] + rightmost_mask = spans[..., -1].ge(0) + ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1 + # should not include the target node for the Juxtapose action + ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1)) + target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1] + # the right boundaries of ancestor nodes should be aligned with the new generated terminals + spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1) + spans[..., -2].masked_fill_(ancestor_mask, -1) + spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask] + spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask] + # [batch_size, seq_len+1, seq_len+1] + spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1) + return spans + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ) -> List[AttachJuxtaposeTreeSentence]: + r""" + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + + Returns: + A list of :class:`AttachJuxtaposeTreeSentence` instances. + """ + + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + if data.endswith('.txt'): + data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1) + else: + data = open(data) + else: + if lang is not None: + data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + + index = 0 + for s in data: + + try: + tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root) + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + except ValueError: + logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!") + continue + except IndexError: + tree = nltk.Tree.fromstring('(S ' + s + ')') + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + else: + yield sentence + index += 1 + self.root = tree.label() + + +class AttachJuxtaposeTreeSentence(Sentence): + r""" + Args: + transform (AttachJuxtaposeTree): + A :class:`AttachJuxtaposeTree` object. + tree (nltk.tree.Tree): + A :class:`nltk.tree.Tree` object. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + """ + + def __init__( + self, + transform: AttachJuxtaposeTree, + tree: nltk.Tree, + index: Optional[int] = None + ) -> AttachJuxtaposeTreeSentence: + super().__init__(transform, index) + + words, tags = zip(*tree.pos()) + nodes, parents, news = None, None, None + if transform.training: + oracle_tree = tree.copy(True) + # the root node must have a unary chain + if len(oracle_tree) > 1: + oracle_tree[:] = [nltk.Tree('*', oracle_tree)] + oracle_tree.collapse_unary(joinChar='::') + if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree): + oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]]) + nodes, parents, news = zip(*transform.tree2action(oracle_tree)) + tags = [x.split("##")[0] for x in tags] + self.values = [words, tags, tree, nodes, parents, news] + + def __repr__(self): + return self.values[-4].pformat(1000000) + + def pretty_print(self): + self.values[-4].pretty_print() diff --git a/tania_scripts/supar/models/const/crf/__init__.py b/tania_scripts/supar/models/const/crf/__init__.py new file mode 100644 index 0000000..b3a1e58 --- /dev/null +++ b/tania_scripts/supar/models/const/crf/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import CRFConstituencyModel +from .parser import CRFConstituencyParser + +__all__ = ['CRFConstituencyModel', 'CRFConstituencyParser'] diff --git a/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b23ae21ab8db14bfbcb97e155b4203d8c61d82a GIT binary patch literal 287 zcmd1j<>g{vU|`_PGe}>-z`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$ zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9WBF;f>&iQ%8C7C6qsd>qjzWFJsIhu^O zMA5_p5{rsci;6%t6)`g~F!*V*-eS!KDF%z(Vk>|s0Lk5AkB?8x$%&6&$xy`3zyKkB z+3RQI=cekHB$i|*<|XPS<s_zLrWWaE<|P*-7U>t4f=IA|#rnx02k9plrRm4VXXa&= h#K-FuRNmsS$<0qG%}KQbIlY*Tfq{XCiHDJg2>_fANj?Ao literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ebb3eb81e33d0ac6cbfe3c6b1f467617348d959 GIT binary patch literal 365 zcmZ3^%ge>Uz`&q%Uo~R|0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w?v$S+?@0Cic2y}N>lTaD}D1*QgbvJZ;7Ib z2P761rxq14GcYg|u`n<&_-V4<V$B6928-QdD}X2f$=za)k5A0WiH~2&@EPQ`Ut#(g z`MIh3C5a`OiFt{7NjZrrnW;tk$@#ej`MM>k6(zc<Wr;cZC5d^NiSfnBMVSR9#rnmi z1&KxaU@MCClR-|@PcBN+kB`sH%PfhH*DI*}#bJ}1pHiBWYFEU~z`y|VQLz;R1H%Vq pMn=XDYz&MV7Z}u$(G3R83#jM;x8en5s|#G#4eTIT#L2+G007|NX2Jjf literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d01854d3d9e7b162c4bbd2903109ba1d1b0384a1 GIT binary patch literal 9776 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ba33210adee6c2b20457972f93ac9ce0b2e68e0 GIT binary patch literal 12210 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 IY!ujM02sh72><{9 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7e69785c24d5aba0b6e9363ddd28806b9f04cfa GIT binary patch literal 8295 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7282c0aa3c3e6e0aa427723393109f9b057bba50 GIT binary patch literal 15580 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fec7bc1c3fc13a4209bb5c3f1be993b016f7cd7a GIT binary patch literal 19620 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 WhlvNYOoWMtk%LKqnV}v8MQj0r*q0Xo literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..284c610e9e875040233cc1a2d0138345a2c0e4ae GIT binary patch literal 26740 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/crf/model.py b/tania_scripts/supar/models/const/crf/model.py new file mode 100644 index 0000000..03199e8 --- /dev/null +++ b/tania_scripts/supar/models/const/crf/model.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.model import Model +from supar.modules import MLP, Biaffine +from supar.structs import ConstituencyCRF +from supar.utils import Config + + +class CRFConstituencyModel(Model): + r""" + The implementation of CRF Constituency Parser :cite:`zhang-etal-2020-fast`, + also called FANCY (abbr. of Fast and Accurate Neural Crf constituencY) Parser. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_span_mlp (int): + Span MLP size. Default: 500. + n_label_mlp (int): + Label MLP size. Default: 100. + mlp_dropout (float): + The dropout ratio of MLP layers. Default: .33. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_span_mlp=500, + n_label_mlp=100, + mlp_dropout=.33, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.span_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout) + self.span_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout) + self.label_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout) + self.label_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout) + + self.span_attn = Biaffine(n_in=n_span_mlp, bias_x=True, bias_y=False) + self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True) + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first tensor of shape ``[batch_size, seq_len, seq_len]`` holds scores of all possible constituents. + The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds + scores of all possible labels on each constituent. + """ + + x = self.encode(words, feats) + + x_f, x_b = x.chunk(2, -1) + x = torch.cat((x_f[:, :-1], x_b[:, 1:]), -1) + + span_l = self.span_mlp_l(x) + span_r = self.span_mlp_r(x) + label_l = self.label_mlp_l(x) + label_r = self.label_mlp_r(x) + + # [batch_size, seq_len, seq_len] + s_span = self.span_attn(span_l, span_r) + # [batch_size, seq_len, seq_len, n_labels] + s_label = self.label_attn(label_l, label_r).permute(0, 2, 3, 1) + + return s_span, s_label + + def loss(self, s_span, s_label, charts, mask, mbr=True): + r""" + Args: + s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all constituents. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all constituent labels. + charts (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + The tensor of gold-standard labels. Positions without labels are filled with -1. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask for covering the unpadded tokens in each chart. + mbr (bool): + If ``True``, returns marginals for MBR decoding. Default: ``True``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The training loss and original constituent scores + of shape ``[batch_size, seq_len, seq_len]`` if ``mbr=False``, or marginals otherwise. + """ + + span_mask = charts.ge(0) & mask + span_dist = ConstituencyCRF(s_span, mask[:, 0].sum(-1)) + span_loss = -span_dist.log_prob(charts).sum() / mask[:, 0].sum() + span_probs = span_dist.marginals if mbr else s_span + label_loss = self.criterion(s_label[span_mask], charts[span_mask]) + loss = span_loss + label_loss + + return loss, span_probs + + def decode(self, s_span, s_label, mask): + r""" + Args: + s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all constituents. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all constituent labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + + span_preds = ConstituencyCRF(s_span, mask[:, 0].sum(-1)).argmax + label_preds = s_label.argmax(-1).tolist() + return [[(i, j, labels[i][j]) for i, j in spans] for spans, labels in zip(span_preds, label_preds)] diff --git a/tania_scripts/supar/models/const/crf/parser.py b/tania_scripts/supar/models/const/crf/parser.py new file mode 100644 index 0000000..ad5bd16 --- /dev/null +++ b/tania_scripts/supar/models/const/crf/parser.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Dict, Iterable, Set, Union + +import torch + +from supar.models.const.crf.model import CRFConstituencyModel +from supar.models.const.crf.transform import Tree +from supar.parser import Parser +from supar.structs import ConstituencyCRF +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, EOS, PAD, UNK +from supar.utils.field import ChartField, Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import SpanMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class CRFConstituencyParser(Parser): + r""" + The implementation of CRF Constituency Parser :cite:`zhang-etal-2020-fast`. + """ + + NAME = 'crf-constituency' + MODEL = CRFConstituencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TREE = self.transform.TREE + self.CHART = self.transform.CHART + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + mbr: bool = True, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + mbr: bool = True, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + mbr: bool = True, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, *feats, _, charts = batch + mask = batch.mask[:, 1:] + mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1) + s_span, s_label = self.model(words, feats) + loss, _ = self.model.loss(s_span, s_label, charts, mask, self.args.mbr) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + words, *feats, trees, charts = batch + mask = batch.mask[:, 1:] + mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1) + s_span, s_label = self.model(words, feats) + loss, s_span = self.model.loss(s_span, s_label, charts, mask, self.args.mbr) + chart_preds = self.model.decode(s_span, s_label, mask) + preds = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart]) + for tree, chart in zip(trees, chart_preds)] + return SpanMetric(loss, + [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in trees]) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask, lens = batch.mask[:, 1:], batch.lens - 2 + mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1) + s_span, s_label = self.model(words, feats) + s_span = ConstituencyCRF(s_span, mask[:, 0].sum(-1)).marginals if self.args.mbr else s_span + chart_preds = self.model.decode(s_span, s_label, mask) + batch.trees = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart]) + for tree, chart in zip(trees, chart_preds)] + if self.args.prob: + batch.probs = [prob[:i-1, 1:i].cpu() for i, prob in zip(lens, s_span)] + return batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR, ELMO, BERT = None, None, None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True) + if 'tag' in args.feat: + TAG = Field('tags', bos=BOS, eos=EOS) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len) + if 'elmo' in args.feat: + from allennlp.modules.elmo import batch_to_ids + ELMO = RawField('elmo') + ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device) + if 'bert' in args.feat: + t = TransformerTokenizer(args.bert) + BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t) + BERT.vocab = t.vocab + TREE = RawField('trees') + CHART = ChartField('charts') + transform = Tree(WORD=(WORD, CHAR, ELMO, BERT), POS=TAG, TREE=TREE, CHART=CHART) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if TAG is not None: + TAG.build(train) + if CHAR is not None: + CHAR.build(train) + CHART.build(train) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(CHART.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'bert_pad_index': BERT.pad_index if BERT is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'eos_index': WORD.eos_index + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/const/crf/transform.py b/tania_scripts/supar/models/const/crf/transform.py new file mode 100644 index 0000000..b3ba03c --- /dev/null +++ b/tania_scripts/supar/models/const/crf/transform.py @@ -0,0 +1,494 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import (TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple, + Union) + +import nltk + +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence, Transform + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class Tree(Transform): + r""" + A :class:`Tree` object factorize a constituency tree into four fields, + each associated with one or more :class:`~supar.utils.field.Field` objects. + + Attributes: + WORD: + Words in the sentence. + POS: + Part-of-speech tags, or underscores if not available. + TREE: + The raw constituency tree in :class:`nltk.tree.Tree` format. + CHART: + The factorized sequence of binarized tree traversed in post-order. + """ + + root = '' + fields = ['WORD', 'POS', 'TREE', 'CHART'] + + def __init__( + self, + WORD: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + TREE: Optional[Union[Field, Iterable[Field]]] = None, + CHART: Optional[Union[Field, Iterable[Field]]] = None + ) -> Tree: + super().__init__() + + self.WORD = WORD + self.POS = POS + self.TREE = TREE + self.CHART = CHART + + @property + def src(self): + return self.WORD, self.POS, self.TREE + + @property + def tgt(self): + return self.CHART, + + @classmethod + def totree( + cls, + tokens: List[Union[str, Tuple]], + root: str = '', + normalize: Dict[str, str] = {'(': '-LRB-', ')': '-RRB-'} + ) -> nltk.Tree: + r""" + Converts a list of tokens to a :class:`nltk.tree.Tree`, with missing fields filled in with underscores. + + Args: + tokens (List[Union[str, Tuple]]): + This can be either a list of words or word/pos pairs. + root (str): + The root label of the tree. Default: ''. + normalize (Dict): + Keys within the dict in each token will be replaced by the values. Default: ``{'(': '-LRB-', ')': '-RRB-'}``. + + Returns: + A :class:`nltk.tree.Tree` object. + + Examples: + >>> from supar.models.const.crf.transform import Tree + >>> Tree.totree(['She', 'enjoys', 'playing', 'tennis', '.'], 'TOP').pprint() + (TOP ( (_ She)) ( (_ enjoys)) ( (_ playing)) ( (_ tennis)) ( (_ .))) + >>> Tree.totree(['(', 'If', 'You', 'Let', 'It', ')'], 'TOP').pprint() + (TOP + ( (_ -LRB-)) + ( (_ If)) + ( (_ You)) + ( (_ Let)) + ( (_ It)) + ( (_ -RRB-))) + """ + + normalize = str.maketrans(normalize) + if isinstance(tokens[0], str): + tokens = [(token, '_') for token in tokens] + return nltk.Tree(root, [nltk.Tree('', [nltk.Tree(pos, [word.translate(normalize)])]) for word, pos in tokens]) + + @classmethod + def binarize( + cls, + tree: nltk.Tree, + left: bool = True, + mark: str = '*', + join: str = '::', + implicit: bool = False + ) -> nltk.Tree: + r""" + Conducts binarization over the tree. + + First, the tree is transformed to satisfy `Chomsky Normal Form (CNF)`_. + Here we call :meth:`~nltk.tree.Tree.chomsky_normal_form` to conduct left-binarization. + Second, all unary productions in the tree are collapsed. + + Args: + tree (nltk.tree.Tree): + The tree to be binarized. + left (bool): + If ``True``, left-binarization is conducted. Default: ``True``. + mark (str): + A string used to mark newly inserted nodes, working if performing explicit binarization. Default: ``'*'``. + join (str): + A string used to connect collapsed node labels. Default: ``'::'``. + implicit (bool): + If ``True``, performs implicit binarization. Default: ``False``. + + Returns: + The binarized tree. + + Examples: + >>> from supar.models.const.crf.transform import Tree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ She)) + (VP (_ enjoys) (S (VP (_ playing) (NP (_ tennis))))) + (_ .))) + ''') + >>> tree.pretty_print() + TOP + | + S + ____________|________________ + | VP | + | _______|_____ | + | | S | + | | | | + | | VP | + | | _____|____ | + NP | | NP | + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + >>> Tree.binarize(tree).pretty_print() + TOP + | + S + _____|__________________ + S* | + __________|_____ | + | VP | + | ___________|______ | + | | S::VP | + | | ______|_____ | + NP VP* VP* NP S* + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + >>> Tree.binarize(tree, implicit=True).pretty_print() + TOP + | + S + _____|__________________ + | + __________|_____ | + | VP | + | ___________|______ | + | | S::VP | + | | ______|_____ | + NP NP + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + >>> Tree.binarize(tree, left=False).pretty_print() + TOP + | + S + ____________|______ + | S* + | ______|___________ + | VP | + | _______|______ | + | | S::VP | + | | ______|_____ | + NP VP* VP* NP S* + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + .. _Chomsky Normal Form (CNF): + https://en.wikipedia.org/wiki/Chomsky_normal_form + """ + + tree = tree.copy(True) + nodes = [tree] + if len(tree) == 1: + if not isinstance(tree[0][0], nltk.Tree): + tree[0] = nltk.Tree(f'{tree.label()}{mark}', [tree[0]]) + nodes = [tree[0]] + while nodes: + node = nodes.pop() + if isinstance(node, nltk.Tree): + if implicit: + label = '' + else: + label = node.label() + if mark not in label: + label = f'{label}{mark}' + # ensure that only non-terminals can be attached to a n-ary subtree + if len(node) > 1: + for child in node: + if not isinstance(child[0], nltk.Tree): + child[:] = [nltk.Tree(child.label(), child[:])] + child.set_label(label) + # chomsky normal form factorization + if len(node) > 2: + if left: + node[:-1] = [nltk.Tree(label, node[:-1])] + else: + node[1:] = [nltk.Tree(label, node[1:])] + nodes.extend(node) + # collapse unary productions, shoule be conducted after binarization + tree.collapse_unary(joinChar=join) + return tree + + @classmethod + def factorize( + cls, + tree: nltk.Tree, + delete_labels: Optional[Set[str]] = None, + equal_labels: Optional[Dict[str, str]] = None + ) -> Iterable[Tuple]: + r""" + Factorizes the tree into a sequence traversed in post-order. + + Args: + tree (nltk.tree.Tree): + The tree to be factorized. + delete_labels (Optional[Set[str]]): + A set of labels to be ignored. This is used for evaluation. + If it is a pre-terminal label, delete the word along with the brackets. + If it is a non-terminal label, just delete the brackets (don't delete children). + In `EVALB`_, the default set is: + {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''} + Default: ``None``. + equal_labels (Optional[Dict[str, str]]): + The key-val pairs in the dict are considered equivalent (non-directional). This is used for evaluation. + The default dict defined in `EVALB`_ is: {'ADVP': 'PRT'} + Default: ``None``. + + Returns: + The sequence of the factorized tree. + + Examples: + >>> from supar.models.const.crf.transform import Tree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ She)) + (VP (_ enjoys) (S (VP (_ playing) (NP (_ tennis))))) + (_ .))) + ''') + >>> Tree.factorize(tree) + [(0, 1, 'NP'), (3, 4, 'NP'), (2, 4, 'VP'), (2, 4, 'S'), (1, 4, 'VP'), (0, 5, 'S'), (0, 5, 'TOP')] + >>> Tree.factorize(tree, delete_labels={'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}) + [(0, 1, 'NP'), (3, 4, 'NP'), (2, 4, 'VP'), (2, 4, 'S'), (1, 4, 'VP'), (0, 5, 'S')] + + .. _EVALB: + https://nlp.cs.nyu.edu/evalb/ + """ + + def track(tree, i): + label = tree if isinstance(tree, str) else tree.label() + if delete_labels is not None and label in delete_labels: + label = None + if equal_labels is not None: + label = equal_labels.get(label, label) + if len(tree) == 1 and not isinstance(tree[0], nltk.Tree): + return (i + 1 if label is not None else i), [] + j, spans = i, [] + for child in tree: + j, s = track(child, j) + spans += s + if label is not None and j > i: + spans = spans + [(i, j, label)] + return j, spans + return track(tree, 0)[1] + + @classmethod + def build( + cls, + sentence: Union[nltk.Tree, Iterable], + spans: Iterable[Tuple], + delete_labels: Optional[Set[str]] = None, + mark: Union[str, Tuple[str]] = ('*', '|<>'), + root: str = '', + join: str = '::', + postorder: bool = True + ) -> nltk.Tree: + r""" + Builds a constituency tree from a span sequence. + During building, the sequence is recovered, i.e., de-binarized to the original format. + + Args: + sentence (Union[nltk.tree.Tree, Iterable]): + Sentence to provide a base for building a result tree, both `nltk.tree.Tree` and tokens are allowed. + spans (Iterable[Tuple]): + A list of spans, each consisting of the indices of left/right boundaries and label of the constituent. + delete_labels (Optional[Set[str]]): + A set of labels to be ignored. Default: ``None``. + mark (Union[str, List[str]]): + A string used to mark newly inserted nodes. Non-terminals containing this will be removed. + Default: ``('*', '|<>')``. + root (str): + The root label of the tree, needed if input a list of tokens. Default: ''. + join (str): + A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains. + Default: ``'::'``. + postorder (bool): + If ``True``, enforces the sequence is sorted in post-order. Default: ``True``. + + Returns: + A result constituency tree. + + Examples: + >>> from supar.models.const.crf.transform import Tree + >>> Tree.build(['She', 'enjoys', 'playing', 'tennis', '.'], + [(0, 5, 'S'), (0, 4, 'S*'), (0, 1, 'NP'), (1, 4, 'VP'), (1, 2, 'VP*'), + (2, 4, 'S::VP'), (2, 3, 'VP*'), (3, 4, 'NP'), (4, 5, 'S*')], + root='TOP').pretty_print() + TOP + | + S + ____________|________________ + | VP | + | _______|_____ | + | | S | + | | | | + | | VP | + | | _____|____ | + NP | | NP | + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + >>> Tree.build(['She', 'enjoys', 'playing', 'tennis', '.'], + [(0, 1, 'NP'), (3, 4, 'NP'), (2, 4, 'VP'), (2, 4, 'S'), (1, 4, 'VP'), (0, 5, 'S')], + root='TOP').pretty_print() + TOP + | + S + ____________|________________ + | VP | + | _______|_____ | + | | S | + | | | | + | | VP | + | | _____|____ | + NP | | NP | + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + """ + + tree = sentence if isinstance(sentence, nltk.Tree) else Tree.totree(sentence, root) + leaves = [subtree for subtree in tree.subtrees() if not isinstance(subtree[0], nltk.Tree)] + if postorder: + spans = sorted(spans, key=lambda x: (x[1], x[1] - x[0])) + + root = tree.label() + start, stack = 0, [] + for span in spans: + i, j, label = span + if delete_labels is not None and label in delete_labels: + continue + stack.extend([(n, n + 1, leaf) for n, leaf in enumerate(leaves[start:i], start)]) + children = [] + while len(stack) > 0 and i <= stack[-1][0]: + children = [stack.pop()] + children + start = children[-1][1] if len(children) > 0 else i + children.extend([(n, n + 1, leaf) for n, leaf in enumerate(leaves[start:j], start)]) + start = j + if not label or label.endswith(mark): + stack.extend(children) + continue + labels = label.split(join) + tree = nltk.Tree(labels[-1], [child[-1] for child in children]) + for label in reversed(labels[:-1]): + tree = nltk.Tree(label, [tree]) + stack.append((i, j, tree)) + stack.extend([(n, n + 1, leaf) for n, leaf in enumerate(leaves[start:], start)]) + return nltk.Tree(root, [i[-1] for i in stack]) + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ) -> List[TreeSentence]: + r""" + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + + Returns: + A list of :class:`TreeSentence` instances. + """ + + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + if data.endswith('.txt'): + data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1) + else: + data = open(data) + else: + if lang is not None: + data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + + index = 0 + for s in data: + try: + tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root) + sentence = TreeSentence(self, tree, index, **kwargs) + except ValueError: + logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!") + continue + else: + yield sentence + index += 1 + self.root = tree.label() + + +class TreeSentence(Sentence): + r""" + Args: + transform (Tree): + A :class:`Tree` object. + tree (nltk.tree.Tree): + A :class:`nltk.tree.Tree` object. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + """ + + def __init__( + self, + transform: Tree, + tree: nltk.Tree, + index: Optional[int] = None, + **kwargs + ) -> TreeSentence: + super().__init__(transform, index) + + words, tags, chart = *zip(*tree.pos()), None + if transform.training: + chart = [[None] * (len(words) + 1) for _ in range(len(words) + 1)] + for i, j, label in Tree.factorize(Tree.binarize(tree, implicit=kwargs.get('implicit', False))[0]): + chart[i][j] = label + self.values = [words, tags, tree, chart] + + def __repr__(self): + return self.values[-2].pformat(1000000) + + def pretty_print(self): + self.values[-2].pretty_print() diff --git a/tania_scripts/supar/models/const/sl/__init__.py b/tania_scripts/supar/models/const/sl/__init__.py new file mode 100644 index 0000000..1b6b7bd --- /dev/null +++ b/tania_scripts/supar/models/const/sl/__init__.py @@ -0,0 +1,4 @@ +from .model import SLConstituentModel +from .parser import SLConstituentParser + +__all__ = ['SLConstituentModel', 'SLConstituentParser'] \ No newline at end of file diff --git a/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25ff091642789417721ecf105676e6aa0cec7ae7 GIT binary patch literal 282 zcmd1j<>g{vU|`_PGe~b^U|@I*;vi!t1_lNP1_p*=6$S=|6owSW9EM!RC`LvQn<<AW zmpO`=ks*aSg(aOSiY0|Lm_d{6B_jg^gC^rGp<o~9{Ji3l%#za7yb|C1l++we##_QD zq5+9T#i>O_AX|!<85kJ+G+A%4=7N-h#cr_`Koo%FZn4M5C+6hD$FF24VrO805Wnp7 zGxBp&^-B^<G86L>^^$TDQ!-PF^fU943lfX;i%UTy*uY}_WRPq0i*xkj<1_OzOXB18 e3My}L*yQG?l;)(`fm~h8#=yY9!@$GH!vp~Rsz-4E literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d46638efe8006ba326a4c8302ee488c3cbf8e14 GIT binary patch literal 358 zcmZ3^%ge>Uz`&q%Up1qRfq~&Mhy%k+P{wC91_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9 zGb2L^a|%m3Qxr=IYcPW*+e=0U1_n*WTSCD;&iQ%8C7C6qsd**7`6;P6nvA!EQA7h0 zi;7c=ikKM~7>ZaJ7#RFCS#PoCf|P>AZm|_W6oBMzvB$?J=H$f3uVnZPa@Vg={fzwF zRQ-~~lFY=sM7^Y(#FWg`BK_q2+=6`FlGKV4-PE$g9Q~5Syv)S-;^d;tf|6qW;?jb| zB7LwG#rnx0_vshs=*P!r=4F<|$LkeT{^GF7%}*)KNwq8DW?*0dd8XKcfq~%zGb1D8 i4F=T<sOScR`UO<<fLs28qS*y5^9FVhEaGHfU;qH~mSnL2 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f671041ff9274200b3afc20f09983fcd26145c5b GIT binary patch literal 3360 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 HDiLM?{Wf2! literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1dc15de997aec065667819a9092434d52331791f GIT binary patch literal 5671 zcmZ3^%ge>Uz`&q%Up3<!9|OZ<5C?`?p^VR23=9m@8B!Qh7;_k+AT(nxQxp>;h|QG4 zoXZl$0%kMku;#KwvE{Nyv4i<6IUKp1QJi2lYYtZ~cN8}x0~3QgLke39LkfE;%Q9vL zhSkhadl;g4QW%37G&x>^1pG7^Z?XF3r=;d+GTmbK^$EDe?UI_DpORYS6CC2J$#{#+ zIX^EgGhLJM7K=}2aY-^r6Aa5j8K1u}Ffg<;OlL@Ch+<4(h+;}%Okqr6N?}fCOkn{- z))bZ$wiNahjugfe&J?Z`?i98Zo)oqe-W0wR{uJI6ffSY$-W0YJwiLlM*%YBv=2R9* zsNoC@X-pjqX^bhtExb{zDRL<yscc#7Fv%3rRAyv8k}j4Mu@=@SjudfZ`4kBho+JuS z3WX<)%uC}+k!fLx;!KfkVTj`DV5ne>;tpoel)ohu?BkrDS6q@=Qkt4q0uD*PTP!)n zCAqg)k~0#EUZyZGFuXKkU|=X>Vqjpn#hqW2nVy-Km=kZBq{$TG_L7Bxfgv5{om(uq zsfl@R>GG|w19!+>wa-*wW?*;;in`1%j0_Af89_#{q@^a7BrC%7FfcH1FfcH1GcYiG zmSSRHn9A7B&@MZjfr+66q#UYj83O~uYABn5Aqy^(!jZ{P0!xDo3=F917J#gV>w+;# zIAJVw^~)F;7*@m0Uc%VN$jFew7{kQC(8&-Fx22OIo(*O~Cj%lfvq1g;OQbMmgF=g; zh`mF$gCUJ6g}H^JRw<7S%3}fXm>6o5P;|pxh3X1qn=$l&^Ciei3_aLg2nuD8a)uPv zY;f2VS(hNv90Q7bc)<!8Kz>K^Bf<o>Dh39IDpoXkgf7`N?5H`nlOdiDW@d>zjK#o^ zB>-ci#$G2wydX>_g&~+hlhaR=$<MC{<mqI1EJ4$cFev?$FfcGoWtxtXaypq1sU-^> zD<Ctmi`Foph=W52teUZtDGQX+K^%rPjLX;<7*@kWIG90`$xoB%7JEujenEa|$t|{& z)UwRvR87_*P@1{Ll30{pd`loNJ~a<qG{t9Rrlh3ifkaXug;jh`Vr6PkagjI!1H($@ zTkQFzCGjblxwp7;a|+^Nrm_^L=A;#a+@#RZ@GD3^BR@A)za+6FGchkwFDWN6B{Q{1 zKRG|QAYZp6wW35fwJb45za%j)Gcmq6xhS)sq*%YWv>>raKNnP97V9U2^1Xg>4ur2) zQ2C3)CMPjBDJ9XaN*A+O(2I}H%*!l^kJq!w$xlwqDYnytDK}wYU??_aU|{&sz_2v? zhJeTv&MN|1D_quiUeR$o!44DH;C+JS4EG0CW_7-g49x0$UqD0y!)H*SqQoaCWWn)i zM|6DFFmy7eFs@-*#=^j`8Xi-@44TY-A(||=Sn}dC^KP-`#pjon6p4XKA+E&alFYKi zlFa-(P39tyjv@(ADF@08MbaP-K|{I-lv0ZnKxv({P_YCVq6!U_<Qt-rQzEa3>Tf8& zA)&m11tS!SKm{VWj4cvkU|`T>E>Z?LM+HQH9K4c2Q|K0JacMzn(Jc;GR1|?i>K0pR zK}upt>Mb@%yxihT&d<%w&x?m9u3G|$dC958CHX}#5wK5hvBTs!^Wq^oif?h}#lsXA z-(pQk%}K0;gbgTIZgGJH;tPuMvu-iv<=ql+F3K-1cFij($}gz&$uBOx#hF}`S&~`= z3RIOMIZ!yW=f#)j7o`*z>4AKr4-#U_i!Vt`FTTZ|7Z0jpif^$)Ge!|8(m}$hxk;%h zw|Mg63yM-piV`#PAUsgT5f7IG>4oxmAtu2x79UuuATcFAGcP5z;ucG4PHz4!9uOIy zlwTa5nqPd2B`LM2<Q8vUJcx$ozgyh7nHBK-#siiq$j{Ho%uBz;2jRiZ<VefROD!qQ zO9h2lK~65rC1B^l%qRi}8&b}P<nvqnP!Ge@-QvuPPb^A~&&??SF^f`jK+Gag1LYQL zadKi#>Mc%$cQ{M)vY|d>%Pt2ME=9VaaOI4TPtHj!E{=~c1|^#W1v~&E*#Jr08lc22 zjVH^43iV<YMh1o-KYlbYd~ji8;FRoT?PTv^zrrDLfy49yhv{6inHF;_=G)J*Uu(9~ zVvWT`X_G6`CJ?y`9Ht-G7|a|PFLD@luw3Dgo)L0I*60Q|e~;xAZkYvam$=m~aI1Y_ zVixE7z<^0~xOcdJ;KCFKs|86h$g9mrUy!mS^NO0~MLDZ0a#mnlZYZcPU|+$qhVzPs z?L`H<D++cXVc8FC3_JoomOb_}5-)MfU*ML%E2p@iWJ%=}b;koCM<S2JUkH!5=o)cR zJ@STz4oI`p3GWZgjPj9;9~nU87ckl3(&PV?jX_H0iloj(NxdtQdL1l1d>wopeBhjX zixr&eZ?S^XY;iKEECCgBAPj2!f%u;fFoK$$?Hui#(-}G$7J%e1a1CP((=sLohSl(z ztBbRfGle0Ap%v6j1(9HO8Z#)VL9~NZAnLprW(I~@<}Qv}mQDsl{g(xD0a$qo6SO4| zjNC5D0@Yk#`3{Z_h7Qg&W>6cZ1e6fKqTpH|?j|JD7(uN9)Yga#TB|IDWeqEapBNT^ z!UbwJg6iZ%HLHuWlVJh8orO@xz<{n2)N1SEtYz(FSip&_4#q}T-^s85)Ubd_!)bJN zwd}QQHEcEPHLPjO!3>&ge&F&NTympSVj%B;%CpZwph}E+Izu``4MVJQEn_DOB>HL? zJDEC}LER>ZU5F^F;$mQ^0S9C&6GSa?^iE{zQ3+;P$>^ua1TM&n3_$e->n$cdgIkQ5 zx41zCMR96jd`@Z}qzGoLC<eu*f<i+BB*XvWvdIB;hVpX@?5gyz<omSzqVmL|6y%y7 zrak~vt2sbwwF^=?5OgAOhT)7r5M02xz<Pto7RfF07nL0j7+zF%xuD>Bpb!Kv$a-9n z_JnA-Ae95oCNDurNR#mvb4q5eCig8iNV#~6wKyZOAQj=eTdXDdMadbrn3EGrZm||6 z=B1|=8G?#DuCl^-sAG$?K^2S+C@i?Z{w@Lqd{Ho1SyEz2az=b{W>xAfE=UOtX0sON zfNCv{VrT_;i>nx3{}n}o%!>kf7nCj_1*U?6g9EtCyu}W+wn_?j_<4Xde*%RSsMvhK zBhc^N<voLSM(IT!)hj%z9gH`4csmk7aDw0jp$S400zt4NqsP00@dF!!zQLOGiyYb= zTob$(NP$aBq%uoDbP6XtEa8l+!4VfCW3NOeU5U)NkePKcGV5Y+_Lbo53sN~3rE;!F z<y<H#z93L?QK00CKuL$=4FQqq{FC?>FkTc;x+0*|;rKvUe7gN4`vry<g;lQzt9Ej9 zFm{-J;9yWtxh`*XN#1CK;YE4VEAplrO0JvxTr&4L5qQzu|BAW)1g#E^8~oxkq!xr; z;Mcmqp#_fJB2dS$C<7D&?64LFC!&49lABnZoeXNiKr#RW1E?7WDwsYm0S_kBFxIdl zinSVMWL_<EEn^K6vPcaJGOw1UmZ=7Jp~{R}0M)YLRLfMuf~J-ol>I@)TrfjX7%06l z7J*v8njDa12lsRlC~p^KgOX7WC=9qEVGs{abG)!{0CS5$MH;NSh9oc+kg_UqEU615 z0Zx|@3=9kn3?JASWK|c0%<)^{zQJXU?*#P@jvESED@?8^7;Mno;j%@4f@cTU4Kb<d zd6V)MM64*kC}w^|%)Ep9hJ?&~zFB+=sy0|&l(4-bVcWrbgI{V!>_tQbqSRZUhymfx zanQ)YUSp*&qL$dT%r#6zs${8Qu3<@I0{5q0{{R2~KWG3au_!$^u|ks-EpTtaLbISK zHRTo}G(lWwai^f500~MqNK3a$5=&r0q(I|B#h?<Uf#HUj-1PiO`3sURifLXE(*%W+ z(sc>VOA?wZlrBo>UXjp+gp=<De$5LUnvjGJP6j-nhIw9MZfbn|Ew1?Z-29Z%91xo) zKEALtF$W@3#12Xd%*7=|MWAL^Q38m|7LuA*oL^Lw2}&ykAfgN;%nNPMC8y@(#K&tg z76pO|6j09>QV11+DmE|y>XjE8ff{HH3^4eChe1;I1_;UDP}W?aaYIt(hMXc8Dcq1( zx}l(WLrnRGoc0YdsT=YNH)Q2+$f<w?rQ~nO%7GLpsoqdhzM-gcLs|}mWEF0ROWcr_ zxgjm{!I9CDRsRD6h~Q(8keT5;rSbzmhzAzJMwBrMuxfu`5Mb4w5jrOZ%-Eo^p>#{l z6(big51mk9XVtzTE;FU(12c$aXtqTL%z7XuJtgM@D?6+91AUV<H4v7w#}OMa>jMKj z$Qn2y#LTMofdL-@i9k?DYVty2g9BXI=;h@VfyTXVaf5r!df;Aj5hw%P;)RQp=A;%w zI!K@z7N)ecBr~TN+BYkyEXd4D2gf=%ri#=+(F^YEfjXAIIBX#4#IC4`fq?-Ox5eui z7#Kb<Gctne07l*h9uU02AbJ56-C&TtfQoJ~XkEaDZZODQKt(qg#4n(t4{Xtlj9MQU Tu#+=HKZ0exfJsbM;4lOL%9U$q literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d61fb3dc0394c8bb1146467f5c1b762d37cca0b GIT binary patch literal 8808 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdce8977c12fc63d881480ee1b0a5cde8a562fd9 GIT binary patch literal 18487 zcmZ3^%ge>Uz`&q%Uo}Hgg@NHQhy%l{P{wBiMh1rI3@HpLj5!QZAet$MF_$TdDVI5l zIhQ4hC6_gdl@TP)n8Oyu23E%&#h${D!kojA%NfN9mSf4`%H@vY2D4dncyf88cysxp z_;UH9_`zaqIRd$YQG&TbQ9`-GQNp<*Q6gY*_8ie%u_&=z@hI_Ji71I&$tX#%I7g0D zu5^?%n9Z3ZlPen~3ubfW$mPmM$%EP4ISRRoQHo$TPmWTqa+ETd&6}f=s~V*WX7lB! z<*G-i=W0Z0<Z4D~g2niAv~mTbv~z``bQl?!7*eHEb(b+RFsx>Th6qEH9utE*LyABP zLyBN3_cCS%hSkh)IsFvIU<OU0mmmQ@O_p0ME}6+Cw>UgYQi~Fka#C+G2d9?YVhzp9 z%+J$gyd@Ou<D8#YT#{K*nwnSQo1c=Jqse%SEg-R|IJHQV`4*dVeqLH;`Ym>s#FE6~ z)RJ4AuDMC6DJhwG>6$FJn4SECZ!x=qhyX{ITg;(;-kL18xSTT*i%Q%wQ*%;ou|g=0 zpu}<rizm1=sXV_Z1<ccAyv3ECS`wd=pPrst1mXo3B<A_1mK0?sYck#v2`Ng<D^ANV z%1tc_$<I#B%d7&c;ze<^CgUwur^J%v3{A#cEFndyshZ5U_(7&7=jX+z<|XH+q!!)c z^U2IhO)Sc+N=*SNxy9}r?~|C6nxn~7#KXYAP{hl?z>o|IG8mSGGCsdzWMF7#n9h*O z5XG3n5XF?j5XGFz62;oVkj9w8*uoLT#>s#VQ`A$qQrS~EQaRI@U<NTTq;O*q<G~`v zo642Km&%pGpURaYkjj-Jn97wRl**MNoXVXdlFFSTn#!Ff0k&VPg*S=^+4dBT6bURQ zf=t3@3Ln@M$rj!yUSv}s>=aF`W=W@Vq{yUlq{yangI$QtToJIjaxJ`3d@1s&{3!~l z0$GC45M@YXNl|QJi4tOBNEOHuhKVj?U|?7c<1j#ViKMZlD7CPl%0-D1p_4z2B}ExS zr&y|ZidKqR3nQ9|5*-W`j8T%o44T@vgi%r#Bqt=p^Bw~O1E^%;XJBCXynum$VJhQv z1}26QBzaV$v*0o{jF}8IOiLL17#SIA7_yjPe$9gC-5Q2?BsP)?7MR)^hIk}4k_wQU zz=~=Z;^FKRhG2%3jDDJIw^)ly3sQ@2am2@G=4F<|$KT>Cfn}{*Y|j3^zW#o<I2`?) zU4ujXgKn`ya}B8UC{E2uyTy`NlwN#`ExQ~{bH>Lf=Oh*v$Hy0g9HXG1(C{l*KO;Xk zRlg*$Br`EDQ7<VcF(os#NIyA0w;*4)B(<VMH?=G=N53R7FEcT|IJqdZprly8xU?X# zNIw@;=oITGgNh;j;vD?~aM`0*P+6qJz`#%?gC#ojVE&M0U|=YAXJBCX(ZFznL!y_p zlf8%i3WvlDl?xo23)C)fXhP5fF{vqeSH!eCSbDf`NXX3LyCR|A!P3KfLtJ`F-4$`& z4wfFC4xSF4&!8}T`GT2&;bjT~1H;P>VFrempcs6q04gOwapo3si?yUEF*ENLb4qI2 zEtZnh;*wizsRjAT8O66a3KB~)Q}dEjZ*e7oilq4B%&OE|Jf#IGi6yD=#U-f)#kbg# zN|UowONwu?m**E{rxq38VouC0xW$^Bn4FP%i@hwhC@H@<H5pVQfm{Q^91IK$+@KWK zLsE)MVa#MGfu{xr2Go?f0G`%BR={uxCya%z9<>evrQ=|Rl}vss88lgo6hWb51R_A% zZ?Qo<e2Xn7KRGd{Sd+g<9V7=<U<_iJfCy6%VFn`1L4*Z}umllSAi^3%*nkLI5TOYo zv_R1f%6bYYprJ?`BnvXWN)lUg0mqjLNHfUJ9}Ns26c_|#drLdZd&+xiFYsGl;J2Jx zHnU<*#r*nN^=r#kR;;PGC~t8^-U1?bfy1&$2b3N_5pjzpC9xzi8N`GI6^K13<EO}; zfdLjjw>Usqur#qGwFneRMUJ2_a{|e8L88Y6Bmj;IB4Pp5aDztzGy>dk=2w`_px7=3 z5ui8_V-Qe)#K9GQ`3w9u7x-<Ksx8!5qOn|mk^WY-jT&1tE-G1HQL=`}UEr_*M}pri zmV%<xlv^x0iFxTDc79SaDDa0?WUzz$keOV99v8ewaRDmWiabEE;t3*%jT%tN0goC` z=?uvp-k{i##+E&xPH{%gATkUB@{q{sslUK)eSzP4sn|k^B@)Z!7s+oG+bFR`;-aF} z6-6tE+yxG6aNOKt1s8j_*osn1N{jN6K?No(Uf3BJ7(hkN=W`6827L|V1m-xVTBcg& zT9#VYTDDsD8pbS`T2OPIp_M6xv4#Orfg-BADh39I6oytN<knR!M-2n^BCUq0hGiKO z1H)>#Yhsug7-~6dxoWv<7!cL(0#I!RcL9u1!&$>s!&<{u!?BE&fnhbgIIZCZxuTY* zh6h{>78!tY66-CN+{EJSA`J!xhFh#DsX2+2w^+dy+%1-z{NiFwX!QDk<w5P>;#;hs z>aqA1Yg%d|s8UGI&&|!xE55~<n3tSdT#{b|Qc;weT3i$W(!^054^eT8t2iE}<Q8io z$n>IMPz<6+zXCY=Z*hSOL2w;ZC5J5)AmqWuR4_0wG%(z-vcJe--oe^YI-zt%`hv<0 zsyFyWda7n9f??tUmL;4^_%F)oUywBfAt}Qv{6-xtH`KJ2XD!OwAi9I~qMF?mHM@%( z${idNv}UB<;1}+x>aXvrpHZ<wYD4&r%o8FP`Tef&`&|eOyT~8b!E%FNxPu#<mQWH8 zD1(C&PX!yKIZj;i=_Dcfbdr&LIw?**C?>!Y7cB9CXix$~OTJ7D47I$qd^L<&Y#<dN zoWfYe#lV2Wzg!Fq3)n%b&@pO@pq3xpY-eiWsNt>QKy+Ldfa*7Ntqe8%s4W5)wDv_U zFW5BZ7LFP|DwxJs0`Dp?Fr=`wFx0T4hDxnKi73L6Xg(7x5l6_CAiTy<!(1a!!&}3* zjD>+=HM{^o_t^x-*gG+xP#20}VPL2gt`(^jtrbJI57~8Kf3vo5px7f?BZlf;G#*M1 zzg8TV*(q!-3@GLb*ND`JqmBXKHCduW3K0^s8B*Bs^XIarGuB9ein<aRG<|saAblWR zwGt^D3qVaagk~tKMgldIYb8oR%}A&$qPtilk;2)@kR=3_U_f*kQA9;x@@u$I<FZx~ zS=|Ecc}x<`Es`~o3y@M1%xq96K80ruFKP(aO4bN25JRXzuuAk0>?{cwdjV4VgNZRP zlz`f%P;L#Hdr)16%41|G0ksTZIt5es5XLV+iX*532K?=M6tmcCgeWm98&qO56xo)5 z+VW8AQ}|N^P(#m@p;oF!YJnV70SbklM!@4^3@Hq#CNMJOaVs+zG8D6vGgUB0GL$ni zGDI>kGB7esVC=b90%`+8O|9Wc5o}?o5kxPmQiMR|3A!k1t_o(*6!rsG^BAK6ppxlx z1hj9K&QQY;t5(a{$%JUmAQ~|>j0@n+5U8WT6l!^e2=$3fJ?g;>MGg!M3@e$7Kz*27 ztY!JhiAlHEO7e3ui%V8A-(u1;xW$+WZa5Z$f?PoX(jfoEWdl+H>V(@>8DgvRLG5yI zlR(b~(p9t5LuknW^*BL2s~-&v7sTTrXounqmO0#4Bs5njuGd(lu~KV|))fg;h};G7 zI7rP6>M?_T1syG+TllDg+R2F^A_+u*M)XiZq$my42qrx!GLeHqGUWmo?MR%VGDr7{ zl<tbe^%<)&R%Wfqx*}x>k-H$7f*BN`${HLLao`p(@}N-(DBhq!R>MF{66s?=Ee28; z5s4<4p~xT99A&=6T2fj78uYEoEV#v7kY5ZMBP{{7CP7gIX&L_Fu*pfxO-f0$tI`if z9u0;Jed%FMBM=SQp!OzcWTb&%Y3N$x4J_L^HgRm^+QM}~+xnua%@tLf9f4O=?Hd>{ z!vf@Aa9DtPprAptPNdd9BD-J@i5fJ&2Qw6bT(Oe5NDb6R<}6MvNGwV$$uGLal9ivC zx02}=V+AC8fbt$RcN7(X(gLYo&IhFgP!0N{fnf#98lEc}cGoqWFKIX*aJ;DDc16Pt zuV+Dn2-6u-7(pY4(AY+zFuk>s$?q2<=Ss$+5>WnUEGh#9I3nuE^8(1<p9R3p`xP$h zJy&^dNL=Z&#s})~B2cY;i;?RVtFymfaL7vLTP&asOi?i?WO+*S5{oM1L4lfDbc?gN zq$sf@J~y$#Z6)I^?&O@*#Ju>t(wv;)m;e9&|9^`$wWuh+=oVu+N`VP#h=OAtG|V%d zAstj)O4KqU=LSUl*D$7lihGnPj)_b?lCT(ODgveYTbyZ$$tC%q;r*3NMWB(pqI^(D zfnytz%E`_7^`Q6$rK$#o3sQa%bbw{9$sD^CDjQffq+FD?z9MZ65x*eihndi+>D{6( zP^ktQ1T3b4*BU^E^@0dcveZ-ncQC<S*P=j>Xb^}1^#yOSrKEzUQEsv1q~;YDfr{2! zti=U6nI*TFa}x`0v4CosTb!wRrMam^pz)<#P+DPijt5N-u{y`Q`Uis(aFH}foI9;3 zKR3R(q$o2l9h_gmNvo&{BqvaiUtCg9l%JehTpSN7r*5$&78IoBrQBl4%PGl*L^c=5 z0Eqru%*7=|x0rKM^KP-_q$ZZ77T;pYFG$V1#adpJS&~`=YQkwsgR_1SsLx##0`gNR zhzJ7_;UEH3aTi5`SfCzuQ51+34I*Md1ULYAAbsw5&`3$~Ek0Pk8^SM|0CGBKNn$#L ze~T5YtSA*E%nF*mD!#>1T999SiyO(9Tf8Wy++xcC%|{jA;>v-~RDl!mEta&*oYZ1a z&?O*`>Y%bAeSA)MSzRTIw<rhsvACQWJZ}DgtS<fsHU@QVay$7S*cdc)mQ-C=x45Kk zu|wj3)kSr`E9!n1IaE4$Cggo!V-OUZ!ZjmsBHsd$C6Y_zFA5l3=eM}TZ*h^|>I%PA z2g?muYvh7>+>V+PE?4XWuiJ-TvJbxy5p&T#_KJP%1@X9x;&E5R<2rb5fGcZAwS2(t zLQvQh=kV*!v6q}<FT^EXbWXnFoP0qt<)UQD70HwizNaGM7bNU2NZ20`y(r>-MZ~>> z^QnNyM7Akx9jte4T#qK7P`wZsbs;9>LRQ5^x5_JSl^1QQuGmz4VBqD{{s<y2@>p~@ zUgWo!z&fF1M)V5ZyP}eFl`qJ-!O>af6W$jh(=K|XU-3x4D3x(VD&wMP<`vP*4!66K zvU8I!C|O)kve>J<BlSSY3A2k<L07DTF3JU8kqf>k8FEE3q{Hj3tkMN3vkOvYOH(2A z+ENI8LDGDO)<sE|v!)k3QZ9I;Tn&kYGGdb;j0^6m7bR0WylzO!&X=4exxnh8q}~-t zy$-Lt!irafbysBVC<g^mP~4TEj2qVWdu*;)hkRgW6bWPe$N(b0fXNP*2g2f0Y_1Ed zT@qGXP;yaN=ZdgShszCN@$14GmxMJ|NFPwWAgpmw*yD<@M~BM|9>IQ}E}yv~b0n`z z>Ryu6U7Nf?Wo71?%!`s1S0pVi@>pKsvAn=z`IKL1g6RyQDVEoTl`jb^UldloBCL9m zU+oIN+FIomsT&;EWUS9$m48vs{)(RcMJ<ObS`L@^9WL-Y+!d9ap}xTQqNw^6QS}cD zjDp%LOm2usO!u1PHKXdHh}IPmtqUSrAD9^hwZXDr;v-1i7Z3sF;v|0j_<>FC=T{B} z0jU`(H^9}x3Dyfzeix<uu1NV|2z+E^5(r@Y!T=&aFfefjFcyP)v!^x0e7IQ8aIyIC zah?%m^x@;gKIG-a3LEl*jhEK2Ah-5FHDoJO3R5QowhjlVI>#6*WvyXEjHZ&IpN+)9 zGWJ@IT2Ln*)anB_cyNrhve$4dLmjCF4Z48FX&JNN9rqL_=uj8fBoKjUFMwngfZEw0 zVHAwo!K&ry0L|Zn2B)}c*g$Ovh+^!+WHmgfZEf_9Vl5ZgG?o^Q8g43>#tk-&wS@yT z?o6@UcuU|j@916sT9iRG<RPaT<{I7_t{QICp%nB`n7|n84;~id2M>!0)C$%L)e0lq zhdk^C_7z(T2Z}vHHNvPdj>bbB78Ai`b_#n71B$r<HG(xFs2zB`CX1H9hi4cVW;3L4 z;OB#ew`xQ|c?)g$i~~O(qz|O4Ry2ik0UspIp^`PCsG(ddS|X27kp*hEgSj=LDO{Zl zh+#6s02zuXsHF{7zXmNXYsHY&;mD6-Xl@a!5nBKsXagGyB~o}&c-QcuhH$M|4c`J# z3k<3TL6v|SoKS8Sd|-9~QVc*P85kH!KoiDLZVj4yP+f=00}uWL*6`IZ#)G<RU=wOU zOQZPxirPR8JJ5s;O2-6Lz<`2__9Hn(2_OfMGCBcjQQ{n^0kuDi(m_Uo!gZkh1R5hL zqMDy3g1iH&&oFyb@OT1sL_k9a>7Xv8Hm(sjL`7G_h<$<(wQ4{VxD%Orbf9Bznk+@i zpyoVtfPZiic>_#%qi_<ay9ydC2933eL|p)*9f=b{ro>$VHENK@m_#ih(icRcFarlv z!-5kr6~|SIia?Q33UVU2+X)$6#54GS)vJ&pqiG<c%0UE1T7^3uBtyz5Nl_)pylN0p z19Bu$10;CdI2~kCEr<ZQ1Uw*8R0raM1_O$~-R5Qn1_rmH7SJG@G*Xut+<^r5oBKiP z!5I^jN{hhBc``_B3Wxx8kc&WZUNjZN1qTXfhzHz5E&|&R8goGOjEiP~)XfADvp@tW zkrvGcvF3mXQ14Y!9A`iG7E4KDI%EPF(Y?LJ7+<syq<ImD06TRth_wVnfcmaQOF=A9 z<|tYYVyyrXD?!965RnfGYEa>wfZ7#>@t|E&csOJ4lES4y{r}>9Opq?AyvhX*8OW^j z4StacK|Pf-1i>(HM#-GYIrSH1^)AR5fRLoY6@J4G7Svg3l_i=>^e@U8UXV2gAt~c4 z{3abNAJ`a_)t756(pnL^!S$k&)fFYHiyZRcdFjMK+#|gKE(;)8{(#8|mLpczor5nq z2VV$@xab^t#X0hVNYq7<s4F5-M0Zs=IITW1aBx};pRVeK^6D=P3>AznOkgUI=>r3U zND$LUF!=>cc7VF4)bF!i<gvUVCf&i>!+nEaq=N@sBEJL`lP^IHrDXV&G6MqxXk`Xy zA;afy9H132$RnO9(wPj%a{!=Rhgb~@T5MO#ioBE$v1+9R$%ZUA8^<&!BWfF|fH8$J zg=q~lYP*e*0f(7b`&Bh)W)_vyux5b<J;5!m;#?-sVpsSA0+2szSi$~b1IvJxqJdR{ zW!SQ~z#Ik!29TN>ws=r@frV<=vf%6mpf%fIQDmZqEejOFV4*B{+d72>R91oo8M5FL z(Wv3D0N$#GsDqF-Y>3u1s(MC-8n$4D63}cML@C1pP@M~9Bd8QsbbTpo;QkVOEk_M& z7AS#$6{oOggHjAbQECZjz6~tKz)-`Q1)o$#HK&%dh7-|lE@DUK<*}83TDDL#YPpcx z&nX<pDr-2i5G`ZQEYJueSXT{e7JS;chO>q>3$)4>EVG7l89M{RYIy9{a@TNX!6$BO zxZ~mMyaeQF*Axz9H<f@UGr{IDFqD9rDNuF_6N+72%h(tgR>RX=Eq4lc4Qm!?O)yw} z8AFjCir;vMu>-|#$UfsmvyB7A{d~yoT*Hr=UuxM)Kr8jYu3}(F5kQM89u$)V(PVj1 zWQEXV`A|$2Mw8_)0j&#!+FQe#1)BW?^U%}@l=y;$!9<Nf4R;Ms4M!St4LfMzOAY@T z5j4LGmVjmt!KxV;Y6NRovq0<F!2C3(Oa^HF6+%nFpynGxQD_Y}jxiLFdeACfusJoX zh`d-NSppi72a7W>WWmb{WHqQh$^*>`iMBAHj!rN#)NnM4)^OmmAJq&-h8lLFRq_(8 zl8<PWtP7CxI@I$F;9QScE{K$XT6j=JHQb0ihw7(1Ze+PEU8n{I6y3bIbfc)^BT5xJ zE>$%gji_$sz@-utmo*%X>@^%&p#Bfo$zU;V1iywmOCKx&TK6ed!@2;egoBBrk8PDP z7BQu;<gp=_DJkM}I8j54k%&^fMsPOTd^0h+QqYz+fwpqhFl3?Dci@^3du>(%>PkaB zSHqnmiCX3qvDa`Tau6uIQ2kXaOt^Nc5uVMEA~lx@RVT!qHLNwlHG-()XSHl7bud|V zrlyQv6_cKRh$iDLj?{|G;*$9M>>^OzS0(IJnwbOISEf*sk*bge+C5gR$>isEizO+w zs02K5r^$AUxgas+7ISG{_ATb5{Nh{eX_*!ApxHl;64?GQ(A1?SYtbH17iBMq*azyj zv*zTNrxt<dHE*#bXCxNgVg-@K7%GeQgY<w5DcS<+-7yw{^cR5&s3O$aLQOXC?By+% zaQ`5eqKzPJpaww^s1&}%5)$O<iZT)dYMOx>37<h}cRE82%AO&_05<v>fGTbV2IyqB zCetm}lKi6N4A87+N)gtst~R!5za&t|BCqg)bj1&WI&h%IQ3Jz;+`OxWWmgKTE>zcC zEUdj!SbH(I7PcS&6d0PEx7hRIAq$o{^Po$Ri*Iq~!Pg)c-(t&)2X!++3c+D}iw{J_ z7bK>{XXd4(R@~x5VwUD*Lqx%GQYC~E`=A8}Ik#9-L0b(WJ#SExLDLAbSRT}5xW$xT ze2XJDF*`LSv#9tMOF?2u#x3@g%%Z%++|*la;G|W2ixup1(9-L~lv}L6{w}UQkj^@& zi++ngCqFR-G-V53`J9>p9^olE0*c6spftl&k`J2sF3U_#y~PIEqIioXGcPS49PdS- zwpr0`kZN#R12s5{KoML7PjyIX2|Q#38iy|eH9?C&?bll@pcUUmpqZc|P&@1vD`<|r zxCqpxE&?@!i$EJ%ZgJ#h=EbKKr4|-}n!k`;8*@R<W6J|?<|;Z5a>50W2upTqW$`Wc zjKt!^l9D1#kz35kImJa+K=Kbk1UPAfs$g&+++r&L@3gwb9OCGHi^bW)G3XX!2_%xh zxd|K;w^%}4BSOFn&%i0W=qSh}@Zbb!Kn(20B2aJ^gK8~U-yfL<j{_842Q9Xd#F;ul z0};hCETARlU)dN0#4hkFUf@@p%Qll^4hMwY!E%>_tA~54(-imV{*(L{xLg#`ydt7` zLBw!H$PSka9F7+`9ItRVUf^)N%gx(k-f!1sH$&wjxBL}u`40>%oKh=T)^LFtH$-J8 z1W$>$AgX#nRCNIhgzj*=A+0jQc#h=-Y2yph#tX`pR6|%DZaqFXc!YX<uJdSI;?Y<k zc16?jil*I;!Yi7NS2W!(@_1a~@wm?8eTm2WgxeY4i#$<Rc%m-wMBNaU?C^cc!Pn2- z#eG3U^CE}V6%MTn99lO-<T^P!m^(slaP#-r%rLvet$2Z3@veZ%f{-PV7X|dM2<Ue> z-cVFpB6>kWe+J_m))}m8ojW}53d=8GUlF(_bO+-e)&qt|Od*rB7c#Rh6qQ{ms<|Ls zdr`Rdig0a*%MD4XIpQ5IJzgDNPlY9Bh%ZfETfCR~fXRuHGgTLaqb>?ZT@jAzaJj)R zIzwcR<OP1E3;arV#g!MhZx!CFeAM_tK**JVm<uTxS5opWi05Av&%Yv`KY`^gpYQ~? zrOX%jR4?+WUg1;iV7|*QK7;)tzrq!Mg$|axf?^XYFA6GN5mfA8yDKa)LmD!9+rfdV zOh|Eo$`Y-MLb_LkbUWDZiYTs7-yyQ2<Uq&;3$F_S!8bJZcW9gt`M}I5>JOT57WHTR z!T@4-aDHWD5R{m~xxi$J)dc~w3j$^vL?CnrD@st_;1THe>hhXUIwNIH?g^JOUKjKd z)@H8B+Yz!S>Y|><6+Mp&dL9>I5-udyUP!LJ$WwQPr|tqz-3@->3;gmo1VpBDP2!qi zdQm{}ih$w;0mT~}-2I$goD)<pa!6d^khs7haf5@epQnpwLg+;f=_?%47dWJEa0vAC zb@5Foy~rVZg+ulNhwKdw9#F*J(9&C@vqSBYmcs=thpELgOy*ckte;Xpq5eS1k*q6j z;ddovW`xa&xhSc1MN;dowA_q}IdvDM^{z<k-4&CZp*%-(V&0Uz8(Ml7w5(8cv)nK+ zxnSThBV|tBjJyLWHzZ}}$Uz7x#T6p!C09wVlwKo!LCWNUl*xp^34uFQ_Go<&<`U)l zz`!NS^^t*#llu#Z_y8iliZO8VgIqhIa)RGQ4&^Hx$`?44;YnBHB8TP`@IJ~L0+JJ$ zr*K{Xhsz8X2z_0^@RESxQT7uoC(<uEgk5n6yI_>CL1l~92CWM*2^R$tuLvY|u-=7a zgbAe+d_eFbhvF3u#S0vY4+KRf2u}!^VY)!`qM*(dL7fh^8ytK+JpKG#{4?0*@LuFl zyTYM%fkW*Ezi0<9cx*+Jvk26#Edn(bi$JYH@RHmjLr}2<YDl=bg=n%tBtRRQz>N!# z7^k0~8x~=vqU|7^J3w{4)Gdzqcu)lrAAgH0K0Y@;r8FlsKK>R@e0*VPVh&V>#m~{# zwFuM)F1iWQ3hI#-fx4+h;GtMhJ%5WiGq2<pOHzJ*4y1qt?Tjk|ZNMr5&2beS2bI=r zA*p%A`9(#sAP#$8etddSVhVW0QqdZax!XYE+~A$Ixv3=?`6=Ks^cF94_ib`&PELHh zCSwtJQzU4}+W}J2g8JY^AOd7n@lVKzY6AlVKHyepaJj)F*Wmhrg_TwB0|OR9f<avR zhJ^GDDY+XmvNyyfZ-`6W5RtqgCVfLf=7Y2VtJMbv0amLA{2~*AXJ|}_y~3~jffXdm z#=s{$!FUG81ludTiXYfPLL3bIA`_fvNKEj(!l(3s6C}jNASm*I8^q#a5ElEu3u5sx zh)R6m2eAYg#HBt6f>=TfLZTmpK`apvOBBQsW8f3|AP!<lFbIfzkOZ-$7=*+St^zv^ zozP;CmIrwP*&l-3thOH*xLIu<@ChSa$O;l=1G$DB#Nq(i%n4#~fmqxi77xe`ydV}I z$PN4;mH@~Na1+7Cq7w=XqLMd6ByNaGfx=Z>0^}Zepo;Uc+I(Q(W3@qb3`mrXfnVqY zJBY;rVsV04TnzleAGkp*9*|RcK`cIy1NlKL0T4?N#1aBIRT#t)0XbC^#1aEJ6>cBc zQglLrl~rT`D=2A*tWaH}17@HTd<<;D4WTWujqxq<ADC2G0~lwNeqaF6E2JPaGWn62 zflU;q@Pi*Cie?#BQIK94R?!ur9~fj<kqEdxkf;p<o8Si~OIEQD3@`#DFW3@|CW?>; z7Z~8YplMKaiGhLP7F$VW0chPJXt1IPlvRsBvx$)G3(A#6pxKpM(%_xxdf;Ygv0gH0 zXS!Z-4ulWR`L}o=Dj+SWBG8b<EpCWVX-Q^IF{GgiZp49FZMTGw<n$nm0KsiQ@VOI3 z;HD#}U3g0nSsl0!R0Qf~6@goh;Fcn&g?URDSsAEh3i1-D{e@~#ZYt;?4RDciOB7iP zxOoRUOat7Ay(JHkL-#KHhyZYt6wL(K@d4lh?Un)-6OxP4^bkgX`Wd%)A<97Q+?>oj zaH|(G;{_UTyd{ews|OB9NZ=>tl@ue*l)V8Jk9R=?sF(xqjex{7Xh7u`hYh6Qwku*` zWMBXljKxP885lk=Gcq!MU}Iq9YTyLH8w|P^2%!fILKm>18w^$#P|*zr`3tD%27}QB z+~@{_;RQnI27~(rLg)sA)&*2_gF*8GD!Rd7b^#ULV6eP^if%BdUqD5eF1*3ubOATI w!QgTM8+yPg+#xl=<07Z*6;9a(whwI1%#30m7_gHw)INe`zJN(gRp4j_01h|aK>z>% literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1874e521ca0c7d7e3004a1b69a4ae48e1f6bf140 GIT binary patch literal 3612 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 ORJAb+=m@Zjumb>QxgZDt literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbffb6675228c80bd72bea723d3dbbfbcbec55b4 GIT binary patch literal 6748 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/sl/model.py b/tania_scripts/supar/models/const/sl/model.py new file mode 100644 index 0000000..640c1f9 --- /dev/null +++ b/tania_scripts/supar/models/const/sl/model.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.model import Model +from supar.modules import MLP, DecoderLSTM +from supar.utils import Config +from typing import List + + +class SLConstituentModel(Model): + + def __init__(self, + n_words, + n_commons, + n_ancestors, + n_tags=None, + n_chars=None, + encoder='lstm', + feat: List[str] =['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_arc_mlp=500, + n_rel_mlp=100, + mlp_dropout=.33, + scale=0, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + # create decoder + self.common_decoder, self.ancestor_decoder = None, None + if self.args.decoder == 'lstm': + decoder = lambda out_dim: DecoderLSTM( + self.args.n_encoder_hidden, self.args.n_encoder_hidden, out_dim, + self.args.n_decoder_layers, dropout=mlp_dropout, device=self.device + ) + else: + decoder = lambda out_dim: MLP( + n_in=self.args.n_encoder_hidden, n_out=out_dim, + dropout=mlp_dropout, activation=True + ) + + self.common_decoder = decoder(self.args.n_commons) + self.ancestor_decoder = decoder(self.args.n_ancestors) + + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay + 1), + n_out=self.args.n_encoder_hidden, dropout=mlp_dropout) + + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words: torch.Tensor, feats: List[torch.Tensor]=None): + # words, *feats ~ [batch_size, bos + pad(seq_len) + delay, n_encoder_hidden] + x = self.encode(words, feats) + x = x[:, 1:, :] + + # x ~ [batch_size, pad(seq_len), n_encoder_hidden] + batch_size, pad_seq_len, embed_size = x.shape + if self.args.delay != 0: + x = torch.cat([x[:, i:(pad_seq_len - self.args.delay + i), :] for i in range(self.args.delay+1)], dim=2) + x = self.delay_proj(x) + + x, qloss = self.vq_forward(x) # vector quantization + + # s_common ~ [batch_size, pad(seq_len), n_commons] + # s_ancestor ~ [batch_size, pad(seq_len), n_ancestors] + s_common, s_ancestor = self.common_decoder(x), self.ancestor_decoder(x) + return s_common, s_ancestor, qloss + + def loss(self, + s_common: torch.Tensor, s_ancestor: torch.Tensor, + commons: torch.Tensor, ancestors: torch.Tensor, mask: torch.Tensor): + s_common, commons = s_common[mask], commons[mask] + s_ancestor, ancestors = s_ancestor[mask], ancestors[mask] + common_loss = self.criterion(s_common, commons) + ancestor_loss = self.criterion(s_ancestor, ancestors) + return common_loss + ancestor_loss + + def decode(self, s_common, s_ancestor): + common_pred = s_common.argmax(-1) + ancestor_pred = s_ancestor.argmax(-1) + return common_pred, ancestor_pred \ No newline at end of file diff --git a/tania_scripts/supar/models/const/sl/parser.py b/tania_scripts/supar/models/const/sl/parser.py new file mode 100644 index 0000000..17e8a3a --- /dev/null +++ b/tania_scripts/supar/models/const/sl/parser.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Dict, Iterable, Set, Union + +import torch, nltk +from supar.models.const.sl.model import SLConstituentModel +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, EOS, PAD, UNK +from supar.utils.field import ChartField, Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import SpanMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.models.const.sl.transform import SLConstituent +from supar.utils.transform import Batch +from supar.models.const.crf.transform import Tree +from supar.codelin import get_con_encoder, LinearizedTree, C_Label +from supar.codelin.utils.constants import BOS as C_BOS, EOS as C_EOS + +logger = get_logger(__name__) + + +class SLConstituentParser(Parser): + + NAME = 'SLConstituentParser' + MODEL = SLConstituentModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.COMMON = self.transform.COMMON + self.ANCESTOR = self.transform.ANCESTOR + self.encoder = self.transform.encoder + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, texts, *feats, commons, ancestors, trees = batch + mask = batch.mask[:, (1+self.args.delay):] + s_common, s_ancestor, qloss = self.model(words, feats) + loss = self.model.loss(s_common, s_ancestor, commons, ancestors, mask) + qloss + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + words, texts, *feats, commons, ancestors, trees = batch + mask = batch.mask[:, (1+self.args.delay):] + + # forward pass + s_common, s_ancestor, qloss = self.model(words, feats) + loss = self.model.loss(s_common, s_ancestor, commons, ancestors, mask) + qloss + + # make predictions of the output of the network + common_preds, ancestor_preds = self.model.decode(s_common, s_ancestor) + + # obtain original tokens to compute decoding + lens = (batch.lens - 1 - self.args.delay).tolist() + common_preds = [self.COMMON.vocab[i.tolist()] for i in common_preds[mask].split(lens)] + ancestor_preds = [self.ANCESTOR.vocab[i.tolist()] for i in ancestor_preds[mask].split(lens)] + # tag_preds = [self.transform.POS.vocab[i.tolist()] for i in tags[mask].split(lens)] + tag_preds = map(lambda tree: tuple(zip(*tree.pos()))[1], trees) + + preds = list() + for i, (forms, upos, common_pred, ancestor_pred) in enumerate(zip(texts, tag_preds, common_preds, ancestor_preds)): + labels = list(map(lambda x: self.encoder.separator.join(x), zip(common_pred, ancestor_pred))) + linearized = list(map(lambda x: '\t'.join(x), zip(forms, upos, labels))) + linearized = [f'{C_BOS}\t{C_BOS}\t{C_BOS}'] + linearized + [f'{C_EOS}\t{C_EOS}\t{C_EOS}'] + linearized = '\n'.join(linearized) + tree = LinearizedTree.from_string(linearized, mode='CONST', separator=self.encoder.separator, + unary_joiner=self.encoder.unary_joiner) + tree = self.encoder.decode(tree) + tree = tree.postprocess_tree('strat_max', clean_nulls=False) + preds.append(nltk.Tree.fromstring(str(tree))) + + if len(preds[-1].leaves()) != len(trees[i].leaves()): + with open('error', 'w') as file: + file.write(linearized) + + + return SpanMetric(loss, + [Tree.factorize(tree, None, None) for tree in preds], + [Tree.factorize(tree, None, None) for tree in trees]) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, texts, *feats = batch + tags = feats[-1][:, (1+self.args.delay):] + mask = batch.mask[:, (1 + self.args.delay):] + + # forward pass + s_common, s_ancestor, _ = self.model(words, feats) + + # make predictions of the output of the network + common_preds, ancestor_preds = self.model.decode(s_common, s_ancestor) + + # obtain original tokens to compute decoding + lens = (batch.lens - 1 - self.args.delay).tolist() + common_preds = [self.COMMON.vocab[i.tolist()] for i in common_preds[mask].split(lens)] + ancestor_preds = [self.ANCESTOR.vocab[i.tolist()] for i in ancestor_preds[mask].split(lens)] + tag_preds = [self.transform.POS.vocab[i.tolist()] for i in tags[mask].split(lens)] + + preds = list() + for i, (forms, upos, common_pred, ancestor_pred) in enumerate(zip(texts, tag_preds, common_preds, ancestor_preds)): + labels = list(map(lambda x: self.encoder.separator.join(x), zip(common_pred, ancestor_pred))) + linearized = list(map(lambda x: '\t'.join(x), zip(forms, upos, labels))) + linearized = [f'{C_BOS}\t{C_BOS}\t{C_BOS}'] + linearized + [f'{C_EOS}\t{C_EOS}\t{C_EOS}'] + linearized = '\n'.join(linearized) + tree = LinearizedTree.from_string(linearized, mode='CONST', separator=self.encoder.separator, unary_joiner=self.encoder.unary_joiner) + tree = self.encoder.decode(tree) + tree = tree.postprocess_tree('strat_max', clean_nulls=False) + preds.append(nltk.Tree.fromstring(str(tree))) + batch.trees = preds + return batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR = None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len, delay=args.delay) + TAG = Field('tags', bos=BOS,) + TEXT = RawField('texts') + COMMON = Field('commons') + ANCESTOR = Field('ancestors') + TREE = RawField('trees') + encoder = get_con_encoder(args.codes) + transform = SLConstituent(encoder=encoder, WORD=(WORD, TEXT, CHAR), POS=TAG, + COMMON=COMMON, ANCESTOR=ANCESTOR, TREE=TREE) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if CHAR is not None: + CHAR.build(train) + TAG.build(train) + COMMON.build(train) + ANCESTOR.build(train) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_commons': len(COMMON.vocab), + 'n_ancestors': len(ANCESTOR.vocab), + 'n_tags': len(TAG.vocab), + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'delay': 0 if 'delay' not in args.keys() else args.delay, + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/const/sl/transform.py b/tania_scripts/supar/models/const/sl/transform.py new file mode 100644 index 0000000..b94b966 --- /dev/null +++ b/tania_scripts/supar/models/const/sl/transform.py @@ -0,0 +1,94 @@ +from typing import Union, Iterable, Optional, Set +from supar.utils.field import Field +from supar.utils.transform import Sentence, Transform +from supar.codelin import C_Tree, UNARY_JOINER, LABEL_SEPARATOR +import nltk, re + + +class SLConstituent(Transform): + fields = ['WORD', 'POS', 'COMMON', 'ANCESTOR', 'TREE'] + + def __init__( + self, + encoder, + WORD: Union[Field, Iterable[Field]], + POS: Union[Field, Iterable[Field]], + COMMON: Union[Field, Iterable[Field]], + ANCESTOR: Union[Field, Iterable[Field]], + TREE: Union[Field, Iterable[Field]] + ): + super().__init__() + + self.WORD = WORD + self.POS = POS + self.COMMON = COMMON + self.ANCESTOR = ANCESTOR + self.TREE = TREE + self.encoder = encoder + + + @property + def src(self): + return self.WORD, self.POS + + @property + def tgt(self): + return self.COMMON, self.ANCESTOR, self.TREE + def load( + self, + data: Union[str, Iterable], + **kwargs + ) -> Iterable[Sentence]: + lines = open(data) + index = 0 + for line in lines: + line = line.strip() + if len(line) > 0: + sentence = SLConstituentSentence(self, line, self.encoder, index) + yield sentence + index += 1 + + +def get_nodes(tree: nltk.Tree): + nodes = {tree.label()} + for subtree in tree: + if isinstance(subtree[0], nltk.Tree): + nodes = {*nodes, *get_nodes(subtree)} + return nodes + +def remove_doubles(tree: nltk.Tree): + for i, subtree in enumerate(tree): + if isinstance(subtree, str) and len(tree) > 1: + tree.pop(i) + elif isinstance(subtree, nltk.Tree): + remove_doubles(subtree) + +class SLConstituentSentence(Sentence): + + def __init__(self, transform: SLConstituent, line: str, encoder, index: Optional[int] = None): + super().__init__(transform, index) + + # get nodes of the tree + gold = nltk.Tree.fromstring(line) + nodes = ''.join(get_nodes(gold)) + assert (encoder.separator not in nodes) and (encoder.unary_joiner not in nodes) + + # create linearized tree + tree = C_Tree.from_string(line) + linearized_tree = encoder.encode(tree) + self.annotations = [] + commons = list(map(lambda x: repr(x).split(encoder.separator)[0], linearized_tree.labels)) + ancestors = list(map(lambda x: encoder.separator.join(repr(x).split(encoder.separator)[1:]), linearized_tree.labels)) + + _, postags = zip(*gold.pos()) + self.values = [ + linearized_tree.words, + postags, + commons, ancestors + ] + self.values.append( + nltk.Tree.fromstring(line) + ) + def __repr__(self): + remove_doubles(self.values[-1]) + return re.sub(' +', ' ', str(self.values[-1]).replace('\n', '').replace('\t', '')) diff --git a/tania_scripts/supar/models/const/tt/__init__.py b/tania_scripts/supar/models/const/tt/__init__.py new file mode 100644 index 0000000..4389219 --- /dev/null +++ b/tania_scripts/supar/models/const/tt/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import TetraTaggingConstituencyModel +from .parser import TetraTaggingConstituencyParser + +__all__ = ['TetraTaggingConstituencyModel', 'TetraTaggingConstituencyParser'] diff --git a/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a577e63e231c15d7c6ffbde1d8660f3f458b985 GIT binary patch literal 304 zcmd1j<>g{vU|`_PGe|$fz`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$ zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9WvLUG@MTsGa>FJqy>CX9i#U+^~rKx$z zmA?5YsX3aAx8!gs2uLg{PAw_|*<HlUz`)?A$$E=57o-a;c8je5q5vd!i#<L*F()TJ zekDT@I|BoR_+_V`k)NBYUy@jonV6TTmz0y3l9^hhpP83jkXWQ&TnZw=1{UilgIuOx pQlcLppP83g5+AQuP<e~PCO1E&G$+*#<d<SL1_lNmCLTr}CIErDQ0xEz literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f242de08b1629939a1184b1ebf706bb4b2b2cbda GIT binary patch literal 382 zcmZ3^%ge>Uz`&q%Up3<l0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w`4<7ONtUh64TQ&^U|I3^NLF{OG;Dok}G}l zQ&Mv@8E?tqQV@_>RGeB=#LU3JP{hK(z~HCJdW$s|qzf!|i>&~n03>&dJw84$Cnr9B zCBtWsYk!66XXNLm>X#&zWG3b%>LukQrevlT=_lvs7Ub)eq*j#Zrj{k<=$9nsWhTZK zCl_TFloab1mlh-z>4U8()=vhxRllS}KR!M)FS8^*Uaz3?7l%!5eoARhs$CH`0|Nud xi^Wz93=AKb85tQrurV+iUSKdlMmHFYE})_Z+*%iOd@gYLHn4+W5hnu!0{~YAZxR3i literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4deac65c29f9618638ef3d168e5f3799e148ae96 GIT binary patch literal 10462 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 O4kjK(9uQ^}VFm!NZ@HfU literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08a12831d12bab671d404d55859b4bb81ba4c6e0 GIT binary patch literal 15368 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..740bf37c4d0abed35cbd2fe734b4899404da1c63 GIT binary patch literal 8248 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 QD8VSg2x5US2a^ah0MyVEd;kCd literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d0f9c3cecab729455b1cf901cfed200de9a4883 GIT binary patch literal 15371 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2226fc4c38750791963263a693f1896078972e05 GIT binary patch literal 11481 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee00f85bb15eed4b144ed777f9dbfeef8c753e8c GIT binary patch literal 17156 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/tt/model.py b/tania_scripts/supar/models/const/tt/model.py new file mode 100644 index 0000000..9bce1b6 --- /dev/null +++ b/tania_scripts/supar/models/const/tt/model.py @@ -0,0 +1,265 @@ +# -*- coding: utf-8 -*- + +from typing import List, Tuple + +import torch +import torch.nn as nn + +from supar.model import Model +from supar.utils import Config +from supar.utils.common import INF + + +class TetraTaggingConstituencyModel(Model): + r""" + The implementation of TetraTagging Constituency Parser :cite:`kitaev-klein-2020-tetra`. + + Args: + n_words (int): + The size of the word vocabulary. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layers. Default: .33. + n_gnn_layers (int): + The number of GNN layers. Default: 3. + gnn_dropout (float): + The dropout ratio of GNN layers. Default: .33. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_gnn_layers=3, + gnn_dropout=.33, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.proj = nn.Linear(self.args.n_encoder_hidden, self.args.n_leaves + self.args.n_nodes) + self.criterion = nn.CrossEntropyLoss() + + def forward( + self, + words: torch.LongTensor, + feats: List[torch.LongTensor] = None + ) -> torch.Tensor: + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + Scores for all leaves (``[batch_size, seq_len, n_leaves]``) and nodes (``[batch_size, seq_len, n_nodes]``). + """ + + s = self.proj(self.encode(words, feats)[:, 1:-1]) + s_leaf, s_node = s[..., :self.args.n_leaves], s[..., self.args.n_leaves:] + return s_leaf, s_node + + def loss( + self, + s_leaf: torch.Tensor, + s_node: torch.Tensor, + leaves: torch.LongTensor, + nodes: torch.LongTensor, + mask: torch.BoolTensor + ) -> torch.Tensor: + r""" + Args: + s_leaf (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``. + Leaf scores. + s_node (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``. + Non-terminal scores. + leaves (~torch.LongTensor): ``[batch_size, seq_len]``. + Actions for leaves. + nodes (~torch.LongTensor): ``[batch_size, seq_len]``. + Actions for non-terminals. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor: + The training loss. + """ + + leaf_mask, node_mask = mask, mask[:, 1:] + leaf_loss = self.criterion(s_leaf[leaf_mask], leaves[leaf_mask]) + node_loss = self.criterion(s_node[:, :-1][node_mask], nodes[node_mask]) if nodes.shape[1] > 0 else 0 + return leaf_loss + node_loss + + def decode( + self, + s_leaf: torch.Tensor, + s_node: torch.Tensor, + mask: torch.BoolTensor, + left_mask: torch.BoolTensor, + depth: int = 8 + ) -> List[List[Tuple]]: + r""" + Args: + s_leaf (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``. + Leaf scores. + s_node (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``. + Non-terminal scores. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + left_mask (~torch.BoolTensor): ``[n_leaves + n_nodes]``. + The mask for distingushing left/rightward actions. + depth (int): + Stack depth. Default: 8. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + from torch_scatter import scatter_max + + lens = mask.sum(-1) + batch_size, seq_len, n_leaves = s_leaf.shape + end_mask = (lens - 1).unsqueeze(-1).eq(lens.new_tensor(range(seq_len))) + leaf_left_mask, node_left_mask = left_mask[:n_leaves], left_mask[n_leaves:] + s_leaf = s_leaf.masked_fill_(end_mask.unsqueeze(-1) & leaf_left_mask, -INF) + # [n_leaves], [n_nodes] + changes = (torch.where(leaf_left_mask, 1, 0), torch.where(node_left_mask, 0, -1)) + # [batch_size, depth] + depths = lens.new_full((depth,), -2).index_fill_(-1, lens.new_tensor(0), -1).repeat(batch_size, 1) + # [2, batch_size, depth, seq_len] + labels, paths = lens.new_zeros(2, batch_size, depth, seq_len), lens.new_zeros(2, batch_size, depth, seq_len) + # [batch_size, depth] + s = s_leaf.new_zeros(batch_size, depth) + + def advance(s, s_t, depths, changes): + batch_size, n_labels = s_t.shape + # [batch_size, depth * n_labels] + depths = (depths.unsqueeze(-1) + changes).view(batch_size, -1) + # [batch_size, depth, n_labels] + s_t = s.unsqueeze(-1) + s_t.unsqueeze(1) + # [batch_size, depth * n_labels] + # fill scores of invalid depths with -INF + s_t = s_t.view(batch_size, -1).masked_fill_((depths < 0).logical_or_(depths >= depth), -INF) + # [batch_size, depth] + # for each depth, we use the `scatter_max` trick to obtain the 1-best label + s, ls = scatter_max(s_t, depths.clamp(0, depth - 1), -1, s_t.new_full((batch_size, depth), -INF)) + # [batch_size, depth] + depths = depths.gather(-1, ls.clamp(0, depths.shape[1] - 1)).masked_fill_(s.eq(-INF), -1) + ll = ls % n_labels + lp = depths - changes[ll] + return s, ll, lp, depths + + for t in range(seq_len): + m = lens.gt(t) + s[m], labels[0, m, :, t], paths[0, m, :, t], depths[m] = advance(s[m], s_leaf[m, t], depths[m], changes[0]) + if t == seq_len - 1: + break + m = lens.gt(t + 1) + s[m], labels[1, m, :, t], paths[1, m, :, t], depths[m] = advance(s[m], s_node[m, t], depths[m], changes[1]) + + lens = lens.tolist() + labels, paths = labels.movedim((0, 2), (2, 3))[mask].split(lens), paths.movedim((0, 2), (2, 3))[mask].split(lens) + leaves, nodes = [], [] + for i, length in enumerate(lens): + leaf_labels, node_labels = labels[i].transpose(0, 1).tolist() + leaf_paths, node_paths = paths[i].transpose(0, 1).tolist() + leaf_pred, node_pred, prev = [leaf_labels[-1][0]], [], leaf_paths[-1][0] + for j in reversed(range(length - 1)): + node_pred.append(node_labels[j][prev]) + prev = node_paths[j][prev] + leaf_pred.append(leaf_labels[j][prev]) + prev = leaf_paths[j][prev] + leaves.append(list(reversed(leaf_pred))) + nodes.append(list(reversed(node_pred))) + return leaves, nodes diff --git a/tania_scripts/supar/models/const/tt/parser.py b/tania_scripts/supar/models/const/tt/parser.py new file mode 100644 index 0000000..7289c22 --- /dev/null +++ b/tania_scripts/supar/models/const/tt/parser.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Dict, Iterable, Set, Union + +import torch + +from supar.models.const.tt.model import TetraTaggingConstituencyModel +from supar.models.const.tt.transform import TetraTaggingTree +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, EOS, PAD, UNK +from supar.utils.field import Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import SpanMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class TetraTaggingConstituencyParser(Parser): + r""" + The implementation of TetraTagging Constituency Parser :cite:`kitaev-klein-2020-tetra`. + """ + + NAME = 'tetra-tagging-constituency' + MODEL = TetraTaggingConstituencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TREE = self.transform.TREE + self.LEAF = self.transform.LEAF + self.NODE = self.transform.NODE + + self.left_mask = torch.tensor([*(i.startswith('l') for i in self.LEAF.vocab.itos), + *(i.startswith('L') for i in self.NODE.vocab.itos)]).to(self.device) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + depth: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + depth: int = 1, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + depth: int = 1, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, *feats, _, leaves, nodes = batch + mask = batch.mask[:, 2:] + s_leaf, s_node = self.model(words, feats) + loss = self.model.loss(s_leaf, s_node, leaves, nodes, mask) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + words, *feats, trees, leaves, nodes = batch + mask = batch.mask[:, 2:] + s_leaf, s_node = self.model(words, feats) + loss = self.model.loss(s_leaf, s_node, leaves, nodes, mask) + preds = self.model.decode(s_leaf, s_node, mask, self.left_mask, self.args.depth) + preds = [TetraTaggingTree.action2tree(tree, (self.LEAF.vocab[i], self.NODE.vocab[j] if len(j) > 0 else [])) + for tree, i, j in zip(trees, *preds)] + return SpanMetric(loss, + [TetraTaggingTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [TetraTaggingTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees]) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask = batch.mask[:, 2:] + s_leaf, s_node = self.model(words, feats) + preds = self.model.decode(s_leaf, s_node, mask, self.left_mask, self.args.depth) + batch.trees = [TetraTaggingTree.action2tree(tree, (self.LEAF.vocab[i], self.NODE.vocab[j] if len(j) > 0 else [])) + for tree, i, j in zip(trees, *preds)] + if self.args.prob: + raise NotImplementedError("Returning action probs are currently not supported yet.") + return batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR, ELMO, BERT = None, None, None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True) + if 'tag' in args.feat: + TAG = Field('tags', bos=BOS, eos=EOS) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len) + if 'elmo' in args.feat: + from allennlp.modules.elmo import batch_to_ids + ELMO = RawField('elmo') + ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device) + if 'bert' in args.feat: + t = TransformerTokenizer(args.bert) + BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t) + BERT.vocab = t.vocab + TREE = RawField('trees') + LEAF, NODE = Field('leaf'), Field('node') + transform = TetraTaggingTree(WORD=(WORD, CHAR, ELMO, BERT), POS=TAG, TREE=TREE, LEAF=LEAF, NODE=NODE) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if TAG is not None: + TAG.build(train) + if CHAR is not None: + CHAR.build(train) + LEAF, NODE = LEAF.build(train), NODE.build(train) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_leaves': len(LEAF.vocab), + 'n_nodes': len(NODE.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'bert_pad_index': BERT.pad_index if BERT is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'eos_index': WORD.eos_index + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/const/tt/transform.py b/tania_scripts/supar/models/const/tt/transform.py new file mode 100644 index 0000000..a337b94 --- /dev/null +++ b/tania_scripts/supar/models/const/tt/transform.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union, Sequence + +import nltk + +from supar.models.const.crf.transform import Tree +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class TetraTaggingTree(Tree): + r""" + :class:`TetraTaggingTree` is derived from the :class:`Tree` class and is defined for supporting the transition system of + tetra tagger :cite:`kitaev-klein-2020-tetra`. + + Attributes: + WORD: + Words in the sentence. + POS: + Part-of-speech tags, or underscores if not available. + TREE: + The raw constituency tree in :class:`nltk.tree.Tree` format. + LEAF: + Action labels in tetra tagger transition system. + NODE: + Non-terminal labels. + """ + + fields = ['WORD', 'POS', 'TREE', 'LEAF', 'NODE'] + + def __init__( + self, + WORD: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + TREE: Optional[Union[Field, Iterable[Field]]] = None, + LEAF: Optional[Union[Field, Iterable[Field]]] = None, + NODE: Optional[Union[Field, Iterable[Field]]] = None + ) -> Tree: + super().__init__() + + self.WORD = WORD + self.POS = POS + self.TREE = TREE + self.LEAF = LEAF + self.NODE = NODE + + @property + def tgt(self): + return self.LEAF, self.NODE + + @classmethod + def tree2action(cls, tree: nltk.Tree) -> Tuple[Sequence, Sequence]: + r""" + Converts a (binarized) constituency tree into tetra-tagging actions. + + Args: + tree (nltk.tree.Tree): + A constituency tree in :class:`nltk.tree.Tree` format. + + Returns: + Tetra-tagging actions for leaves and non-terminals. + + Examples: + >>> from supar.models.const.tt.transform import TetraTaggingTree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ She)) + (VP (_ enjoys) (S (VP (_ playing) (NP (_ tennis))))) + (_ .))) + ''') + >>> tree.pretty_print() + TOP + | + S + ____________|________________ + | VP | + | _______|_____ | + | | S | + | | | | + | | VP | + | | _____|____ | + NP | | NP | + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + >>> tree = TetraTaggingTree.binarize(tree, left=False, implicit=True) + >>> tree.pretty_print() + TOP + | + S + ____________|______ + | + | ______|___________ + | VP | + | _______|______ | + | | S::VP | + | | ______|_____ | + NP NP + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + >>> TetraTaggingTree.tree2action(tree) + (['l/NP', 'l/', 'l/', 'r/NP', 'r/'], ['L/S', 'L/VP', 'R/S::VP', 'R/']) + """ + + def traverse(tree: nltk.Tree, left: bool = True) -> List: + if len(tree) == 1 and not isinstance(tree[0], nltk.Tree): + return ['l' if left else 'r'], [] + if len(tree) == 1 and not isinstance(tree[0][0], nltk.Tree): + return [f"{'l' if left else 'r'}/{tree.label()}"], [] + return tuple(sum(i, []) for i in zip(*[traverse(tree[0]), + ([], [f'{("L" if left else "R")}/{tree.label()}']), + traverse(tree[1], False)])) + return traverse(tree[0]) + + @classmethod + def action2tree( + cls, + tree: nltk.Tree, + actions: Tuple[Sequence, Sequence], + mark: Union[str, Tuple[str]] = ('*', '|<>'), + join: str = '::', + ) -> nltk.Tree: + r""" + Recovers a constituency tree from tetra-tagging actions. + + Args: + tree (nltk.tree.Tree): + An empty tree that provides a base for building a result tree. + actions (Tuple[Sequence, Sequence]): + Tetra-tagging actions. + mark (Union[str, List[str]]): + A string used to mark newly inserted nodes. Non-terminals containing this will be removed. + Default: ``('*', '|<>')``. + join (str): + A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains. + Default: ``'::'``. + + Returns: + A result constituency tree. + + Examples: + >>> from supar.models.const.tt.transform import TetraTaggingTree + >>> tree = TetraTaggingTree.totree(['She', 'enjoys', 'playing', 'tennis', '.'], 'TOP') + >>> actions = (['l/NP', 'l/', 'l/', 'r/NP', 'r/'], ['L/S', 'L/VP', 'R/S::VP', 'R/']) + >>> TetraTaggingTree.action2tree(tree, actions).pretty_print() + TOP + | + S + ____________|________________ + | VP | + | _______|_____ | + | | S | + | | | | + | | VP | + | | _____|____ | + NP | | NP | + | | | | | + _ _ _ _ _ + | | | | | + She enjoys playing tennis . + + """ + + stack = [] + leaves = [nltk.Tree(pos, [token]) for token, pos in tree.pos()] + for i, (al, an) in enumerate(zip(*actions)): + leaf = nltk.Tree(al.split('/', 1)[1], [leaves[i]]) + if al.startswith('l'): + stack.append([leaf, None]) + else: + slot = stack[-1][1] + slot.append(leaf) + if an.startswith('L'): + node = nltk.Tree(an.split('/', 1)[1], [stack[-1][0]]) + stack[-1][0] = node + else: + node = nltk.Tree(an.split('/', 1)[1], [stack.pop()[0]]) + slot = stack[-1][1] + slot.append(node) + stack[-1][1] = node + # the last leaf must be leftward + leaf = nltk.Tree(actions[0][-1].split('/', 1)[1], [leaves[-1]]) + if len(stack) > 0: + stack[-1][1].append(leaf) + else: + stack.append([leaf, None]) + + def debinarize(tree): + if len(tree) == 1 and not isinstance(tree[0], nltk.Tree): + return [tree] + label, children = tree.label(), [] + for child in tree: + children.extend(debinarize(child)) + if not label or label.endswith(mark): + return children + labels = label.split(join) if join in label else [label] + tree = nltk.Tree(labels[-1], children) + for label in reversed(labels[:-1]): + tree = nltk.Tree(label, [tree]) + return [tree] + return debinarize(nltk.Tree(tree.label(), [stack[0][0]]))[0] + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ) -> List[TetraTaggingTreeSentence]: + r""" + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + + Returns: + A list of :class:`TetraTaggingTreeSentence` instances. + """ + + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + if data.endswith('.txt'): + data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1) + else: + data = open(data) + else: + if lang is not None: + data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + + index = 0 + for s in data: + try: + tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root) + sentence = TetraTaggingTreeSentence(self, tree, index) + except ValueError: + logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!") + continue + else: + yield sentence + index += 1 + self.root = tree.label() + + +class TetraTaggingTreeSentence(Sentence): + r""" + Args: + transform (TetraTaggingTree): + A :class:`TetraTaggingTree` object. + tree (nltk.tree.Tree): + A :class:`nltk.tree.Tree` object. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + """ + + def __init__( + self, + transform: TetraTaggingTree, + tree: nltk.Tree, + index: Optional[int] = None + ) -> TetraTaggingTreeSentence: + super().__init__(transform, index) + + words, tags = zip(*tree.pos()) + leaves, nodes = None, None + if transform.training: + oracle_tree = tree.copy(True) + # the root node must have a unary chain + if len(oracle_tree) > 1: + oracle_tree[:] = [nltk.Tree('*', oracle_tree)] + oracle_tree = TetraTaggingTree.binarize(oracle_tree, left=False, implicit=True) + if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree): + oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]]) + leaves, nodes = transform.tree2action(oracle_tree) + self.values = [words, tags, tree, leaves, nodes] + + def __repr__(self): + return self.values[-3].pformat(1000000) + + def pretty_print(self): + self.values[-3].pretty_print() diff --git a/tania_scripts/supar/models/const/vi/__init__.py b/tania_scripts/supar/models/const/vi/__init__.py new file mode 100644 index 0000000..db91608 --- /dev/null +++ b/tania_scripts/supar/models/const/vi/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import VIConstituencyModel +from .parser import VIConstituencyParser + +__all__ = ['VIConstituencyModel', 'VIConstituencyParser'] diff --git a/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..061ba0053d502449b355ff1e49fecf53cd5b85e9 GIT binary patch literal 284 zcmd1j<>g{vU|`_PGe}>;z`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$ zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9W!eO4y`FX`9nI)yEdC8T&`6;P6nvAzZ zP=x~$i;7c=ia_=hF*7hQ_-V4<V$B7q1&iHcD}X2f$=za)k5A0WiH~2&P{hu_03m+a z>1X8Urs|g@mSiU8CF&*RB&KAh7U^f^B^M+X=@*xRNU(v$`pF>o=$B>c$H!;pWtPOp f>lIYq;;_lhPbtkwwF9}kn2mvffrp8Qk%tKY(bPy| literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5780eac044e7f23e6effee39efea6913adc7c972 GIT binary patch literal 362 zcmZ3^%ge>Uz`&q%Uo~S10|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w}ityo%8dGOEODJQ}dE5ee+XNb2J%miJ%Gx zBo-B?78NlwFfbIcFfcIqX|mp8%>}6ii``-?fG7aT-C~cAPt3`Qk6+2~8RW8Gq52v5 zxvBaki6xndd5L;SIf*HmsYUw9`MCx8x+SR<CAz6)i8=ZuiFuic@x{qSnFS@q`o*OM ziADNgD~k1#K`zuU%hZpL&&<m#iI3MSsQkrYlbfGXnv-f*#Ld9K0P;?;6$1mq2WCb_ n#t&=^jOrH{)R55)28|1-=mEFF1tp6MT$T;&AXvo7z`y_i$h>9M literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74c5b353f48c7a6aaa1d1f8944496ff7070b89ec GIT binary patch literal 10359 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 B)gAx< literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef42262709e0f807a94447a265c803f5688b9c97 GIT binary patch literal 13244 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6aec5892d74be8c41b6e936b63abef924b1a5841 GIT binary patch literal 4769 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 RCJrVZCLTrv<X{qE1^|nnV%Pux literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2279ac265980ece4415c326074e52e8ec8ef509 GIT binary patch literal 8761 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 Q+TbHt>I;~}R0a+q0Hd?)Gynhq literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/const/vi/model.py b/tania_scripts/supar/models/const/vi/model.py new file mode 100644 index 0000000..c44daac --- /dev/null +++ b/tania_scripts/supar/models/const/vi/model.py @@ -0,0 +1,237 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.models.const.crf.model import CRFConstituencyModel +from supar.modules import MLP, Biaffine, Triaffine +from supar.structs import ConstituencyCRF, ConstituencyLBP, ConstituencyMFVI +from supar.utils import Config + + +class VIConstituencyModel(CRFConstituencyModel): + r""" + The implementation of Constituency Parser using variational inference. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_span_mlp (int): + Span MLP size. Default: 500. + n_pair_mlp (int): + Binary factor MLP size. Default: 100. + n_label_mlp (int): + Label MLP size. Default: 100. + mlp_dropout (float): + The dropout ratio of MLP layers. Default: .33. + inference (str): + Approximate inference methods. Default: ``mfvi``. + max_iter (int): + Max iteration times for inference. Default: 3. + interpolation (int): + Constant to even out the label/edge loss. Default: .1. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, True), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_span_mlp=500, + n_pair_mlp=100, + n_label_mlp=100, + mlp_dropout=.33, + inference='mfvi', + max_iter=3, + interpolation=0.1, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.span_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout) + self.span_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout) + self.pair_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=mlp_dropout) + self.pair_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=mlp_dropout) + self.pair_mlp_b = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=mlp_dropout) + self.label_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout) + self.label_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout) + + self.span_attn = Biaffine(n_in=n_span_mlp, bias_x=True, bias_y=False) + self.pair_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=False) + self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True) + self.inference = (ConstituencyMFVI if inference == 'mfvi' else ConstituencyLBP)(max_iter) + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words, feats): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + + Returns: + ~torch.Tensor, ~torch.Tensor, ~torch.Tensor: + Scores of all possible constituents (``[batch_size, seq_len, seq_len]``), + second-order triples (``[batch_size, seq_len, seq_len, n_labels]``) and + all possible labels on each constituent (``[batch_size, seq_len, seq_len, n_labels]``). + """ + + x = self.encode(words, feats) + + x_f, x_b = x.chunk(2, -1) + x = torch.cat((x_f[:, :-1], x_b[:, 1:]), -1) + + span_l = self.span_mlp_l(x) + span_r = self.span_mlp_r(x) + pair_l = self.pair_mlp_l(x) + pair_r = self.pair_mlp_r(x) + pair_b = self.pair_mlp_b(x) + label_l = self.label_mlp_l(x) + label_r = self.label_mlp_r(x) + + # [batch_size, seq_len, seq_len] + s_span = self.span_attn(span_l, span_r) + s_pair = self.pair_attn(pair_l, pair_r, pair_b).permute(0, 3, 1, 2) + # [batch_size, seq_len, seq_len, n_labels] + s_label = self.label_attn(label_l, label_r).permute(0, 2, 3, 1) + + return s_span, s_pair, s_label + + def loss(self, s_span, s_pair, s_label, charts, mask): + r""" + Args: + s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all constituents. + s_pair (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of second-order triples. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all constituent labels. + charts (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + The tensor of gold-standard labels. Positions without labels are filled with -1. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The training loss and marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + span_mask = charts.ge(0) & mask + span_loss, span_probs = self.inference((s_span, s_pair), mask, span_mask) + label_loss = self.criterion(s_label[span_mask], charts[span_mask]) + loss = self.args.interpolation * label_loss + (1 - self.args.interpolation) * span_loss + + return loss, span_probs + + def decode(self, s_span, s_label, mask): + r""" + Args: + s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all constituents. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all constituent labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + List[List[Tuple]]: + Sequences of factorized labeled trees. + """ + + span_preds = ConstituencyCRF(s_span, mask[:, 0].sum(-1)).argmax + label_preds = s_label.argmax(-1).tolist() + return [[(i, j, labels[i][j]) for i, j in spans] for spans, labels in zip(span_preds, label_preds)] diff --git a/tania_scripts/supar/models/const/vi/parser.py b/tania_scripts/supar/models/const/vi/parser.py new file mode 100644 index 0000000..5721a9d --- /dev/null +++ b/tania_scripts/supar/models/const/vi/parser.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- + +from typing import Dict, Iterable, Set, Union + +import torch + +from supar.models.const.crf.parser import CRFConstituencyParser +from supar.models.const.crf.transform import Tree +from supar.models.const.vi.model import VIConstituencyModel +from supar.utils import Config +from supar.utils.logging import get_logger +from supar.utils.metric import SpanMetric +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class VIConstituencyParser(CRFConstituencyParser): + r""" + The implementation of Constituency Parser using variational inference. + """ + + NAME = 'vi-constituency' + MODEL = VIConstituencyModel + + def train( + self, + train, + dev, + test, + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, workers: int = 0, amp: bool = False, cache: bool = False, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}, + equal: Dict = {'ADVP': 'PRT'}, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, *feats, _, charts = batch + mask = batch.mask[:, 1:] + mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1) + s_span, s_pair, s_label = self.model(words, feats) + loss, _ = self.model.loss(s_span, s_pair, s_label, charts, mask) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> SpanMetric: + words, *feats, trees, charts = batch + mask = batch.mask[:, 1:] + mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1) + s_span, s_pair, s_label = self.model(words, feats) + loss, s_span = self.model.loss(s_span, s_pair, s_label, charts, mask) + chart_preds = self.model.decode(s_span, s_label, mask) + preds = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart]) + for tree, chart in zip(trees, chart_preds)] + return SpanMetric(loss, + [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in preds], + [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in trees]) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats, trees = batch + mask, lens = batch.mask[:, 1:], batch.lens - 2 + mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1) + s_span, s_pair, s_label = self.model(words, feats) + s_span = self.model.inference((s_span, s_pair), mask) + chart_preds = self.model.decode(s_span, s_label, mask) + batch.trees = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart]) + for tree, chart in zip(trees, chart_preds)] + if self.args.prob: + batch.probs = [prob[:i-1, 1:i].cpu() for i, prob in zip(lens, s_span)] + return batch diff --git a/tania_scripts/supar/models/dep/__init__.py b/tania_scripts/supar/models/dep/__init__.py new file mode 100644 index 0000000..aad5357 --- /dev/null +++ b/tania_scripts/supar/models/dep/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +from .biaffine import BiaffineDependencyModel, BiaffineDependencyParser +from .crf import CRFDependencyModel, CRFDependencyParser +from .crf2o import CRF2oDependencyModel, CRF2oDependencyParser +from .vi import VIDependencyModel, VIDependencyParser +from .sl import SLDependencyModel, SLDependencyParser +from .eager import ArcEagerDependencyModel, ArcEagerDependencyParser + +__all__ = ['BiaffineDependencyModel', 'BiaffineDependencyParser', + 'CRFDependencyModel', 'CRFDependencyParser', + 'CRF2oDependencyModel', 'CRF2oDependencyParser', + 'VIDependencyModel', 'VIDependencyParser', + 'SLDependencyModel', 'SLDependencyParser', + 'ArcEagerDependencyModel', 'ArcEagerDependencyParser'] diff --git a/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7861152ee2c2a8276035f9246170cd9dc9cc615c GIT binary patch literal 723 zcmd1j<>g{vU|`^9UzGlyiGkrUh=Yuo7#J8F7#J9ea~K#HQW#Pga~N_NqZo6UqL>&# ze5M@cT$U)7T-GR7FrPVxEtfrtJ(nYj1I%a1;mqZV;>zWY;s*0sb9i!jqj+=qqWHjk zwjBOkfhd7o!6-pShIED$_C<_QLMa@<44RxT85tNDG?{LRJ7p%OrDf)&x}+AQ=B1?O zC0F|9r=;fGlE9P*NGvK&Ez)GVCFC6BhOS;1MGUS~#5u^#C?8$1D4Hl-xnP(lx>_M* zA%wzU9}I=aLU4uRjz!6?iRr0D=*lH9C7_ykia-%l#LU3JP{aZvSV06Eh+qd193X-d zM1Z2Vh#SP>0TH|m3=Dpn!nZh*pn-}o=oWKwQ5wRuDAwenG^6|?xS_Y0$})@K2H#>T z&MAT$ev35~<bfi%9k<xy;}dgo;^S8`6p4T=1`)rU^fU5vQ}s&{OEMGl67`aD5>ql$ zi}aK8a|`ly(+f&;b3qZSUtC&{SfmeT7we~_7U;*vXXa&=#K-FuRNmsS$<0qG%}KQb TC68i01_lNJCILnm<Y58;EAhg| literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e046f387fd327180d2c8a0e599fbf49639f9884c GIT binary patch literal 902 zcmZ3^%ge>Uz`&q%Up3=B69dCz5C?{tpp4IX3=9m@8B!Qh7;_kM8KW3;nWC5&L42kh z=3JI2mR!~-RxqDAhb@;qianPjiUZ7N$>Gf9isH)Uj^YOMS#x-Dd82r9`J(v1e6}3^ zT!AQoT)`+oMuv2T6!t}oQ9>yk!3>(5FBusa7&Mt~i92N`rln=(rMjdRq~@ih<|SA9 z=BK3Q+>*eQ2uLg{PA$@8x+UZs<c6+Z7)1=ORKz*R%_tvTu_&4-T)AMFC%Rf8WFdsY zU>^*H$U<<1;*Lehu8HZXMd->UFeRXxc#4=A7#NCJKm;p@U;`2CAc6x#aDoU>ycThT zSUezt7ew$eFfjOO3g6;Lf(9zWpj*tzMQKHF({8aQ7o{2H7r_m^#Z;DA1UL8=Q*jQ$ z@LQ~@AP*G5?YPArAD@_$6Cb~l;WH=^{R+^}$j?pHFG(!POw3EvOUg-1$xJQMPtMOR z$k#1Nttin=ElbSNFG<YHOpGs1F3Kz@Db_D8El4cV&jrPHv3^Qwfqr~^W?p7Ve7s&k z<u4AK-29Z%oK(9aNd^W6P+}?Gz`(%pftit!@dFzJqX**!26s$!gTdkgHgto*?gBP+ jgTeFyHiTQ;<pKj1^nrzy+llc51A=T|2f-q71_lNI{1pWG literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__init__.py b/tania_scripts/supar/models/dep/biaffine/__init__.py new file mode 100644 index 0000000..d757c65 --- /dev/null +++ b/tania_scripts/supar/models/dep/biaffine/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import BiaffineDependencyModel +from .parser import BiaffineDependencyParser + +__all__ = ['BiaffineDependencyModel', 'BiaffineDependencyParser'] diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a03c15f409c6cb82e0c38e8de1c728163143075d GIT binary patch literal 305 zcmd1j<>g{vU|`^9UzEOufq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$#GNt|)6z2YQe9FDQu9($^O7rl^HWlD zG#PJ6U`hof78R!!6@lz4VrF1q@Y7_y#hMFJ4;H({Rsc}|lDowoAD@_$6Cb~lp@^M< z0Yd!p*3Zb#P1P?+EXhpFOVmrsNleL1Ez(cU&n?K;O)n_X1)HW{Tw0J=qz`5n>!+j^ s=qEv)sUIJonU`4-AFo$Xd5gm)H$SB`C)Ez*nPN5u1_mA`9!4G}0KsxlF8}}l literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6cc85e00431ce55159ade848598530026f4c870f GIT binary patch literal 374 zcmZ3^%ge>Uz`&q%Uo~S30|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#x5S+?6VuW%^HN<>3sUn^QuC54ee+XNb2J%m zNnlC^Bo-B?78NlwFfbIcFfcIqX|mp8%>}6ki``-?fG7aT-C~cAPt3`Qk6+2~8RWuW zk@^|=xvBaki6xndd5L;SIf*HmsYUw9`MCx8x+SR<CAz6)i8=ZuiFuic@x{qSnFS@q z`o*OMiADNgD~k0~QVaBxpzhU=kI&4@EQycTE2#X%VUwGmQks)$SH#W0zyR`Eu@wUY s!v|(YM#c|p42;?r7_^Yl4F;VHsOSN=$^|ut3tWy3>>yag$-uw>067+FcmMzZ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c463ffc47a61e67f929c1d390efdc163db1ecc9 GIT binary patch literal 10021 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 ISCt~n0A#*l(EtDd literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec57b786c69963f7b6418e915051312869bea45f GIT binary patch literal 12885 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a161c0ca80e6f499166fc7e4f195252909a9dc8 GIT binary patch literal 8024 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41daea0ef2c2181fcba2b5fbf9a540eded84891b GIT binary patch literal 14692 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 O2$uN*CNWikV*&uma3O2} literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a172f6c96a8bba92e2b94ef264d11b820f66f204 GIT binary patch literal 16984 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b880c597dadc460d71c38295eb68e34d01977a2 GIT binary patch literal 24798 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 P@ewTZ1x#Y90*5UC3;Bf3 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/biaffine/model.py b/tania_scripts/supar/models/dep/biaffine/model.py new file mode 100644 index 0000000..14420cb --- /dev/null +++ b/tania_scripts/supar/models/dep/biaffine/model.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.model import Model +from supar.models.dep.biaffine.transform import CoNLL +from supar.modules import MLP, Biaffine +from supar.structs import DependencyCRF, MatrixTree +from supar.utils import Config +from supar.utils.common import MIN + + +class BiaffineDependencyModel(Model): + r""" + The implementation of Biaffine Dependency Parser :cite:`dozat-etal-2017-biaffine`. + + Args: + n_words (int): + The size of the word vocabulary. + n_rels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_arc_mlp (int): + Arc MLP size. Default: 500. + n_rel_mlp (int): + Label MLP size. Default: 100. + mlp_dropout (float): + The dropout ratio of MLP layers. Default: .33. + scale (float): + Scaling factor for affine scores. Default: 0. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_rels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['tag', 'char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_arc_mlp=500, + n_rel_mlp=100, + mlp_dropout=.33, + scale=0, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.arc_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout) + self.arc_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout) + self.rel_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout) + self.rel_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout) + + self.arc_attn = Biaffine(n_in=n_arc_mlp, scale=scale, bias_x=True, bias_y=False) + self.rel_attn = Biaffine(n_in=n_rel_mlp, n_out=n_rels, bias_x=True, bias_y=True) + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first tensor of shape ``[batch_size, seq_len, seq_len]`` holds scores of all possible arcs. + The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds + scores of all possible labels on each arc. + """ + + x = self.encode(words, feats) + mask = words.ne(self.args.pad_index) if len(words.shape) < 3 else words.ne(self.args.pad_index).any(-1) + + arc_d = self.arc_mlp_d(x) + arc_h = self.arc_mlp_h(x) + rel_d = self.rel_mlp_d(x) + rel_h = self.rel_mlp_h(x) + + # [batch_size, seq_len, seq_len] + s_arc = self.arc_attn(arc_d, arc_h).masked_fill_(~mask.unsqueeze(1), MIN) + # [batch_size, seq_len, seq_len, n_rels] + s_rel = self.rel_attn(rel_d, rel_h).permute(0, 2, 3, 1) + + return s_arc, s_rel + + def loss(self, s_arc, s_rel, arcs, rels, mask, partial=False): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + arcs (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard arcs. + rels (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + partial (bool): + ``True`` denotes the trees are partially annotated. Default: ``False``. + + Returns: + ~torch.Tensor: + The training loss. + """ + + if partial: + mask = mask & arcs.ge(0) + s_arc, arcs = s_arc[mask], arcs[mask] + s_rel, rels = s_rel[mask], rels[mask] + s_rel = s_rel[torch.arange(len(arcs)), arcs] + arc_loss = self.criterion(s_arc, arcs) + rel_loss = self.criterion(s_rel, rels) + + return arc_loss + rel_loss + + def decode(self, s_arc, s_rel, mask, tree=False, proj=False): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + tree (bool): + If ``True``, ensures to output well-formed trees. Default: ``False``. + proj (bool): + If ``True``, ensures to output projective trees. Default: ``False``. + + Returns: + ~torch.LongTensor, ~torch.LongTensor: + Predicted arcs and labels of shape ``[batch_size, seq_len]``. + """ + + lens = mask.sum(1) + arc_preds = s_arc.argmax(-1) + bad = [not CoNLL.istree(seq[1:i+1], proj) for i, seq in zip(lens.tolist(), arc_preds.tolist())] + if tree and any(bad): + arc_preds[bad] = (DependencyCRF if proj else MatrixTree)(s_arc[bad], mask[bad].sum(-1)).argmax + rel_preds = s_rel.argmax(-1).gather(-1, arc_preds.unsqueeze(-1)).squeeze(-1) + + return arc_preds, rel_preds diff --git a/tania_scripts/supar/models/dep/biaffine/parser.py b/tania_scripts/supar/models/dep/biaffine/parser.py new file mode 100644 index 0000000..d7b3093 --- /dev/null +++ b/tania_scripts/supar/models/dep/biaffine/parser.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Iterable, Union + +import torch + +from supar.models.dep.biaffine.model import BiaffineDependencyModel +from supar.models.dep.biaffine.transform import CoNLL +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, PAD, UNK +from supar.utils.field import Field, RawField, SubwordField +from supar.utils.fn import ispunct +from supar.utils.logging import get_logger +from supar.utils.metric import AttachmentMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class BiaffineDependencyParser(Parser): + r""" + The implementation of Biaffine Dependency Parser :cite:`dozat-etal-2017-biaffine`. + """ + + NAME = 'biaffine-dependency' + MODEL = BiaffineDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TAG = self.transform.CPOS + self.ARC, self.REL = self.transform.HEAD, self.transform.DEPREL + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + tree: bool = False, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + tree: bool = True, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + tree: bool = True, + proj: bool = False, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, _, *feats, arcs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_rel = self.model(words, feats) + loss = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.partial) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> AttachmentMetric: + words, _, *feats, arcs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_rel = self.model(words, feats) + loss = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.partial) + arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj) + if self.args.partial: + mask &= arcs.ge(0) + # ignore all punctuation if not specified + if not self.args.punct: + mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words])) + return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, _, *feats = batch + mask, lens = batch.mask, (batch.lens - 1).tolist() + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_rel = self.model(words, feats) + arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj) + batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)] + batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)] + if self.args.prob: + batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, s_arc.softmax(-1).unbind())] + return batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. + Required if taking words as encoder input. + Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR, ELMO, BERT = None, None, None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True) + if 'tag' in args.feat: + TAG = Field('tags', bos=BOS) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len) + if 'elmo' in args.feat: + from allennlp.modules.elmo import batch_to_ids + ELMO = RawField('elmo') + ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device) + if 'bert' in args.feat: + t = TransformerTokenizer(args.bert) + BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t) + BERT.vocab = t.vocab + TEXT = RawField('texts') + ARC = Field('arcs', bos=BOS, use_vocab=False, fn=CoNLL.get_arcs) + REL = Field('rels', bos=BOS) + transform = CoNLL(FORM=(WORD, TEXT, CHAR, ELMO, BERT), CPOS=TAG, HEAD=ARC, DEPREL=REL) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if TAG is not None: + TAG.build(train) + if CHAR is not None: + CHAR.build(train) + REL.build(train) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_rels': len(REL.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'bert_pad_index': BERT.pad_index if BERT is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/dep/biaffine/transform.py b/tania_scripts/supar/models/dep/biaffine/transform.py new file mode 100644 index 0000000..073572b --- /dev/null +++ b/tania_scripts/supar/models/dep/biaffine/transform.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from io import StringIO +from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union + +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence, Transform + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class CoNLL(Transform): + r""" + A :class:`CoNLL` object holds ten fields required for CoNLL-X data format :cite:`buchholz-marsi-2006-conll`. + Each field can be bound to one or more :class:`~supar.utils.field.Field` objects. + For example, ``FORM`` can contain both :class:`~supar.utils.field.Field` and :class:`~supar.utils.field.SubwordField` + to produce tensors for words and subwords. + + Attributes: + ID: + Token counter, starting at 1. + FORM: + Words in the sentence. + LEMMA: + Lemmas or stems (depending on the particular treebank) of words, or underscores if not available. + CPOS: + Coarse-grained part-of-speech tags, where the tagset depends on the treebank. + POS: + Fine-grained part-of-speech tags, where the tagset depends on the treebank. + FEATS: + Unordered set of syntactic and/or morphological features (depending on the particular treebank), + or underscores if not available. + HEAD: + Heads of the tokens, which are either values of ID or zeros. + DEPREL: + Dependency relations to the HEAD. + PHEAD: + Projective heads of tokens, which are either values of ID or zeros, or underscores if not available. + PDEPREL: + Dependency relations to the PHEAD, or underscores if not available. + """ + + fields = ['ID', 'FORM', 'LEMMA', 'CPOS', 'POS', 'FEATS', 'HEAD', 'DEPREL', 'PHEAD', 'PDEPREL'] + + def __init__( + self, + ID: Optional[Union[Field, Iterable[Field]]] = None, + FORM: Optional[Union[Field, Iterable[Field]]] = None, + LEMMA: Optional[Union[Field, Iterable[Field]]] = None, + CPOS: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + FEATS: Optional[Union[Field, Iterable[Field]]] = None, + HEAD: Optional[Union[Field, Iterable[Field]]] = None, + DEPREL: Optional[Union[Field, Iterable[Field]]] = None, + PHEAD: Optional[Union[Field, Iterable[Field]]] = None, + PDEPREL: Optional[Union[Field, Iterable[Field]]] = None + ) -> CoNLL: + super().__init__() + + self.ID = ID + self.FORM = FORM + self.LEMMA = LEMMA + self.CPOS = CPOS + self.POS = POS + self.FEATS = FEATS + self.HEAD = HEAD + self.DEPREL = DEPREL + self.PHEAD = PHEAD + self.PDEPREL = PDEPREL + + @property + def src(self): + return self.FORM, self.LEMMA, self.CPOS, self.POS, self.FEATS + + @property + def tgt(self): + return self.HEAD, self.DEPREL, self.PHEAD, self.PDEPREL + + @classmethod + def get_arcs(cls, sequence, placeholder='_'): + return [-1 if i == placeholder else int(i) for i in sequence] + + @classmethod + def get_sibs(cls, sequence, placeholder='_'): + sibs = [[0] * (len(sequence) + 1) for _ in range(len(sequence) + 1)] + heads = [0] + [-1 if i == placeholder else int(i) for i in sequence] + + for i, hi in enumerate(heads[1:], 1): + for j, hj in enumerate(heads[i + 1:], i + 1): + di, dj = hi - i, hj - j + if hi >= 0 and hj >= 0 and hi == hj and di * dj > 0: + if abs(di) > abs(dj): + sibs[i][hi] = j + else: + sibs[j][hj] = i + break + return sibs[1:] + + @classmethod + def get_edges(cls, sequence): + edges = [[0] * (len(sequence) + 1) for _ in range(len(sequence) + 1)] + for i, s in enumerate(sequence, 1): + if s != '_': + for pair in s.split('|'): + edges[i][int(pair.split(':')[0])] = 1 + return edges + + @classmethod + def get_labels(cls, sequence): + labels = [[None] * (len(sequence) + 1) for _ in range(len(sequence) + 1)] + for i, s in enumerate(sequence, 1): + if s != '_': + for pair in s.split('|'): + edge, label = pair.split(':', 1) + labels[i][int(edge)] = label + return labels + + @classmethod + def build_relations(cls, chart): + sequence = ['_'] * len(chart) + for i, row in enumerate(chart): + pairs = [(j, label) for j, label in enumerate(row) if label is not None] + if len(pairs) > 0: + sequence[i] = '|'.join(f"{head}:{label}" for head, label in pairs) + return sequence + + @classmethod + def toconll(cls, tokens: List[Union[str, Tuple]]) -> str: + r""" + Converts a list of tokens to a string in CoNLL-X format with missing fields filled with underscores. + + Args: + tokens (List[Union[str, Tuple]]): + This can be either a list of words, word/pos pairs or word/lemma/pos triples. + + Returns: + A string in CoNLL-X format. + + Examples: + >>> print(CoNLL.toconll(['She', 'enjoys', 'playing', 'tennis', '.'])) + 1 She _ _ _ _ _ _ _ _ + 2 enjoys _ _ _ _ _ _ _ _ + 3 playing _ _ _ _ _ _ _ _ + 4 tennis _ _ _ _ _ _ _ _ + 5 . _ _ _ _ _ _ _ _ + + >>> print(CoNLL.toconll([('She', 'she', 'PRP'), + ('enjoys', 'enjoy', 'VBZ'), + ('playing', 'play', 'VBG'), + ('tennis', 'tennis', 'NN'), + ('.', '_', '.')])) + 1 She she PRP _ _ _ _ _ _ + 2 enjoys enjoy VBZ _ _ _ _ _ _ + 3 playing play VBG _ _ _ _ _ _ + 4 tennis tennis NN _ _ _ _ _ _ + 5 . _ . _ _ _ _ _ _ + + """ + + if isinstance(tokens[0], str): + s = '\n'.join([f"{i}\t{word}\t" + '\t'.join(['_'] * 8) + for i, word in enumerate(tokens, 1)]) + elif len(tokens[0]) == 2: + s = '\n'.join([f"{i}\t{word}\t_\t{tag}\t" + '\t'.join(['_'] * 6) + for i, (word, tag) in enumerate(tokens, 1)]) + elif len(tokens[0]) == 3: + s = '\n'.join([f"{i}\t{word}\t{lemma}\t{tag}\t" + '\t'.join(['_'] * 6) + for i, (word, lemma, tag) in enumerate(tokens, 1)]) + else: + raise RuntimeError(f"Invalid sequence {tokens}. Only list of str or list of word/pos/lemma tuples are support.") + return s + '\n' + + @classmethod + def isprojective(cls, sequence: List[int]) -> bool: + r""" + Checks if a dependency tree is projective. + This also works for partial annotation. + + Besides the obvious crossing arcs, the examples below illustrate two non-projective cases + which are hard to detect in the scenario of partial annotation. + + Args: + sequence (List[int]): + A list of head indices. + + Returns: + ``True`` if the tree is projective, ``False`` otherwise. + + Examples: + >>> CoNLL.isprojective([2, -1, 1]) # -1 denotes un-annotated cases + False + >>> CoNLL.isprojective([3, -1, 2]) + False + """ + + pairs = [(h, d) for d, h in enumerate(sequence, 1) if h >= 0] + for i, (hi, di) in enumerate(pairs): + for hj, dj in pairs[i + 1:]: + (li, ri), (lj, rj) = sorted([hi, di]), sorted([hj, dj]) + if li <= hj <= ri and hi == dj: + return False + if lj <= hi <= rj and hj == di: + return False + if (li < lj < ri or li < rj < ri) and (li - lj) * (ri - rj) > 0: + return False + return True + + @classmethod + def istree(cls, sequence: List[int], proj: bool = False, multiroot: bool = False) -> bool: + r""" + Checks if the arcs form an valid dependency tree. + + Args: + sequence (List[int]): + A list of head indices. + proj (bool): + If ``True``, requires the tree to be projective. Default: ``False``. + multiroot (bool): + If ``False``, requires the tree to contain only a single root. Default: ``True``. + + Returns: + ``True`` if the arcs form an valid tree, ``False`` otherwise. + + Examples: + >>> CoNLL.istree([3, 0, 0, 3], multiroot=True) + True + >>> CoNLL.istree([3, 0, 0, 3], proj=True) + False + """ + + from supar.structs.fn import tarjan + if proj and not cls.isprojective(sequence): + return False + n_roots = sum(head == 0 for head in sequence) + if n_roots == 0: + return False + if not multiroot and n_roots > 1: + return False + if any(i == head for i, head in enumerate(sequence, 1)): + return False + return next(tarjan(sequence), None) is None + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + proj: bool = False, + **kwargs + ) -> Iterable[CoNLLSentence]: + r""" + Loads the data in CoNLL-X format. + Also supports for loading data from CoNLL-U file with comments and non-integer IDs. + + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + proj (bool): + If ``True``, discards all non-projective sentences. Default: ``False``. + + Returns: + A list of :class:`CoNLLSentence` instances. + """ + + isconll = False + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + f = open(data) + if data.endswith('.txt'): + lines = (i + for s in f + if len(s) > 1 + for i in StringIO(self.toconll(s.split() if lang is None else tokenizer(s)) + '\n')) + else: + lines, isconll = f, True + else: + if lang is not None: + data = [tokenizer(s) for s in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + lines = (i for s in data for i in StringIO(self.toconll(s) + '\n')) + + index, sentence = 0, [] + for line in lines: + line = line.strip() + if len(line) == 0: + sentence = CoNLLSentence(self, sentence, index) + if isconll and self.training and proj and not self.isprojective(list(map(int, sentence.arcs))): + logger.warning(f"Sentence {index} is not projective. Discarding it!") + else: + yield sentence + index += 1 + sentence = [] + else: + sentence.append(line) + + +class CoNLLSentence(Sentence): + r""" + Sencence in CoNLL-X format. + + Args: + transform (CoNLL): + A :class:`~supar.utils.transform.CoNLL` object. + lines (List[str]): + A list of strings composing a sentence in CoNLL-X format. + Comments and non-integer IDs are permitted. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + + Examples: + >>> lines = ['# text = But I found the location wonderful and the neighbors very kind.', + '1\tBut\t_\t_\t_\t_\t_\t_\t_\t_', + '2\tI\t_\t_\t_\t_\t_\t_\t_\t_', + '3\tfound\t_\t_\t_\t_\t_\t_\t_\t_', + '4\tthe\t_\t_\t_\t_\t_\t_\t_\t_', + '5\tlocation\t_\t_\t_\t_\t_\t_\t_\t_', + '6\twonderful\t_\t_\t_\t_\t_\t_\t_\t_', + '7\tand\t_\t_\t_\t_\t_\t_\t_\t_', + '7.1\tfound\t_\t_\t_\t_\t_\t_\t_\t_', + '8\tthe\t_\t_\t_\t_\t_\t_\t_\t_', + '9\tneighbors\t_\t_\t_\t_\t_\t_\t_\t_', + '10\tvery\t_\t_\t_\t_\t_\t_\t_\t_', + '11\tkind\t_\t_\t_\t_\t_\t_\t_\t_', + '12\t.\t_\t_\t_\t_\t_\t_\t_\t_'] + >>> sentence = CoNLLSentence(transform, lines) # fields in transform are built from ptb. + >>> sentence.arcs = [3, 3, 0, 5, 6, 3, 6, 9, 11, 11, 6, 3] + >>> sentence.rels = ['cc', 'nsubj', 'root', 'det', 'nsubj', 'xcomp', + 'cc', 'det', 'dep', 'advmod', 'conj', 'punct'] + >>> sentence + # text = But I found the location wonderful and the neighbors very kind. + 1 But _ _ _ _ 3 cc _ _ + 2 I _ _ _ _ 3 nsubj _ _ + 3 found _ _ _ _ 0 root _ _ + 4 the _ _ _ _ 5 det _ _ + 5 location _ _ _ _ 6 nsubj _ _ + 6 wonderful _ _ _ _ 3 xcomp _ _ + 7 and _ _ _ _ 6 cc _ _ + 7.1 found _ _ _ _ _ _ _ _ + 8 the _ _ _ _ 9 det _ _ + 9 neighbors _ _ _ _ 11 dep _ _ + 10 very _ _ _ _ 11 advmod _ _ + 11 kind _ _ _ _ 6 conj _ _ + 12 . _ _ _ _ 3 punct _ _ + """ + + def __init__(self, transform: CoNLL, lines: List[str], index: Optional[int] = None) -> CoNLLSentence: + super().__init__(transform, index) + + self.values = [] + # record annotations for post-recovery + self.annotations = dict() + + for i, line in enumerate(lines): + value = line.split('\t') + if value[0].startswith('#') or not value[0].isdigit(): + self.annotations[-i - 1] = line + else: + self.annotations[len(self.values)] = line + self.values.append(value) + self.values = list(zip(*self.values)) + + def __repr__(self): + # cover the raw lines + merged = {**self.annotations, + **{i: '\t'.join(map(str, line)) + for i, line in enumerate(zip(*self.values))}} + return '\n'.join(merged.values()) + '\n' diff --git a/tania_scripts/supar/models/dep/crf/__init__.py b/tania_scripts/supar/models/dep/crf/__init__.py new file mode 100644 index 0000000..27cae45 --- /dev/null +++ b/tania_scripts/supar/models/dep/crf/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import CRFDependencyModel +from .parser import CRFDependencyParser + +__all__ = ['CRFDependencyModel', 'CRFDependencyParser'] diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5810074dccba6a92cf481e86ef69ece8be74592c GIT binary patch literal 290 zcmd1j<>g{vU|`^9UzEOpfq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$gq(xiTv7{C^HNgtk}G}lQ&Mv@8E*-r zhz2AU6{i*zfov&aW?*3O(`3EHnhR127Q4k(08s#vyTu+KpO}*qAHR~Jh@F7}Li}>m z&&bbB)h|gb$xO^k)Jw`qOvy|w(ofFMEy&kRFDTIko2Fk}T98<z4`vtZr=%9>Cl{sZ n$H!;pWtPOp>lIYq;;_lhPbtkwwF9}nn2mvffrp8Qk%tKY171m? literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3609fddab845fa29cbbf98125bf4f14117dacd7c GIT binary patch literal 359 zcmZ3^%ge>Uz`&q%Uo~R^0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w}hO7++0!%Qu9($^O7rl^HWlDG#PIRqlgA1 z78R!!6)`g~Fch&cFfjOOvfg6N1t|rK-C`?%C;-XbVvmnc%*lz5U&-(p<gQ;K`WgAT zsrn^}C7FqNiF!#ni7A<>Mf%D4xdr*UC8-r9x~XM}Ir=4ud6|jv#mPmP1trD$#ia#_ zMfzYXiuF@c3-ptV()8owGxIV_;^XxSDt~d<<mRW8=A_ycaWgP5fc#Qy#lXPuftit! n@dFzJquK=qRb+I7LHz<MdcZAzLDB32mw5v_2o`ZNFfafBeO_ab literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..350a941b0ad158a2c7ec7f74b109e4200050bd1e GIT binary patch literal 6656 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82c5f8a1f3181f461f6d3f7c6d863af8093a12ca GIT binary patch literal 7412 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 E0H`}!!T<mO literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0a41a163099e2b9eb112143902fdc323def85a0 GIT binary patch literal 4987 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b93724d0f7d60bbc3af66307c55579f66b3ed2c5 GIT binary patch literal 8854 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 Uz)oI}GWrOX`T`~~m4QPG0BKj>M*si- literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf/model.py b/tania_scripts/supar/models/dep/crf/model.py new file mode 100644 index 0000000..472bd35 --- /dev/null +++ b/tania_scripts/supar/models/dep/crf/model.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- + +import torch +from supar.models.dep.biaffine.model import BiaffineDependencyModel +from supar.structs import DependencyCRF, MatrixTree + + +class CRFDependencyModel(BiaffineDependencyModel): + r""" + The implementation of first-order CRF Dependency Parser + :cite:`zhang-etal-2020-efficient,ma-hovy-2017-neural,koo-etal-2007-structured`). + + Args: + n_words (int): + The size of the word vocabulary. + n_rels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_arc_mlp (int): + Arc MLP size. Default: 500. + n_rel_mlp (int): + Label MLP size. Default: 100. + mlp_dropout (float): + The dropout ratio of MLP layers. Default: .33. + scale (float): + Scaling factor for affine scores. Default: 0. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + proj (bool): + If ``True``, takes :class:`DependencyCRF` as inference layer, :class:`MatrixTree` otherwise. + Default: ``True``. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def loss(self, s_arc, s_rel, arcs, rels, mask, mbr=True, partial=False): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + arcs (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard arcs. + rels (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + mbr (bool): + If ``True``, returns marginals for MBR decoding. Default: ``True``. + partial (bool): + ``True`` denotes the trees are partially annotated. Default: ``False``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The training loss and + original arc scores of shape ``[batch_size, seq_len, seq_len]`` if ``mbr=False``, or marginals otherwise. + """ + + CRF = DependencyCRF if self.args.proj else MatrixTree + arc_dist = CRF(s_arc, mask.sum(-1)) + arc_loss = -arc_dist.log_prob(arcs, partial=partial).sum() / mask.sum() + arc_probs = arc_dist.marginals if mbr else s_arc + # -1 denotes un-annotated arcs + if partial: + mask = mask & arcs.ge(0) + s_rel, rels = s_rel[mask], rels[mask] + s_rel = s_rel[torch.arange(len(rels)), arcs[mask]] + rel_loss = self.criterion(s_rel, rels) + loss = arc_loss + rel_loss + return loss, arc_probs diff --git a/tania_scripts/supar/models/dep/crf/parser.py b/tania_scripts/supar/models/dep/crf/parser.py new file mode 100644 index 0000000..2ed1689 --- /dev/null +++ b/tania_scripts/supar/models/dep/crf/parser.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- + +from typing import Iterable, Union + +import torch + +from supar.models.dep.biaffine.parser import BiaffineDependencyParser +from supar.models.dep.crf.model import CRFDependencyModel +from supar.structs import DependencyCRF, MatrixTree +from supar.utils import Config +from supar.utils.fn import ispunct +from supar.utils.logging import get_logger +from supar.utils.metric import AttachmentMetric +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class CRFDependencyParser(BiaffineDependencyParser): + r""" + The implementation of first-order CRF Dependency Parser :cite:`zhang-etal-2020-efficient`. + """ + + NAME = 'crf-dependency' + MODEL = CRFDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + mbr: bool = True, + tree: bool = False, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + mbr: bool = True, + tree: bool = True, + proj: bool = True, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + mbr: bool = True, + tree: bool = True, + proj: bool = True, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, _, *feats, arcs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_rel = self.model(words, feats) + loss, s_arc = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.mbr, self.args.partial) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> AttachmentMetric: + words, _, *feats, arcs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_rel = self.model(words, feats) + loss, s_arc = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.mbr, self.args.partial) + arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj) + if self.args.partial: + mask &= arcs.ge(0) + # ignore all punctuation if not specified + if not self.args.punct: + mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words])) + return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + CRF = DependencyCRF if self.args.proj else MatrixTree + words, _, *feats = batch + mask, lens = batch.mask, batch.lens - 1 + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_rel = self.model(words, feats) + s_arc = CRF(s_arc, lens).marginals if self.args.mbr else s_arc + arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj) + lens = lens.tolist() + batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)] + batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)] + if self.args.prob: + arc_probs = s_arc if self.args.mbr else s_arc.softmax(-1) + batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, arc_probs.unbind())] + return batch diff --git a/tania_scripts/supar/models/dep/crf2o/__init__.py b/tania_scripts/supar/models/dep/crf2o/__init__.py new file mode 100644 index 0000000..d2acf9c --- /dev/null +++ b/tania_scripts/supar/models/dep/crf2o/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import CRF2oDependencyModel +from .parser import CRF2oDependencyParser + +__all__ = ['CRF2oDependencyModel', 'CRF2oDependencyParser'] diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb6754d2364431258038d51a7d60f97240ef9d09 GIT binary patch literal 296 zcmd1j<>g{vU|`^9UzEOrfq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$M4W@%jPhMl3sUn^QuC54ee+XNb2J%m ziK2-IBo-B?78QYPDq?0}VDQsqy~UafQVbTm#Z~}O0Ft}K9v`2WlM^4mlA(y5fdNAN z^3c!7&rQ`YNi4}s%uCcu%1KPgOfAw+&d)8#*G(@d(FL2PUtC&{SfmeT7we~_7U(Az rr5WYx$H!;pWtPOp>lIYq;;_lhPbtkwwFCK~n2mvffrp8Qk%tKY+LKF? literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4cf033823fb198f1abbc2c5fe24ab7427a6e3819 GIT binary patch literal 365 zcmZ3^%ge>Uz`&q%Uo~R|0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w?v$S+>G*FQVUY^Qd0AhD}D1*QgbvJZ;7Ib z2P761rxq14GcYg|u`n<&_-V4<V$B6928-QdD}X2f$=za)k5A0WiH~2&@EPQ`Ut#(g z`MIh3C5a`OiFt{7NjZrrnW;tk$@#ej`MM>k6(zc<Wr;cZC5d^NiSfnBMVSR9#rnmi z1&KxaU@MCCQ&J1`lZ(=f^7Z56GxIV_;^XxSDt~d<<mRW8=A_ycaWgP5fP7SJ#lXPu rftit!@dFzJqs9dWb!2pdLGuDCdcduCLD}j8mvsX>2o`ZNFfafB@r-4q literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6243392a5a1c5d884a93eb8cd18fbcf1edad6ec4 GIT binary patch literal 11378 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 E0ROS|?*IS* literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7586c6f2981ac0dc9e8dbe7252d6f9ed741d5805 GIT binary patch literal 15100 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cf299268ee7bd3bd211e8bd3d917638bd104180 GIT binary patch literal 8249 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec22eb9df296b742697cdd799d431ff90162da41 GIT binary patch literal 15194 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/crf2o/model.py b/tania_scripts/supar/models/dep/crf2o/model.py new file mode 100644 index 0000000..1b53bdd --- /dev/null +++ b/tania_scripts/supar/models/dep/crf2o/model.py @@ -0,0 +1,263 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.models.dep.biaffine.model import BiaffineDependencyModel +from supar.models.dep.biaffine.transform import CoNLL +from supar.modules import MLP, Biaffine, Triaffine +from supar.structs import Dependency2oCRF, MatrixTree +from supar.utils import Config +from supar.utils.common import MIN + + +class CRF2oDependencyModel(BiaffineDependencyModel): + r""" + The implementation of second-order CRF Dependency Parser :cite:`zhang-etal-2020-efficient`. + + Args: + n_words (int): + The size of the word vocabulary. + n_rels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_arc_mlp (int): + Arc MLP size. Default: 500. + n_sib_mlp (int): + Sibling MLP size. Default: 100. + n_rel_mlp (int): + Label MLP size. Default: 100. + mlp_dropout (float): + The dropout ratio of MLP layers. Default: .33. + scale (float): + Scaling factor for affine scores. Default: 0. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_rels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_arc_mlp=500, + n_sib_mlp=100, + n_rel_mlp=100, + mlp_dropout=.33, + scale=0, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.arc_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout) + self.arc_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout) + self.sib_mlp_s = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout) + self.sib_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout) + self.sib_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout) + self.rel_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout) + self.rel_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout) + + self.arc_attn = Biaffine(n_in=n_arc_mlp, scale=scale, bias_x=True, bias_y=False) + self.sib_attn = Triaffine(n_in=n_sib_mlp, scale=scale, bias_x=True, bias_y=True) + self.rel_attn = Biaffine(n_in=n_rel_mlp, n_out=n_rels, bias_x=True, bias_y=True) + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor, ~torch.Tensor: + Scores of all possible arcs (``[batch_size, seq_len, seq_len]``), + dependent-head-sibling triples (``[batch_size, seq_len, seq_len, seq_len]``) and + all possible labels on each arc (``[batch_size, seq_len, seq_len, n_labels]``). + """ + + x = self.encode(words, feats) + mask = words.ne(self.args.pad_index) if len(words.shape) < 3 else words.ne(self.args.pad_index).any(-1) + + arc_d = self.arc_mlp_d(x) + arc_h = self.arc_mlp_h(x) + sib_s = self.sib_mlp_s(x) + sib_d = self.sib_mlp_d(x) + sib_h = self.sib_mlp_h(x) + rel_d = self.rel_mlp_d(x) + rel_h = self.rel_mlp_h(x) + + # [batch_size, seq_len, seq_len] + s_arc = self.arc_attn(arc_d, arc_h).masked_fill_(~mask.unsqueeze(1), MIN) + # [batch_size, seq_len, seq_len, seq_len] + s_sib = self.sib_attn(sib_s, sib_d, sib_h).permute(0, 3, 1, 2) + # [batch_size, seq_len, seq_len, n_rels] + s_rel = self.rel_attn(rel_d, rel_h).permute(0, 2, 3, 1) + + return s_arc, s_sib, s_rel + + def loss(self, s_arc, s_sib, s_rel, arcs, sibs, rels, mask, mbr=True, partial=False): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of all possible dependent-head-sibling triples. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + arcs (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard arcs. + sibs (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + The tensor of gold-standard siblings. + rels (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + mbr (bool): + If ``True``, returns marginals for MBR decoding. Default: ``True``. + partial (bool): + ``True`` denotes the trees are partially annotated. Default: ``False``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The training loss and + original arc scores of shape ``[batch_size, seq_len, seq_len]`` if ``mbr=False``, or marginals otherwise. + """ + + arc_dist = Dependency2oCRF((s_arc, s_sib), mask.sum(-1)) + arc_loss = -arc_dist.log_prob((arcs, sibs), partial=partial).sum() / mask.sum() + if mbr: + s_arc, s_sib = arc_dist.marginals + # -1 denotes un-annotated arcs + if partial: + mask = mask & arcs.ge(0) + s_rel, rels = s_rel[mask], rels[mask] + s_rel = s_rel[torch.arange(len(rels)), arcs[mask]] + rel_loss = self.criterion(s_rel, rels) + loss = arc_loss + rel_loss + return loss, s_arc, s_sib + + def decode(self, s_arc, s_sib, s_rel, mask, tree=False, mbr=True, proj=False): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of all possible dependent-head-sibling triples. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + tree (bool): + If ``True``, ensures to output well-formed trees. Default: ``False``. + mbr (bool): + If ``True``, performs MBR decoding. Default: ``True``. + proj (bool): + If ``True``, ensures to output projective trees. Default: ``False``. + + Returns: + ~torch.LongTensor, ~torch.LongTensor: + Predicted arcs and labels of shape ``[batch_size, seq_len]``. + """ + + lens = mask.sum(1) + arc_preds = s_arc.argmax(-1) + bad = [not CoNLL.istree(seq[1:i+1], proj) for i, seq in zip(lens.tolist(), arc_preds.tolist())] + if tree and any(bad): + if proj: + arc_preds[bad] = Dependency2oCRF((s_arc[bad], s_sib[bad]), mask[bad].sum(-1)).argmax + else: + arc_preds[bad] = MatrixTree(s_arc[bad], mask[bad].sum(-1)).argmax + rel_preds = s_rel.argmax(-1).gather(-1, arc_preds.unsqueeze(-1)).squeeze(-1) + + return arc_preds, rel_preds diff --git a/tania_scripts/supar/models/dep/crf2o/parser.py b/tania_scripts/supar/models/dep/crf2o/parser.py new file mode 100644 index 0000000..c822b2a --- /dev/null +++ b/tania_scripts/supar/models/dep/crf2o/parser.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Iterable, Union + +import torch + +from supar.models.dep.biaffine.parser import BiaffineDependencyParser +from supar.models.dep.biaffine.transform import CoNLL +from supar.models.dep.crf2o.model import CRF2oDependencyModel +from supar.structs import Dependency2oCRF +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, PAD, UNK +from supar.utils.field import ChartField, Field, RawField, SubwordField +from supar.utils.fn import ispunct +from supar.utils.logging import get_logger +from supar.utils.metric import AttachmentMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class CRF2oDependencyParser(BiaffineDependencyParser): + r""" + The implementation of second-order CRF Dependency Parser :cite:`zhang-etal-2020-efficient`. + """ + + NAME = 'crf2o-dependency' + MODEL = CRF2oDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + mbr: bool = True, + tree: bool = False, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + mbr: bool = True, + tree: bool = True, + proj: bool = True, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + mbr: bool = True, + tree: bool = True, + proj: bool = True, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, _, *feats, arcs, sibs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_sib, s_rel = self.model(words, feats) + loss, *_ = self.model.loss(s_arc, s_sib, s_rel, arcs, sibs, rels, mask, self.args.mbr, self.args.partial) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> AttachmentMetric: + words, _, *feats, arcs, sibs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_sib, s_rel = self.model(words, feats) + loss, s_arc, s_sib = self.model.loss(s_arc, s_sib, s_rel, arcs, sibs, rels, mask, self.args.mbr, self.args.partial) + arc_preds, rel_preds = self.model.decode(s_arc, s_sib, s_rel, mask, self.args.tree, self.args.mbr, self.args.proj) + if self.args.partial: + mask &= arcs.ge(0) + # ignore all punctuation if not specified + if not self.args.punct: + mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words])) + return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, _, *feats = batch + mask, lens = batch.mask, batch.lens - 1 + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_sib, s_rel = self.model(words, feats) + s_arc, s_sib = Dependency2oCRF((s_arc, s_sib), lens).marginals if self.args.mbr else (s_arc, s_sib) + arc_preds, rel_preds = self.model.decode(s_arc, s_sib, s_rel, mask, self.args.tree, self.args.mbr, self.args.proj) + lens = lens.tolist() + batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)] + batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)] + if self.args.prob: + arc_probs = s_arc if self.args.mbr else s_arc.softmax(-1) + batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, arc_probs.unbind())] + return batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default: 2. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + TAG, CHAR, ELMO, BERT = None, None, None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True) + if 'tag' in args.feat: + TAG = Field('tags', bos=BOS) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len) + if 'elmo' in args.feat: + from allennlp.modules.elmo import batch_to_ids + ELMO = RawField('elmo') + ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device) + if 'bert' in args.feat: + t = TransformerTokenizer(args.bert) + BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t) + BERT.vocab = t.vocab + TEXT = RawField('texts') + ARC = Field('arcs', bos=BOS, use_vocab=False, fn=CoNLL.get_arcs) + SIB = ChartField('sibs', bos=BOS, use_vocab=False, fn=CoNLL.get_sibs) + REL = Field('rels', bos=BOS) + transform = CoNLL(FORM=(WORD, TEXT, CHAR, ELMO, BERT), CPOS=TAG, HEAD=(ARC, SIB), DEPREL=REL) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if TAG is not None: + TAG.build(train) + if CHAR is not None: + CHAR.build(train) + REL.build(train) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_rels': len(REL.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'bert_pad_index': BERT.pad_index if BERT is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/dep/eager/__init__.py b/tania_scripts/supar/models/dep/eager/__init__.py new file mode 100644 index 0000000..c3e9859 --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/__init__.py @@ -0,0 +1,2 @@ +from .parser import ArcEagerDependencyParser +from .model import ArcEagerDependencyModel \ No newline at end of file diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69b6b347907cd94bda81a4738bf8e7e85860c421 GIT binary patch literal 273 zcmd1j<>g{vU|`^9Uz8rsz`*br#6iYP3=9ko3=9m#G7Jn1DGVu$ISjdsQH+crHd78$ zE^`z!BSQ*vFoPz`OGX9;22I9W5{^a5u8HZXMJ}lYsd*`>dC8RliABY!MVgGa#4+W3 z^HWlD{4`l^u@!(-6@je0#hMEeE@Eb2U|7je#Kyn?A%1!2XXNLm>X#&zWG3b%>LukQ zrevlT=_lvs7Ub)u7nJCN_30Ov79<wwgW1LUDX9hesUQdG$H!;pWtPOp>lIYq;;_lh VPbtkwwF5c3n1z9XfrmkW5db~bNI3ui literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4eb2047d9191fa7725d4f6c991fbd42ac25afea GIT binary patch literal 333 zcmZ3^%ge>Uz`&q%Uo|6~fq~&Mhy%k+P{wCD1_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9 zGb2L^b1;J@%S%QE1_n*WTM~{%$*zg%sYNcS1*v%{sd>qj0f|M$sYRNMx5P2!eDhOM zbNn<}Zm|`BRTVKaFfiO=%>@Y;u`n<&tYr8Ma>lPP{fzwFRQ-~~lFY=sM7^Y(#FWg` zBK_q2+=6`FlGKV4-PE$g9Q~5Syv)S-;^d;tf|6qW;?jb|B7Lx7#ri3!1^THVm+8mH zXXa&=#K-FuRQ}?y$<0qG%}KQ@0tE!f6UF)r3=AKb85tRGFz8%BMK>6<E?`4N91IK$ E0J_UxVgLXD literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c35f8752a167848718305af293b7ba376172b991 GIT binary patch literal 6877 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd043bef1f8af3f5ca69f649ed48a44101524e37 GIT binary patch literal 11595 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 FPXNKi27dqm literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f44d08db4b5106cd902edd53576ffd54fc22572 GIT binary patch literal 14058 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c53842f2152b6d56e2c6e8626ae48e37586c53a4 GIT binary patch literal 29283 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35d39d5378eae49dfe2f72c59831aec35703b2ca GIT binary patch literal 7792 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 R3?mOCq*Wxq%up}F3;;PSl=J`q literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbdee27774e2be073b02a1de3f1e5540e6c700cf GIT binary patch literal 13871 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/model.py b/tania_scripts/supar/models/dep/eager/model.py new file mode 100644 index 0000000..300e829 --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/model.py @@ -0,0 +1,198 @@ +import torch +import torch.nn as nn +from supar.model import Model +from supar.modules import MLP, DecoderLSTM +from supar.utils import Config +from typing import Tuple, List + +class ArcEagerDependencyModel(Model): + + def __init__(self, + n_words, + n_transitions, + n_trels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_arc_mlp=500, + n_rel_mlp=100, + mlp_dropout=.33, + scale=0, + pad_index=0, + unk_index=1, + n_decoder_layers=4, + **kwargs): + super().__init__(**Config().update(locals())) + + # create decoder for buffer front, stack top and rels + self.transition_decoder = self.rel_decoder = None, None + + stack_size, buffer_size = [self.args.n_encoder_hidden//2] * 2 if (self.args.n_encoder_hidden % 2) == 0 \ + else [self.args.n_encoder_hidden//2, self.args.n_encoder_hidden//2+1] + + # create projection to reduce dimensionality of the encoder + self.stack_proj = MLP( + n_in=self.args.n_encoder_hidden, n_out=stack_size, + dropout=mlp_dropout) + self.buffer_proj = MLP( + n_in=self.args.n_encoder_hidden, n_out=buffer_size, + dropout=mlp_dropout + ) + + if self.args.decoder == 'lstm': + decoder = lambda out_dim: DecoderLSTM( + self.args.n_encoder_hidden, self.args.n_encoder_hidden, out_dim, + self.args.n_decoder_layers, dropout=mlp_dropout, device=self.device + ) + else: + decoder = lambda out_dim: MLP( + n_in=self.args.n_encoder_hidden, n_out=out_dim, dropout=mlp_dropout + ) + + self.transition_decoder = decoder(n_transitions) + self.trel_decoder = decoder(n_trels) + + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay + 1), + n_out=self.args.n_encoder_hidden, dropout=mlp_dropout) + + # create PoS tagger + if self.args.encoder in ['lstm', 'bert']: + self.pos_tagger = DecoderLSTM( + self.args.n_encoder_hidden, self.args.n_encoder_hidden, self.args.n_tags, + num_layers=1, dropout=mlp_dropout, device=self.device + ) + else: + #args.encoder is bert + self.pos_tagger = nn.Identity() + + self.criterion = nn.CrossEntropyLoss() + + def encoder_forward(self, words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]: + """ + Applies encoding forward pass. Maps a tensor of word indices (`words`) to their corresponding neural + representation. + Args: + words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay] + feats: List[torch.Tensor] + lens: List[int] + + Returns: x, qloss + x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + qloss: torch.FloatTensor ~ 1 + + """ + + x = super().encode(words, feats) + s_tag = self.pos_tagger(x[:, 1:-(1+self.args.delay), :]) + + # adjust lengths to allow delay predictions + # x ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + if self.args.delay != 0: + x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay + 1)], dim=2) + x = self.delay_proj(x) + + # pass through vector quantization + x, qloss = self.vq_forward(x) + return x, s_tag, qloss + + def decoder_forward(self, x: torch.Tensor, stack_top: torch.Tensor, buffer_front: torch.Tensor) -> Tuple[torch.Tensor]: + """ + Args: + x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim] + stack_top: torch.IntTensor ~ [batch_size, pad(tr_len)] + buffer_front: torch.IntTensor ~ [batch_size, pad(tr_len)] + + Returns: s_transition, s_trel + s_transition: torch.FloatTensor ~ [batch_size, pad(tr_len), n_transitions] + s_trel: torch.FloatTensor ~ [batch_size, pad(tr_len), n_trels] + """ + batch_size = x.shape[0] + + # obtain encoded embeddings for stack_top and buffer_front + stack_top = torch.stack([x[i, stack_top[i], :] for i in range(batch_size)]) + buffer_front = torch.stack([x[i, buffer_front[i], :] for i in range(batch_size)]) + + # pass through projections + stack_top = self.stack_proj(stack_top) + buffer_front = self.buffer_proj(buffer_front) + + # stack_top ~ [batch_size, pad(tr_len), embed_dim//2] + # buffer_front ~ [batch_size, pad(tr_len), embed_dim//2] + # x ~ [batch_size, pad(tr_len), embed_dim] + x = torch.concat([stack_top, buffer_front], dim=-1) + + # s_transition ~ [batch_size, pad(tr_len), n_transitions] + # s_trel = [batch_size, pad(tr_len), n_trels] + s_transition = self.transition_decoder(x) + s_trel = self.trel_decoder(x) + + return s_transition, s_trel + + def forward(self, words: torch.Tensor, stack_top: torch.Tensor, buffer_front: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]: + """ + Args: + words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay]. + stack_top: torch.IntTensor ~ [batch_size, pad(tr_len)] + buffer_front: torch.IntTensor ~ [batch_size, pad(tr_len)] + feats: List[torch.Tensor] + + Returns: s_transition, s_trel, qloss + s_transition: torch.FloatTensor ~ [batch_size, pad(tr_len), n_transitions] + s_trel: torch.FloatTensor ~ [batch_size, pad(tr_len), n_trels] + qloss: torch.FloatTensor ~ 1 + """ + x, s_tag, qloss = self.encoder_forward(words, feats) + + s_transition, s_trel = self.decoder_forward(x, stack_top, buffer_front) + return s_transition, s_trel, s_tag, qloss + + def decode(self, s_transition: torch.Tensor, s_trel: torch.Tensor, exclude: list = None): + transition_preds = s_transition.argsort(-1, descending=True) + if exclude: + s_trel[:, :, exclude] = -1 + trel_preds = s_trel.argmax(-1) + return transition_preds, trel_preds + + def decode_stag(self, s_tag: torch.Tensor): + stag_preds = s_tag.argmax(-1) + #stag_preds = s_tag.argsort(-1, descending=True) + return stag_preds + + def loss(self, s_transition: torch.Tensor, s_trel: torch.Tensor, s_tag, + transitions: torch.Tensor, trels: torch.Tensor, tags, + smask: torch.Tensor, trmask: torch.Tensor, TRANSITION): + s_transition, transitions = s_transition[trmask], transitions[trmask] + s_trel, trels = s_trel[trmask], trels[trmask] + + # remove those values in trels that correspond to shift and reduce actions + transition_pred = TRANSITION.vocab[s_transition.argmax(-1).flatten().tolist()] + trel_mask = torch.tensor(list(map(lambda x: x not in ['reduce', 'shift'], transition_pred))) + s_trel, trels = s_trel[trel_mask], trels[trel_mask] + + tag_loss = self.criterion(s_tag[smask], tags[smask]) if self.args.encoder == 'lstm' else torch.tensor(0).to(self.device) + transition_loss = self.criterion(s_transition, transitions) + trel_loss = self.criterion(s_trel, trels) + + return transition_loss + trel_loss + tag_loss diff --git a/tania_scripts/supar/models/dep/eager/oracle/__init__.py b/tania_scripts/supar/models/dep/eager/oracle/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cf072a90eda87b6f954a0a161965c253cafd1b1 GIT binary patch literal 172 zcmd1j<>g{vU|`^9Uz84_AA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_`Rixo z=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>!uf!=;r39q~_=smlh-z>4VwD`YEXe`l*TO tsYUwvMTyBdsrvEpnR%Hd@$q^EmA5!-a`RJ4b5iX<78NrwFfgz%002-#DbxS} literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13ce2553293d74a70524325df69e92ffe8f7771d GIT binary patch literal 202 zcmZ3^%ge>Uz`&q%Uo`_nKL!yn%m`(CW@BJrn9h*G5X_*-=(m!gh>3xL;WJ3`SFC<U zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB zL1K}9ZhlH?PO*MUYJq-gVtQ(ketuD6a!#s#e0*kJW=VX!UP0wA4x8Nkl+v73yCPNw b1_qFOiuoBB7(OsFGBSQ(fDuK^3=9kajjc5m literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93488668e82fa23ba9e3ff1768cb420f90132ce3 GIT binary patch literal 7330 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 Q0rN0GhL{8x`Iv;_0n}~H=>Px# literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09ee22f8790adc5bbc67d6acfbc51c23685850e4 GIT binary patch literal 15872 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 FP5^kB=zstK literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41d88bf55396dcd614cb06abfdcd6cdd80a64562 GIT binary patch literal 1286 zcmd1j<>g{vU|`^9Uz9G-#K7<v#6iZ)3=9ko3=9m#dJGH<DGVu$ISjdsQH;4vQA~^= zK2r{JE=v>(BZE6b3Udle3quM^GgB063TrTfCfiGpNt#TzIQ$DrGV}8ib8fNtWEPib zGTvhG%TGy721z4h7MNu*3=9mZ3{i|J3{gxejH%42EUB!L43Z3KOest$%q=WYY$+_M ztZ7UstSM|QEK%%G9(xK$3riG73MW{OD}}p-C5khJCxy3#A&M)7FNME_A&NUiAecc@ z@D`g>X<Axp(Jj`@lGNPdWF{ncfY>1H4Dz=G0|P@1V-b4|V+}(*LkdGMLplSDwUW_q zC1VjA0|SF5(=C?b)SNUhXC*@sC{Ta->SyHVrs|g@mSiU8CF&*RB&KAh7U?JF=N9Da zrWcgx=H{oQ=I9rf79<wwgW1LUDX9hesfp>SMf&+giOD&s`bl7C>J?Pp;)svW%*!l^ zk7otB3uG$`BNrnVQx!kND|#^bTWm$CC8b4q$&5&z0<qzq0y(dSA&Vh}QIa8;VI`Aa z5lFg-gMoozC1VjM0|UedU~d$0GcYjRVopyj0Wm&<%-~|I;)2?lo?3!o4Jgfk!;S|O zb_`hz3m8)v7cvGj6!C$B3LHqcm<#d?iukcu#a5J>n_rd+Qd<nNjfb&{7it?s<`xSm z&M=}3Zmj^^+8V}%jG$y1%uvLRWHno2K|yL>iY61pt0I_=C=z90U=Rd_Gsp!32p2$f zVt5&(3gqR_ppY$LsA0%rYzBE4V(TsDoYXw9ud#ZVJw84sH7`CM><*BnReVtYLM3oo zS0n~<I?R&dk|NxeaKy(Kr4|&$$BTosfNepf8;FdbCJ!i)<t65(#>d~{ijU9DPbtj- zv3cU-3riDoATmWD&lZ6~y9ktFi$Jkl1Pb#aVUW?FkShY^nj$F>7Zf0nbOdIB(ohj7 z0fV#_gW{NjL5z`)jgOg+nS+^!87$|g$##paq_QA0FCAgoEhTV9(Su|Zy_D1fJ#a?R ngJcxFy!@0@h=V}JBUuTz_ZEi@#7B0Z)LsnAK>`dsj6zHRAy@Y> literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c22b12dc825c9a45c4c9b0f8e44b31477268e653 GIT binary patch literal 1846 zcmZ3^%ge>Uz`&q%Uo}IXiGkrUhy%kcP{wB)1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL zb1q913nK#)gF8bCa|=TX%Q7YghSf|^oeWW|DXhT^nrtsY0-8*>IQ$DrGV}8ib8fNt zWEPibGTvhG%TGy721&y(+}b3twW$nIj42FJOeu`1%&9D?tdcNw3<y>lQwmcHOB7oQ zb1G{ZQwmE9OB6el&Dz2e#gW1W7H4l^iQ-J*Xkm!rO5to_h~iG+3TDvczQyKLnwFMY zbc;2!BsI4<8SZ)p1_ltDnSp`fvliGfHH<}^HH<Y3@o-0^Fa$HCGoXvCWb|9fSj54= zz@W)=i={X<Ck@Og1{tTI@GDwBBR@A)za+6FGchkwFDWN6B{Q{1KRG|QAYZp6wW35f zwJb45za%j)Gcmq6xhS)sq*%YWv>>raKQ})mHK$lVCAC05H8DN4NI$<QF*zqyKMCvw zy@JYH9P#m)d6^~g@m2f~f9b&lSQ!`?iWL|b7#bLEa0`53VCIy$At~44(&N?P)#3F( zQX0nm4D#MBwxZOM(xSX%Mi38*K^_2yhYTb<7_y)e3=AoZhzJR0Sjps91X5hY&A`C0 zlCg*fWH-npg(6-C28LVA>8T}ETu=w5r<Q<}74t#d#xLAcHAAtd_5z1Y5kCV11Bwek zwuA6zGYl6j0GSVW4~&t*xQvm3VKrPXn4w4r95LW1xy4+NUr;2B<~p{b)ZF~C)GA)6 z10h_H^NPg~ZtSn?s+*B`kze5ozrqC$1+ZIhv49d0N*V&W7KA@r5$WO@G#7*NS};Qq zD5q*NL0rw2SWu9fm!io84%i|Iko!TwtpEw$A}Iz22Ds}XY6U@R<RGr+;OXJI&LMe; zLvn`7MGpBZ9P$@n2<!{&Ar8p{CGe1BV5nipg7Yv!8RFhs%sHufU`JzwGJAY{PHJ9! zd=(!wn4x?TP=*r#yYw!<&;*kyR-N@d^%pqgsPDGok|OMG<A{$hN-Zct$wd$WaRvs4 zB2YMjUE`<81IlrEiMgrq@wd3*<8$*<N^?MLp7{8}(!?ByOc5vn6oHDiB2X?Y0wtv) zkUxvS#(|=%NET$UA}G5sfQ<%clp=PJD2M=QE?y1}l?Da~{J_M*Dl;QvLCFf2B~@4C zj6N{1u*#qlJdCWe6GA>PFtW;`6KssEiZfV1qKfDQ8zZa23=@#30y@FQ$SMyKgA!<5 z2AC|w4<MKOX|mm7E2%8V%u7dv!!0Fnfu;v3(DYJL3-rJRnjWM;)62_GNri+J$cQ3U zP%wZB18}JP;;?~)vt5w}0|Nsn4HhRdFfe>zW@Kc%!Jv2n8@j<@d;t}GU=d-I|G<Dr Pd<2Po0TF1jU{3)6zrJ=@ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fce37dccace89b6d7436c953040e05640fbe754 GIT binary patch literal 1544 zcmd1j<>g{vU|`^9UzBdk%)sy%#6iZ)3=9ko3=9m#HVh05DGVu$ISjdsQH;4vQA~^= zK2r{JE=v>(BZE6b3Udle3quM^GgB0+J3|U<3R??93R^Q%6k7^=FoPz?OOUymOt(1v z3raHc^AdAzvG`;bmuNEHV)4sQNlgYxBV#t0)kX{q45<uJj42FJOeu`1%qdK%EGf*X zENN^hEGeulEK#f}Y$@z53{h+;94VYF3{mVUT)_;Q+_$(~QVUY^Qd0AhD{t|nK-nen znJKr}Gg1>%Kn%8&)PkbaoMaXxn?Y<Q1_lOakiW$k7#M08YZ&4gYM5#m;u&k0YZ&60 zQW%06Rx<i&G8chdS;Wr3z)-}&z`&r%a*L%nH75;CcqKy-Hv<F1uR#5b{M=OilEjkC z#Johkq@2W*%+w<N<ow)%eBJbd65ZVVl++yk;?jb|B7HEsSU)ATKtDAxJ+(+bzbG*| zClw?B^^{&g<t>i*_{_Y_lK6O5kZVD%VPj-t<YKH6MtEKirY4yY$(tZH+?ycB*Dx$# zSjZ5}P{axH3F9sHlKkZSyquhsj76YC0`>xg;9+230NGrWT2K@p50WefnZ$u^D?}c{ zR*+M{fhz|}RE!H4N*HSxvY46~!8CI-h{ux7ypS=NVI`B_FGfyH)>|xD`I&jQn2Sq_ z(89Ke9~AhY;6=Eth>wARffp7aEQ}(IZ2zl-kOBniGe1oZkT>!Yb5rBvZ*j%P=jNxB z=788d@$rSFi8)Xi=FGg3A`y^1AVZ4;KrE0I5F63#2Kf$@go;67%E2JU$id3PTm%xu zNa7$B;M}E$BZ;T5q%x;*fb$Y4nX{*GfRj0AFoP!7Ev}HF#Ju86P-eQtQc_uvdW*BT zBr!QVz9hfk7Ee-XT3TvRd|FX{UI{pDCWD*+i+>Os6lLIOkYT`<#%ow=7~+{hDIJm^ zSc;@T{+0$2ARS;sHCZ8P1B(<=;DFLg5h&<{L2&}|H7Jonk}1LyxRWU;S%Y1whLT{i zn4w9A1;nah$YQNw$YM)l0VSLwK~N%QF9O*Ji8_$OZ?U-f2l*C(oey?0$Sqh?5Gal% zL9PXbk{V-`Fp4`N3ENMTy+{-k9H2s?NF2lhClXNXgS`t$DTwp|W`P3(WV8^-c#zjP z7^E0^*or`6ewysJ*h(r3GV{`lKsFbF3gBBx;1WR(QX=T3q!#FbO9VYgiJ+I4pORVx jwiFbtU~`ZHA8zR_4jV}NwgY8-aPkyj;9=xr65;~@R5>pn literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9534220075a54bc9b129b311b945ea708d02dc8 GIT binary patch literal 2377 zcmZ3^%ge>Uz`&q%Up2#)nStRkhy%kcP{!vl1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL zb1q913nK#)gF8bCa|=TX%Q7YghSf|^oeWW|U>VjHh7>k58MYMmU<OT&mmsB@Ot(1v z3raHc^AdAzvG`;bmuNEHV)4sQNlgYx!!R3^@mUY-pj3t^#uSDqrWD3h<`kw>mK5ex zmNd2$mKK&M))dwjhA6fawibpcc8Eo{xLi^TQu9($^O7rX@uWc6CGnXlx7agM6H`D8 zwv^O@qSTyZn9o7>f&9YEz`*d?0BmUuV+}(*NF0o7m}(f}8No~j28J5u8isg~daytW zLomZiMn6sFA`S)yh9XW70SatQmRl^vsX1wA!o?s<6%-T{e#Pr&<maa9mn4>CCgvsT zCFLZhWTqDBC+FuD<m;BCR+Q+bmL=xsmn7z8CdL;h7iAWd6zdn479<ww=jNxR<`nCv zq!#F>CZ?wr>E{<ECg-Gr1fX8mE2zB15g(tKmst`YUnPtP6Frz9D+2>Vu?zzPLj%JN z8I2B>D;$zH#N|3zdU$S#$#k&vaCdNbaDN7QF&XZ21_lO@zro?81qmmH1t29Dco_o& z!)mx_Fhda!0|SF5<1O}*{N((+oSc=6MZ6#ffQ(is;$vW706DiPwV(*Yxe!56kQNI- zoXaoVU(;37S=Uo{fkU<kB#7cfQ2GHou?6hJ6h`b$ECH#3I<bZ!3*<2{Zy6&4!)lPb zz&tcna6PE1Y8bLW@e0<F&WtJ-%&?Nl?-wJdChIMhto+QpTg=5JMQEv_NEkIRii8*# z7^;Mjq752u;6Ss62Sa67<y{{B2`pCx6fg29UExt$>b!zw4bMdt(<>^b8%nlRe_&>k z;`+$IB*6UzM0{Xi;^YR0n4cyGD8%y;b5rBvZ*j%P=jNxB=788d@$rSFi8)Xi=FGg3 zB1ur9<_8fXAOhsLl?-5Gz)@Gk4iW_spg<^&20O2T0RlfTF|*1p2>!sp%qqLV7)%{t z22<z+7bC0O2L?F7#>~nMQi4uE>;>6|Qfh#5A1M4k>wse&Td9%4lFFRMk-`ctIY4Cw zv~aq`6;hO#SDXndnQpO^R2HP(;w&ynOwNuk$uGFYlT@0PmRb~_R+OJtQUpqe$)LOg zvI~Sk=?0W4KHGuqCBEROVX0w=2k8Wv!T>5pAen@vND&mAN+3cRM1ZW+WCiCJY*NJ_ z*MLeCNIoh8#Z#3q!bk8N4^Cqs6B`(Ah)8s>^l;vgRO(>q;e+RYM8*dPGWJ}x1nf^z zb5$1Hr>MCDEq{R$5I8(=sjp$k0{IuLriLL4l-I%RG!|5IgBgm%Kt&FFkpw6V!6_IN zq_<ey{DXXpK*0bBOi<`zWIs?cM+-wpF$6NF*a4itZ}1EES9Vp-Ri2SDC+~`!;YBH< zD^f;Vop-QYvGBZN;djx*|B8wKg}~4&fl(J?60XFgUy#hW$e($IKl1`dCOCloG}()! zK+cl}5um~tlGQ*y1jl0$$RR~?AX!i`2gz*;ATEdi<-_6#uwx*3t%2bK6AP>CjNlIp zEUdCCLcr7k5ioV47)+rPJdCVajG$bHjRZTg2xOI?Ci^Y6lFEY2y!0YaOcsG6>Xs6? zI?{twM|vr#1$yA>NDopS>E-38q!xkw0?MsmbI|<qi^B#|?${M+GB7ZJO5Nhg3=9k( zm>C%vZ!jocz=m!x7+*j|A6R%8xj!&q5+6ZgUqA#zR)&KS<WKD6M+T7i7clt&g9L{K E04+P;O#lD@ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d76682cca61dd66a9aa936ace916052a3ae2e0f7 GIT binary patch literal 2800 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a8d46ef4a1c5317321c19f8323f13e6319c4fe0 GIT binary patch literal 5581 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f963a4cfe22b0dc6246066d745d20c9344ac44ed GIT binary patch literal 1180 zcmd1j<>g{vU|`^9UzGlxk%8ech=Yuo85kHG7#J9ejTjghQW#Pga~N_NqZo6UqL^}- zqnH^%VoW(KxvWvFj12A!Da<J>Eet6v%}h~jDXhT^nrtsYrfD+YVhzp9%+I^U;*(ii za*M;ipd>RtFEK}x@fM3;eoAUGNEI?>h1na%z`&5o5XG3n5XF?jpTd;NoXV2QD#;+p zkj4bIjTK~5Dr*{33R?<$3riGx3I~|SnZnh=62+0i3g&UA@U*Z*ai;L5@U<{RaiuT@ zGiVCjVht`yOwRVZ#hO`?np>RAgyaGc8-$%fo|j-?V5ng%Vy|JWVTfl)VF+eOXMnL* zGWxA#EMjM1V9;c`#ZsJ_lLqFjWGLchU|{&=qo0wVo2p-uSdy8Tm#CMNlbDj3TBM(x zpIeZxn_f_&o134KnxkJ_T98<z4`vtZr=%9>rzWPS7U|~~B_`*j>KB8YsaH^Wiz7Zh zGcU6wJ{}Z4#cT`=3@nUXj9g4rd|;pG!K81o6{VJx7Ud-~B6$hK2E`}XOFSSiF=R0; zU`%0L$QaD9lF9Go|NsC0YcheIe~Y;wzhEU}5h!(lJpv&>x{3rD7#O%g!2${&9>yw8 zh}{MG1-Dp00f`Zga7zW?mew#XWCSIiV1^<NaL_?)WlJn5NX<*pWP(^M%)kH%MuhFR zSPDvuGx%WE3our3L9H(>&cN_4$c13<g8Wg#kj0R~D9I4aP{a>1m=i<@fe4UqkgQ-% zPb~p?@-s*~7u<vCsU`R=C}F5!$YN|}gnQ~1OHpb;5!h=**ev3Rj|VA;j~4;CLY#qt z0TGc92}tO0gCagJF*h|n{uWn!d~SY9X%2|Z6CYn#nwSHTDPjQ`0t)LQQ0ge+1#v;% zC=vy+#6W~3h(P!j%mT+LI4OYw6~yCUkYMCv<74Jy=3y=Z$@poq-(oANEXd4DF9L;0 z5!e=xeYcdrDOV4Ya`jSD3-rJ#R}YeM_44vlQX$R(nF9%9u&rPMWZ5ka8;F1GK<N{l LrbQTd7=@Ss0w?KM literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a362f4b907de1716061719405def54b641c7abd GIT binary patch literal 1703 zcmZ3^%ge>Uz`&q%Up3=9BLl-@5C?`?pp4HB3=9m@8B!Qh7;_kM8KW3;nWC6-nWLB) zL1IifEV-;vtc(my4DJjm%q<KlEX$Y}7*;bubu&b<rLYDwXtKQo31~9kVhzp9%+I^U z;*(iia*M;ipd>RtFEK}x@fM3;eoAUGNEHmTLK&aqz%EE-h+<4(h+<0NN?}T6PGw1D zm4qr_U_h|am{OQqSfkidSW;Qjm{M3<Sfbcd*uZS|7M3Uus5nOpOB81cXA46VR|;b= zgC_Sa*5H!F<ZQoNteGXLxy8wF4=^w=fY{6o3=E&Ozz(TlEaI$TtYL_UTc5%Z%#hB2 zF0zu*ZzW?9Cj$e6CetmJ;?$fpFsB$~oPxryDE*B5+*JLN#FEU!yhOdEoWzvO)FS=l z{M>?k-ICOb65Z6Y#2o#S#JtSJ_~PWE%z~0){o>Ms#3KFN{FKz3V*QlV0{zs)^wc8# z{G!C<oK*c{kQej{DsOSb$7kkcmc++b@qxXi2jhdnv{-?GfuVun2DiWm24+r~8<KJz zE<IiyUL9T!B&A`@&mhm;Vk=55DJ{xNW(4t|7!(p9{Mif=8Vp%b2?mA*$m-ytDU8b) z85mZ><$@VjGWosy|NsAgO(t-N++r@sFIdS~#LK|IPz+M0P{hZ;z)&R0z`#(&3GqNd zegQW~S`6ZLe&L>~{<^NZ8A%uU6|e9sUf@tH5@29pxWxjBK9tx4xfO&zTM_Br8Z`HU z5_&L05y*O&gV_=b3R3e@G?~C|E)oa13=*wim)~M3C@s#Y;(|K8v^WFgpJF+P+c|i8 zxUO?ZUgD6Pp>mN!{tAcu1sDSR0VT9Srh;8BgW>uVMntj?W+)N{1sM;B0EH1!INoAT zPc4CkV|r?dAjq{K2Q@I<0EOcWrJlMA9I}{pgX{%iXu2-}MGZ7oYZ$WNJoMOwhSV*V zqSS&Sa0C~jyNDw`9wdpJJ|TP&klTd7;dGZ@c!J9muZ#ThSNK681a=?9Y;I5j&r8fr zjgP;@6(66QpHi9wV)Mku7nUaGKxB$QX}t(kj1{qgLWLhhfRa>^6o>^1&mwsS28NXk z5R*Y6Qp5q00udm6#dE<9X<&fB4@@kqG9MUNSY>8pEGSvwvZU&YoDrChPVg|YDoqIa zz`)3=gif$AvMS6F0f{Q06KssEau8i|ASq-5qzfd5t_R|BkbC_!*>ACxR2F3Br5AzX z4B~N65ZqD%7aDqyLPIYlwLlMCXy`!-4ZXbllvGFvfy^mV28949D}ht;FAf_>=-L&j zF)%QI;=DMWfq~%zGb1D84F-)1xX}#;;|r+h1B)P|!UqOS;v-1x3y46I1^W*GP#|Ra literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/eager/oracle/arceager.py b/tania_scripts/supar/models/dep/eager/oracle/arceager.py new file mode 100644 index 0000000..b65dad1 --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/oracle/arceager.py @@ -0,0 +1,219 @@ +from supar.models.dep.eager.oracle.stack import Stack +from supar.models.dep.eager.oracle.buffer import Buffer +from supar.models.dep.eager.oracle.node import Node +from supar.models.dep.eager.oracle.dependency import Transition +from typing import List, Dict + +class ArcEagerEncoder: + def __init__(self, bos: str, eos: str): + self.stack = None + self.buffer = None + self.transitions = [] + self.dependencies = [] + self.nodes_assigned = [] + self.bos, self.eos = bos, eos + self.shift_token = '<shift>' + self.reduce_token = '<reduce>' + self.n = 0 + + def left_arc(self): + # head = buffer_front, dependent = stack_top (stack_top <- buffer_front) + stack_top = self.stack.pop() + buffer_front = self.buffer.get() + self.transitions.append( + Transition(type='left-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=stack_top.DEPREL) + ) + self.dependencies.append( + Node(ID=stack_top.ID, FORM=stack_top.FORM, UPOS=stack_top.UPOS, HEAD=buffer_front.ID, DEPREL=stack_top.DEPREL) + ) + self.nodes_assigned.append(stack_top.ID) + return self.transitions + + def right_arc(self): + # head = stack_top, dependent = buffer_front (stack_top -> buffer_front) + stack_top = self.stack.get() + buffer_front = self.buffer.remove() + self.stack.push(buffer_front) + self.transitions.append( + Transition(type='right-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=buffer_front.DEPREL) + ) + self.dependencies.append( + Node(ID=buffer_front.ID, FORM=buffer_front.FORM, UPOS=buffer_front.UPOS, HEAD=stack_top.ID, DEPREL=buffer_front.DEPREL) + ) + self.nodes_assigned.append(buffer_front.ID) + return self.transitions + + def shift(self): + front_item = self.buffer.remove() + stack_top = self.stack.get() + self.stack.push(front_item) + self.transitions.append( + Transition(type='shift', stack_top=stack_top, buffer_front=front_item, deprel=front_item.DEPREL)) + return self.transitions + + def reduce(self): + stack_top = self.stack.get() + buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(self.n, self.eos) + self.stack.pop() + self.transitions.append( + Transition(type='reduce', stack_top=stack_top, buffer_front=buffer_front, deprel=stack_top.DEPREL) + ) + return self.transitions + + def next_action(self): + stack_top = self.stack.get() + try: + buffer_front = self.buffer.get() + except IndexError: + if stack_top.ID in self.nodes_assigned: + return self.reduce() + return None + + if buffer_front.ID == stack_top.HEAD: + return self.left_arc() + elif (buffer_front.ID not in self.nodes_assigned) and (stack_top.ID == buffer_front.HEAD): + return self.right_arc() + elif (stack_top.ID in self.nodes_assigned) and (buffer_front.HEAD in [node.ID for node in self.stack.items]): + return self.reduce() + elif (stack_top.ID in self.nodes_assigned) and (buffer_front.ID in [node.HEAD for node in self.stack.items]): + return self.reduce() + else: + return self.shift() + + def encode(self, sentence: List[Node]): + # create stack and buffer + self.stack = Stack([Node.create_root(self.bos)]) + self.buffer = Buffer(sentence.copy()) + self.n = len(sentence) + + # reset + self.transitions, self.dependencies = [], [] + + next_action = self.next_action() + while next_action: + next_action = self.next_action() + + # remove values + self.dependencies = sorted(self.dependencies, key=lambda dep: dep.ID) + return self.transitions + + + +class ArcEagerDecoder: + def __init__(self, sentence: List[Node], bos: str, eos: str, unk: str): + self.sentence = sentence.copy() + self.decoded_nodes = [Node(ID=node.ID, FORM=node.FORM, UPOS=node.UPOS, HEAD=0, DEPREL=unk) for node in sentence] + self.transitions = list() + self.nodes_assigned = list() + self.stack = Stack([Node.create_root(bos)]) + self.buffer = Buffer(sentence.copy()) + self.bos, self.eos, self.unk = bos, eos, unk + self.shift_token, self.reduce_token = '<shift>', '<reduce>' + + + def left_arc(self, deprel: str): + # head = buffer_front, dependent = stack_top (stack_top <- buffer_front) + stack_top = self.stack.pop() + buffer_front = self.buffer.get() + self.nodes_assigned.append(stack_top.ID) + self.transitions.append( + Transition(type='left-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=deprel) + ) + self.decoded_nodes[stack_top.ID - 1].HEAD = buffer_front.ID + self.decoded_nodes[stack_top.ID - 1].DEPREL = deprel + # get next states + stack_top = self.stack.get() + buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos) + return stack_top, buffer_front + + def right_arc(self, deprel: str): + # head = stack_top, dependent = buffer_front (stack_top -> buffer_front) + stack_top = self.stack.get() + buffer_front = self.buffer.remove() + self.stack.push(buffer_front) + self.transitions.append( + Transition(type='right-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=deprel) + ) + self.nodes_assigned.append(buffer_front.ID) + self.decoded_nodes[buffer_front.ID - 1].HEAD = stack_top.ID + self.decoded_nodes[buffer_front.ID - 1].DEPREL = deprel + + # get next states + stack_top = self.stack.get() + buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos) + return stack_top, buffer_front + + + def shift(self, deprel): + front_item = self.buffer.remove() + stack_top = self.stack.get() + self.stack.push(front_item) + self.transitions.append( + Transition(type='shift', stack_top=stack_top, buffer_front=front_item, deprel=deprel)) + # get next states + stack_top = self.stack.get() + buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos) + return stack_top, buffer_front + + def reduce(self, deprel): + stack_top = self.stack.get() + try: + buffer_front = self.buffer.get() + except IndexError: + buffer_front = Node.create_eos(len(self.sentence), self.eos) + self.stack.pop() + self.transitions.append( + Transition(type='reduce', stack_top=stack_top, buffer_front=buffer_front, deprel=deprel) + ) + # get next states + stack_top = self.stack.get() + buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos) + return stack_top, buffer_front + + def apply_transition(self, transitions: List[str], deprel: str): + stack_top = self.stack.get() + try: + buffer_front = self.buffer.get() + except IndexError: + if stack_top.ID in self.nodes_assigned: + self.reduce(deprel) + return None + + for transition in transitions: + if (transition == 'left-arc') and (stack_top.ID not in self.nodes_assigned) and (not stack_top.is_root): + return self.left_arc(deprel) + if (transition == 'right-arc') and (buffer_front.ID not in self.nodes_assigned): + return self.right_arc(deprel) + if (transition == 'reduce') and (stack_top.ID in self.nodes_assigned): + return self.reduce(deprel) + return self.shift(deprel) + + def apply(self, transition: str, deprel: str): + if transition == 'left-arc': + return self.left_arc(deprel) + if transition == 'right-arc': + return self.right_arc(deprel) + if transition == 'reduce': + return self.reduce(deprel) + if transition == 'shift': + return self.shift(deprel) + + def decode_sentence(self, transitions: List[List[str]], deprels: List[str]): + for transition_ops, deprel in zip(transitions, deprels): + info = self.apply_transition(transition_ops, deprel) + if info is None: + break + self.postprocess() + return self.decoded_nodes + + def postprocess(self): + # check if there are more than one node with root head + roots = sum([node.HEAD == 0 for node in self.decoded_nodes]) + if roots > 1: + # get leftmost root + for node in self.decoded_nodes: + if node.HEAD == 0: + root = node.ID + for node in self.decoded_nodes[root:]: + if node.HEAD == 0: + node.HEAD = root diff --git a/tania_scripts/supar/models/dep/eager/oracle/buffer.py b/tania_scripts/supar/models/dep/eager/oracle/buffer.py new file mode 100644 index 0000000..9a1f5d4 --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/oracle/buffer.py @@ -0,0 +1,24 @@ +from typing import Optional, List +from supar.models.dep.eager.oracle.node import Node + +class Buffer: + def __init__(self, items: Optional[List[Node]]): + if items: + self.items = items + else: + self.items = [] + + def get(self) -> Node: + return self.items[0] + + def remove(self) -> Node: + return self.items.pop(0) + + def append(self, item: Node): + self.items.append(item) + + def __len__(self): + return len(self.items) + + def __repr__(self): + return str(self.items) \ No newline at end of file diff --git a/tania_scripts/supar/models/dep/eager/oracle/dependency.py b/tania_scripts/supar/models/dep/eager/oracle/dependency.py new file mode 100644 index 0000000..a4825ba --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/oracle/dependency.py @@ -0,0 +1,30 @@ +from typing import Optional, List +from supar.models.dep.eager.oracle.node import Node + +class Dependency: + def __init__(self, dependent_id: int, head_id: str, deprel: str): + self.dependent_id = dependent_id + self.head_id = head_id + self.deprel = deprel + + def __repr__(self): + return self.toconll() + + def toconll(self): + return '\t'.join([ + str(self.dependent_id), str(self.head_id), self.deprel + ]) + +class Transition: + def __init__(self, type: str, stack_top: Node, buffer_front: Node, deprel: str): + self.type = type + self.stack_top = stack_top + self.buffer_front = buffer_front + self.deprel = deprel + + def __repr__(self): + return '\t'.join((str(self.stack_top.FORM), str(self.buffer_front.FORM), self.type, self.deprel)) + + + + diff --git a/tania_scripts/supar/models/dep/eager/oracle/node.py b/tania_scripts/supar/models/dep/eager/oracle/node.py new file mode 100644 index 0000000..7aa07a9 --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/oracle/node.py @@ -0,0 +1,74 @@ +from typing import List + +class Node: + + def __init__(self, ID: int, FORM: str, UPOS: str, HEAD: int, DEPREL: str, is_root: bool = False): + self.ID = ID + self.FORM = FORM + self.UPOS = UPOS + self.HEAD = HEAD + self.DEPREL = DEPREL + self.is_root = is_root + + def __str__(self): + return f'Node(ID={self.ID}, FORM={self.FORM}, UPOS={self.UPOS}, HEAD={self.HEAD})' + + def __repr__(self): + return f'Node(ID={self.ID}, FORM={self.FORM}, UPOS={self.UPOS}, HEAD={self.HEAD})' + + @classmethod + def from_conllu(cls, conll: str): + ID, FORM, LEMMA, UPOS, XPOS, FEATS, HEAD, DEPREL, DEPS, MISC = conll.split('\t') + if HEAD == '_': + return Node(int(ID), FORM, UPOS, HEAD, DEPREL) + else: + return Node(int(ID), FORM, UPOS, int(HEAD), DEPREL) + + @classmethod + def create_root(cls, token: str): + return Node(0, token, token, 0, token, is_root=True) + + @classmethod + def create_eos(cls, position: int, token: str): + return Node(position, token, token, 0, token, is_root=False) + + def coverage(self) -> range: + limits = sorted([self.ID, self.HEAD]) + return range(*limits) + + def isprojective(heads: List[int]): + pairs = [(h, d) for d, h in enumerate(heads, 1) if h >= 0] + for i, (hi, di) in enumerate(pairs): + for hj, dj in pairs[i + 1:]: + (li, ri), (lj, rj) = sorted([hi, di]), sorted([hj, dj]) + if li <= hj <= ri and hi == dj: + print('1') + return False + if lj <= hi <= rj and hj == di: + print('2') + return False + if (li < lj < ri or li < rj < ri) and (li - lj) * (ri - rj) > 0: + print('3') + print(di, hi, dj, hj) + return False + return True + +def isprojective(heads: List[int]): + pairs = [(h, d) for d, h in enumerate(heads, 1) if h >= 0] + for i, (hi, di) in enumerate(pairs): + for hj, dj in pairs[i + 1:]: + (li, ri), (lj, rj) = sorted([hi, di]), sorted([hj, dj]) + if li <= hj <= ri and hi == dj: + print('1') + return False + if lj <= hi <= rj and hj == di: + print('2') + return False + if (li < lj < ri or li < rj < ri) and (li - lj) * (ri - rj) > 0: + print('3') + print(di, hi, dj, hj) + return False + return True + + + diff --git a/tania_scripts/supar/models/dep/eager/oracle/stack.py b/tania_scripts/supar/models/dep/eager/oracle/stack.py new file mode 100644 index 0000000..ee5545a --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/oracle/stack.py @@ -0,0 +1,24 @@ +from typing import Union, List, Optional +from supar.models.dep.eager.oracle.node import Node + +class Stack: + def __init__(self, items: Optional[List[Node]] = None): + if items: + self.items = items + else: + self.items = [] + + def pop(self) -> Node: + return self.items.pop(-1) + + def push(self, item: Node): + self.items.append(item) + + def get(self) -> Node: + return self.items[-1] + + def __repr__(self): + return repr(self.items) + + + diff --git a/tania_scripts/supar/models/dep/eager/parser.py b/tania_scripts/supar/models/dep/eager/parser.py new file mode 100644 index 0000000..f4857de --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/parser.py @@ -0,0 +1,380 @@ +import os +from supar.models.dep.eager.oracle.node import Node + +import torch +from supar.models.dep.eager.model import ArcEagerDependencyModel +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, PAD, UNK, EOS +from supar.utils.field import Field, RawField, SubwordField +from supar.utils.fn import ispunct +from supar.utils.logging import get_logger +from supar.utils.metric import AttachmentMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch +from supar.models.dep.eager.transform import ArcEagerTransform +from supar.models.dep.eager.oracle.arceager import ArcEagerDecoder +from itertools import groupby + + +logger = get_logger(__name__) +from typing import Tuple, List, Union + +def consecutive_duplicate_spans(L): + new_list = [] + for group in groupby(L): + f = list(group[1]) + if len(f) > 1: + new_el = f[0].replace('-arc', '') + "*" + new_list.append(new_el) + elif len(f) == 1: + new_el = f[0].replace('-arc', '') + new_list.append(new_el) + return new_list + + +class ArcEagerDependencyParser(Parser): + MODEL = ArcEagerDependencyModel + NAME = 'arceager-dependency' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.FORM = self.transform.FORM + self.STACK_TOP = self.transform.STACK_TOP + self.BUFFER_FRONT = self.transform.BUFFER_FRONT + self.TRANSITION, self.TREL = self.transform.TRANSITION, self.transform.TREL + self.TAG = self.transform.UPOS + self.HEAD = self.transform.HEAD + + def train_step(self, batch: Batch) -> torch.Tensor: + words, texts, *feats, tags, _, _, stack_top, buffer_front, transitions, trels = batch + #print('dep eager parser feats', len(*feats)) + tmask = self.get_padding_mask(stack_top) + + # pad stack_top and buffer_front vectors: note that padding index must be the length of the sequence + pad_indices = (batch.lens - 1 - self.args.delay).tolist() + stack_top, buffer_front = self.pad_tensor(stack_top, pad_indices), self.pad_tensor(buffer_front, pad_indices) + # forward pass + # stack_top: torch.Tensor ~ [batch_size, pad(tr_len), n_transitions] + # buffer_front: torch.Tensor ~ [batch_size, pad(tr_len), n_trels] + s_transition, s_trel, s_tag, qloss = self.model(words, stack_top, buffer_front, feats) + + # compute loss + smask = batch.mask[:, (2+self.args.delay):] + loss = self.model.loss(s_transition, s_trel, s_tag, transitions, trels, tags, smask, tmask, self.TRANSITION) + qloss + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> AttachmentMetric: + words, texts, *feats, tags, heads, deprels, stack_top, buffer_front, transitions, trels = batch + transition_mask = self.get_padding_mask(stack_top) + + + # obtain transition loss + stack_top, buffer_front = \ + self.pad_tensor(stack_top, (batch.lens - 1 - self.args.delay).tolist()), \ + self.pad_tensor(buffer_front, (batch.lens - 1 - self.args.delay).tolist()) + s_transition, s_trel, s_tag, qloss = self.model(words, stack_top, buffer_front, feats.copy()) + smask = batch.mask[:, (2+self.args.delay):] + loss = self.model.loss(s_transition, s_trel, s_tag, transitions, trels, tags, smask, transition_mask, self.TRANSITION) + qloss + + # obtain indices of deprels from TREL field + batch_size = words.shape[0] + deprels = [self.TREL.vocab[deprels[b]] for b in range(batch_size)] + + # create decoders + lens = list(map(len, texts)) + sentences = list() + for b in range(batch_size): + sentences.append( + [ + Node(ID=i + 1, FORM=form, UPOS='', HEAD=head, DEPREL=deprel) for i, (form, head, deprel) in \ + enumerate(zip(texts[b], heads[b, :lens[b]].tolist(), deprels[b])) + ] + ) + decoders = list(map( + lambda sentence: ArcEagerDecoder(sentence=sentence, bos='', eos='', unk=self.transform.TREL.unk_index), + sentences + )) + + # compute oracle simulation for all elements in batch + head_preds, deprel_preds, *_ = self.oracle_decoding(decoders, words, feats) + head_preds, deprel_preds = self.pad_tensor(head_preds), self.pad_tensor(deprel_preds) + deprels = self.pad_tensor(deprels) + + seq_mask = batch.mask[:, (2 + self.args.delay):] + return AttachmentMetric(loss, (head_preds, deprel_preds), (heads, deprels), seq_mask) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, texts, *feats = batch + #print('SENTENCE: ', ' '.join(list(texts[0]))) + #print() + lens = (batch.lens - 2 - self.args.delay).tolist() + + + batch_size = words.shape[0] + # create decoders + sentences = list() + for b in range(batch_size): + sentences.append( + [ + Node(ID=i + 1, FORM='', UPOS='', HEAD=None, DEPREL=None) for i in range(lens[b]) + ] + ) + decoders = list(map( + lambda sentence: ArcEagerDecoder(sentence=sentence, bos='', eos='', unk=self.transform.TREL.unk_index), + sentences + )) + # compute oracle simulation for all elements in batch + head_preds, deprel_preds, stack_list, buffer_list,actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, act_dict = self.oracle_decoding(decoders, words, feats) + batch.heads = head_preds + batch.rels = deprel_preds + return batch, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, list(texts[0]), act_dict + + def get_padding_mask(self, tensor_list: List[torch.Tensor]) -> torch.Tensor: + """ + From a list of tensors of different lengths, creates a padding mask where False values indicates + padding tokens. True otherwise. + Args: + tensor_list: List of tensors. + Returns: torch.Tensor ~ [len(tensor_list), max(lenghts)] + + """ + lens = list(map(len, tensor_list)) + max_len = max(lens) + return torch.tensor([[True] * length + [False] * (max_len - length) for length in lens]).to(self.model.device) + + def pad_tensor( + self, + tensor_list: Union[List[torch.Tensor], List[List[int]]], + pad_index: Union[int, List[int]] = 0 + ): + """ + Applies padding to a list of tensors or list of lists. + Args: + tensor_list: List of tensors or list of lists. + pad_index: Index used for padding or list of indices used for padding for each item of tensor_list. + Returns: torch.Tensor ~ [len(tensor_list), max(lengths)] + """ + max_length = max(map(len, tensor_list)) + if isinstance(pad_index, int): + if isinstance(tensor_list[0], list): + return torch.tensor( + [tensor + [pad_index] * (max_length - len(tensor)) for tensor in tensor_list]).to(self.model.device) + else: + return torch.tensor( + [tensor.tolist() + [pad_index] * (max_length - len(tensor)) for tensor in tensor_list]).to(self.model.device) + else: + pad_indexes = pad_index + if isinstance(tensor_list[0], list): + return torch.tensor( + [tensor + [pad_index] * (max_length - len(tensor)) for tensor, pad_index in + zip(tensor_list, pad_indexes)]).to(self.model.device) + else: + return torch.tensor( + [tensor.tolist() + [pad_index] * (max_length - len(tensor)) for tensor, pad_index in + zip(tensor_list, pad_indexes)]).to(self.model.device) + + def get_text_mask(self, batch): + text_lens = (batch.lens - 2 - self.args.delay).tolist() + mask = batch.mask + mask[:, 0] = 0 # remove bos token + for i, text_len in enumerate(text_lens): + mask[i, (1 + text_len):] = 0 + return mask + + def oracle_decoding(self, decoders: List[ArcEagerDecoder], words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[ + List[List[int]]]: + """ + Implements Arc-Eager decoding. Using words indices, creates the initial state of the Arc-Eager oracle + and predicts each (transition, trel) with the TransitionDependencyModel. + Args: + decoders: List[ArcEagerDecoder] ~ batch_size + words: torch.Tensor ~ [batch_size, seq_len] + feats: List[torch.Tensor ~ [batch_size, seq_len, feat_embed]] ~ n_feat + + + Returns: head_preds, deprel_preds + head_preds: List[List[int] ~ sen_len] ~ batch_size: Head values for each sentence in batch. + deprel_preds: List[List[int] ~ sen_len] ~ batch_size: Indices of dependency relations for each sentence in batch. + """ + # create a mask vector to filter those decoders that achieved the final state + compute = [True for _ in range(len(decoders))] + batch_size = len(decoders) + #print('ORACLE DECO TAG VOCAB', self.TAG.vocab.items()) + + exclude = self.TREL.vocab[['<reduce>', '<shift>']] + + # obtain word representations of the encoder + x, s_tag, _ = self.model.encoder_forward(words, feats) + transition_stags = self.model.decode_stag(s_tag) + + + stack_top = [torch.tensor([decoders[b].stack.get().ID]).reshape(1) for b in range(batch_size)] + buffer_front = [torch.tensor([decoders[b].buffer.get().ID]).reshape(1) for b in range(batch_size)] + counter = 0 + + stack_list = [] + buffer_list = [] + actions_list = [] + + #print('stack_top', stack_top[-1].item()) + #print('buffer_front', buffer_front[-1].item()) + stack_list.append(stack_top[-1].item()) + buffer_list.append(buffer_front[-1].item()) + + while any(compute): + s_transition, s_trel = self.model.decoder_forward(x, torch.stack(stack_top), torch.stack(buffer_front)) + transition_preds, trel_preds = self.model.decode(s_transition, s_trel, exclude) + transition_preds, trel_preds = transition_preds[:, counter, :], trel_preds[:, counter] + transition_preds = [self.TRANSITION.vocab[i.tolist()] for i in + transition_preds.reshape(batch_size, self.args.n_transitions)] + for b, decoder in enumerate(decoders): + #print('209', transition_preds[b][0]) + actions_list.append(transition_preds[b][0]) + if not compute[b]: + stop, bfront = stack_top[b][-1].item(), buffer_front[b][-1].item() + + else: + result = decoder.apply_transition(transition_preds[b], trel_preds[b].item()) + if result is None: + stop, bfront = stack_top[b][-1].item(), buffer_front[b][-1].item() + #print("2019 stop, bfront", stop, bfront) + + + compute[b] = False + else: + #print() + stop, bfront = result[0].ID, result[1].ID + stack_list.append(stop) + buffer_list.append(bfront) + #print("225 stop, bfront", stop, bfront) + + + stack_top[b] = torch.concat([stack_top[b], torch.tensor([stop])]) + buffer_front[b] = torch.concat([buffer_front[b], torch.tensor([bfront])]) + counter += 1 + + head_preds = [[node.HEAD for node in decoder.decoded_nodes] for decoder in decoders] + deprel_preds = [[node.DEPREL for node in decoder.decoded_nodes] for decoder in decoders] + deprel_preds_decoded = [[self.TREL.vocab[i] for i in dep_pre] for dep_pre in deprel_preds] + pos_preds = [[i.item() for i in trans_stag] for trans_stag in transition_stags] + pos_preds_decoded = [[self.TAG.vocab[i.item()] for i in trans_stag] for trans_stag in transition_stags] + form_preds = [[node.FORM for node in decoder.decoded_nodes] for decoder in decoders] + #print(len(stack_list), stack_list) + #print(len(buffer_list), buffer_list) + #print(len(actions_list), actions_list) + #assert len(stack_list) == len(buffer_list) == len(actions_list) + + """ + print() + + print('stack list: ', stack_list) + print('buffer list: ', buffer_list) + print('actions list: ', actions_list) + print() + print('head_preds: ', head_preds) + print('deprel_preds: ', deprel_preds, deprel_preds_decoded) + print('pos_preds: ', pos_preds, pos_preds_decoded) + print() + """ + + act_dict = {} + for i, j in zip(buffer_list, actions_list): + act_dict.setdefault(i, []).append(j) + + act_dict_list = [] + for _,vel in act_dict.items(): + new_list = consecutive_duplicate_spans(vel) + act_dict_list.append(" ".join(new_list)) + + #print('macro actions: ', act_dict_list) + + #assert len(act_dict_list) == len(head_preds[0]) + + + return head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, act_dict + + @classmethod + def build(cls, path, min_freq=1, fix_len=20, **kwargs): + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + + # ------------------------------- source fields ------------------------------- + WORD, TAG, CHAR = None, None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay) + if 'tag' in args.feat: + TAG = Field('tags') + TAG = Field('tags') + TEXT = RawField('texts') + STACK_TOP = RawField('stack_top', fn=lambda x: torch.tensor(x)) + BUFFER_FRONT = RawField('buffer_front', fn=lambda x: torch.tensor(x)) + + # ------------------------------- target fields ------------------------------- + TRANSITION = Field('transition') + TREL = Field('trels') + HEAD = Field('heads', use_vocab=False) + DEPREL = RawField('rels') + + transform = ArcEagerTransform( + FORM=(WORD, TEXT, CHAR), UPOS=TAG, HEAD=HEAD, DEPREL=DEPREL, + STACK_TOP=STACK_TOP, BUFFER_FRONT=BUFFER_FRONT, TRANSITION=TRANSITION, TREL=TREL, + ) + train = Dataset(transform, args.train, **args) + + if args.encoder != 'bert': + print('HOLY SH dep eager parser') + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), + lambda x: x / torch.std(x)) + if TAG: + TAG.build(train) + if CHAR: + + CHAR.build(train) + TAG.build(train) + TREL.build(train) + TRANSITION.build(train) + + print('TAG VOCAB', TAG.vocab.items()) + #print('CHAR VOCAB', CHAR.vocab.items()) + + + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_transitions': len(TRANSITION.vocab), + 'n_trels': len(TREL.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index + }) + + + logger.info(f"{transform}") + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/dep/eager/transform.py b/tania_scripts/supar/models/dep/eager/transform.py new file mode 100644 index 0000000..be5c883 --- /dev/null +++ b/tania_scripts/supar/models/dep/eager/transform.py @@ -0,0 +1,176 @@ +from supar.utils.transform import Transform, Sentence +from supar.utils.field import Field +from typing import Iterable, Union, Optional, List, Tuple +from supar.models.dep.eager.oracle.arceager import ArcEagerEncoder +from supar.models.dep.eager.oracle.node import Node +import os +from io import StringIO + + +class ArcEagerTransform(Transform): + + fields = ['ID', 'FORM', 'LEMMA', 'UPOS', 'XPOS', 'FEATS', 'HEAD', 'DEPREL', 'DEPS', 'MISC', 'STACK_TOP', 'BUFFER_FRONT', 'TRANSITION', 'TREL'] + + def __init__( + self, + ID: Optional[Union[Field, Iterable[Field]]] = None, + FORM: Optional[Union[Field, Iterable[Field]]] = None, + LEMMA: Optional[Union[Field, Iterable[Field]]] = None, + UPOS: Optional[Union[Field, Iterable[Field]]] = None, + XPOS: Optional[Union[Field, Iterable[Field]]] = None, + FEATS: Optional[Union[Field, Iterable[Field]]] = None, + HEAD: Optional[Union[Field, Iterable[Field]]] = None, + DEPREL: Optional[Union[Field, Iterable[Field]]] = None, + DEPS: Optional[Union[Field, Iterable[Field]]] = None, + MISC: Optional[Union[Field, Iterable[Field]]] = None, + STACK_TOP: Optional[Union[Field, Iterable[Field]]] = None, + BUFFER_FRONT: Optional[Union[Field, Iterable[Field]]] = None, + TRANSITION: Optional[Union[Field, Iterable[Field]]] = None, + TREL: Optional[Union[Field, Iterable[Field]]] = None + ): + super().__init__() + + self.ID = ID + self.FORM = FORM + self.LEMMA = LEMMA + self.UPOS = UPOS + self.XPOS = XPOS + self.FEATS = FEATS + self.HEAD = HEAD + self.DEPREL = DEPREL + self.DEPS = DEPS + self.MISC = MISC + self.STACK_TOP = STACK_TOP + self.BUFFER_FRONT = BUFFER_FRONT + self.TRANSITION = TRANSITION + self.TREL = TREL + + @property + def src(self): + return self.FORM, self.LEMMA, self.UPOS, self.XPOS, self.FEATS + + @classmethod + def toconll(cls, tokens: List[Union[str, Tuple]]) -> str: + r""" + Converts a list of tokens to a string in CoNLL-X format with missing fields filled with underscores. + + Args: + tokens (List[Union[str, Tuple]]): + This can be either a list of words, word/pos pairs or word/lemma/pos triples. + + Returns: + A string in CoNLL-X format. + + Examples: + >>> print(CoNLL.toconll(['She', 'enjoys', 'playing', 'tennis', '.'])) + 1 She _ _ _ _ _ _ _ _ + 2 enjoys _ _ _ _ _ _ _ _ + 3 playing _ _ _ _ _ _ _ _ + 4 tennis _ _ _ _ _ _ _ _ + 5 . _ _ _ _ _ _ _ _ + + >>> print(CoNLL.toconll([('She', 'she', 'PRP'), + ('enjoys', 'enjoy', 'VBZ'), + ('playing', 'play', 'VBG'), + ('tennis', 'tennis', 'NN'), + ('.', '_', '.')])) + 1 She she PRP _ _ _ _ _ _ + 2 enjoys enjoy VBZ _ _ _ _ _ _ + 3 playing play VBG _ _ _ _ _ _ + 4 tennis tennis NN _ _ _ _ _ _ + 5 . _ . _ _ _ _ _ _ + + """ + if isinstance(tokens[0], str): + s = '\n'.join([f"{i}\t{word}\t" + '\t'.join(['_'] * 8) + for i, word in enumerate(tokens, 1)]) + elif len(tokens[0]) == 2: + s = '\n'.join([f"{i}\t{word}\t_\t{tag}\t" + '\t'.join(['_'] * 6) + for i, (word, tag) in enumerate(tokens, 1)]) + elif len(tokens[0]) == 3: + s = '\n'.join([f"{i}\t{word}\t{lemma}\t{tag}\t" + '\t'.join(['_'] * 6) + for i, (word, lemma, tag) in enumerate(tokens, 1)]) + elif len('85!!', tokens[0]) == 10: + s = '\n'.join([f"{i}\t{word}\t{lemma}\t{tag}\t{xpos}\t{upos}\t{head}\t{rel}\t{comm}\t{morph}" + for (i, word, lemma, tag, xpos, upos, head, rel, comm, morph) in tokens]) + else: + raise RuntimeError(f"Invalid sequence {tokens}. Only list of str or list of word/pos/lemma tuples are support.") + return s + '\n' + + @property + def tgt(self): + return self.HEAD, self.DEPREL, self.DEPS, self.MISC, self.STACK_TOP, self.BUFFER_FRONT, self.TRANSITION, self.TREL + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ): + if isinstance(data, str) and os.path.exists(data): + if os.path.isfile(data): + lines = open(data) + if os.path.isdir(data): + lines = [] + for filepath in data: + if filepath.endswith('.conllu'): + l = open(filepath) + lines.append(l) + else: + if lang is not None: + #data = [tokenizer(s) for s in ([data] if isinstance(data, str) else data)] + data = [data.split() if isinstance(data, str) else data] + else: + data = [data] if isinstance(data[0], str) else data + lines = (i for s in data for i in StringIO(self.toconll(s) + '\n')) + + index, sentence = 0, [] + for line in lines: + line = line.strip() + if len(line) == 0: + sentence = ArcEagerSentence(self, sentence, index) + yield sentence + index += 1 + sentence = [] + else: + sentence.append(line) + + + +class ArcEagerSentence(Sentence): + def __init__(self, transform: ArcEagerEncoder, lines: List[str], index: Optional[int] = None): + super().__init__(transform, index) + self.values = list() + self.annotations = dict() + + for i, line in enumerate(lines): + value = line.split('\t') + if value[0].startswith('#') or not value[0].isdigit(): + self.annotations[-i-1] = line + else: + self.annotations[len(self.values)] = line + self.values.append(value) + + nodes = [Node.from_conllu('\t'.join(value)) for value in self.values] + + + algorithm = ArcEagerEncoder(bos=transform.FORM[0].bos, eos=transform.FORM[0].eos) + transitions = algorithm.encode(nodes.copy()) + stack_top, buffer_front, transition, trel = zip( + *[(transition.stack_top.ID, transition.buffer_front.ID, transition.type, transition.deprel) + for transition in transitions]) + + self.values = list(zip(*self.values)) + if self.values[6][0] != '_': + self.values[6] = tuple(map(int, self.values[6])) + self.values += [stack_top, buffer_front, transition, trel] + + + def __repr__(self): + # cover the raw lines + #print('µµµµµµµµ', self.values[:-4]) + merged = {**self.annotations, + **{i: '\t'.join(map(str, line)) + for i, line in enumerate(zip(*self.values[:-4]))}} + + return '\n'.join(merged.values()) + '\n' \ No newline at end of file diff --git a/tania_scripts/supar/models/dep/sl/__init__.py b/tania_scripts/supar/models/dep/sl/__init__.py new file mode 100644 index 0000000..c0e75ee --- /dev/null +++ b/tania_scripts/supar/models/dep/sl/__init__.py @@ -0,0 +1,2 @@ +from .model import SLDependencyModel +from .parser import SLDependencyParser \ No newline at end of file diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e84041e18d76d00c1a56d47aa5947ed6eabe7f48 GIT binary patch literal 258 zcmd1j<>g{vU|`^9UzG06z`*br#6iYP3=9ko3=9m#G7Jn1DGVu$ISjdsQH+crHd78$ zE^`z!BSQ*vFoPz`OGX9;22I9Wg26s6sRgNdDXDqMmA?5YsX3aAw}g-d0}_jhQ;YmG zS#GiBg5--pw%lSX01Fo}GcYi$WGG@|V1N+6T=g^Zb5r$85=$}@^Ah!vauQQAQ;YPI z^K%RGb<+z<bisz`7nc?!7U_f8#ri3!1^UG~`tk9Zd6^~g@p=W7w>WHa^HWN5Qtd$Q OEM{R~VBld8U<3en0zyLo literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7da5b0abda7bcaada2f81498ced6765d9b1bb222 GIT binary patch literal 318 zcmZ3^%ge>Uz`&q%Up2#<fq~&Mhy%k+P{wCD1_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9 zGb2L^b1;J@%S%QE1_n*WTY|wpE~y2nc`2!R$(6qODXBS{jJJf41p^X`ic^dHG+A!3 z=7Qvlm>C!tZm|`Bg^O4i7#LPEd<I$lD_B1xKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}` zU$-Q+qC_{fEHOvFBrz{DF}^stD6^oXSiiWmAhAdvY;v)FN@{_AagKg`d}dx|NqoFs xLFF$Fo80`A(wtPgB9PBPt}fPRU|{&b%*e=igF)p2D!Rd-b^#kI;$UE4003LQSsVZW literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0eca97c4fc223779fc95ca035a2bb17aa33cb321 GIT binary patch literal 5672 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 P!wBlX@Gy!niZB5H9bvLQ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f0f4cad3dcc22e7872d1c2ee274f49f8582da16 GIT binary patch literal 9943 zcmZ3^%ge>Uz`&q%Uo~Tr1Ovlk5C?`?p^VQ(3=9m@8B!Qh7;_k+AT(nxQxp>;h|QG4 zoXZl$0%kMku;#KwvE{Nyv4i<6IUKp1QJi2lYYtZ~cNBLnPZUosZxk;h0~3QgLke39 zLkfE;%Q9vLhSkha`xv75QW%37G&x>^1pG7^Z?XF3r=;d+GTmbK^$EDe?UI_DpORYS z6CC2J$#{#+IX^EgGhLJU7HddpK~Cx|7N5-Gl3T2yd71fn$si+OSQg6oEXKsZ(9STO zA(bJDF@+(DDTOhGF@-6eA%z(XSyGr&SX0<i*i#r&I8r!MxKdbCxKmhDcv5&%_)>UM z_*0lucv4tXSW^VjWK#rFnNx&PSyEY3nI)kXFfgPtr!gUTDZ;7DDI%%NDWa*&DPpN? zDdMT@scZ=OG`<doG{zK(7Tze16txt|RL(4Lw1A9DkxFGp<|A~aNT;%5mq}wwk!fL# z;!cqTy9>!Qgl=S=C~lQQmPwIE;VF<|o+63~N+>*K6rMCPFHImtrG+Jmhw6Snu``V$ zMYV+`inoKIf-#COm_bwhmSC`tOKL%CUP@|SawRz7`Q2j4DK5!<nZm%p@Y0BZfuV?r zfq~%`cYaZ3dS+f?PP}Q7CR2#pOBMzOhICMzf$%Ms+|<N8w{-c|*MU3auG(iRFf%Z` z1f}uJFN_QfFBw5bu;;~>=NF|E-{Q!N&q+*5%_+XcmKR?HrArdii*K>##V2PZ78T!O zPt5}-`&%q&sfi`YiXcm%n1g|Vft!JW;qx4328OAO?F{X*(;1i;N<el%l`LamU|0=h zGcaVqWm32^8A@O|oq>S?Row!Rd*QlZj1o>53tjy(Mh1q}aI=>%_AxRtq%g)XF)(y8 z#KUdrWQb>jnb66Q#SUX<f&2mHq%dWJf|#L*y+gKxA&n`8xrL)vDUS`xV*&9{bi!Sf z!V1;t&BRcngrWwKrI4~7s*5`r;z8jEb^{*$?1*fHp`Qn=nSp@;oTWKhIFNmwCxzQo z43psDg`tNRW(S5I?BU7>Q=h_?4UW+w>k@gG7$|O#;y?f<juLhV6WFU57#ONpaq5y? z!--m&cQV8aVl`6;CJK*jyApMn7*6w%(+hUDioncBVegdfWXKYQ@z-!IV`E@gjTA=l zVlcTpi4uJnn}H!q0>(zo51kAM9VqJI2?9gC6wIU)hF}Iw9zRVcKffYSB1wkl69xtb zP|6nu<=}G+3=C75rlaKD5^$VB%*g`h3lO^m&SGH5f~!~nDuh7NC>YgMMNBD-d5kGc zXsL%O3!dV#5Me}E6rO)O8EY8UFr$WXFoPzG-z}Ep(v-wo%*h3%nrye&Qc}w@lT&YT zW#$!>mc$olR;AwJ&d5wjNzH?BxbjMK<8u-#Q$eL(N>P46erd@q?)=gcm~u^yB9K#W zv6kc)C1(_Yl5!EKa=*osSsb5OmYA87m;`DFBo?I?-xA1+hnAf25KBNJDUc=v)RvXZ zx7hPbOX5>9b8m6y<`l%kEM+N9%}FZ;1+GFv!><7SjQreG{gT9z%*4Dzy`-GPl+4s3 z{p9@If_&YQ)QS?_)Uw1J{gTAI%*6QO<f6=il4AYh(t^Yy{ajE3rdU5EwLrf(2g1`U zsQkrYlarX6l#*yyrGruH=*7op=4F<|$LrbT<R>TQ6x->+RD<fE;s^!?h93<KOSAWi z?vc3~5PBsb>Uu!>rGWH{0hw0<GB3E597sEmb|JsyqGjn7%hDUt@^dV&NShuoIbwOm zITps<QGG*3`2#z%y6Q&;W_8ssAfkccGbr_-Bv4RzgA=F?mIT_#gs4yu3ABcxlW`3r zYGDw}pvmO7lKB=(UVLWWE!MpF{L+#lWd;TYP39s{$}IvF07V+0I#!E;fdLluMS36+ zPzEI}pv*yLC_w`%`G%<El*lWh`WwnmaDQNCQs?`~z@*Oi1w=G36d8ajWG15maOGYE z@+(RJfLsR>{0s{Bsf^PZIvE#$LJ0%cFreit#s$bZ9j+c-T^ds`!%9X!O{QCX;HE%4 zG>saf@r^W@ZZTFA>4LllDgqQ5$PFDkkP(`Y&{^SfUB~{Cj{O0~i#kqMbes;jTz3h- z<Pv@%BJ!e3)D@Sg3)<1pKq>+yKTWnG1yG!Tnju9hAQmW?!BGj$k1H88rEjqomlmWJ z-Qs|y<RVb9a*M6BASJOR^%ff>S>NJC@$N0|qSPFi-@(b@7CST~Zn1(IK*dF%0=>ur zWTz#F0F~jlSW{AS5-TBT2$Xzoae)Qm3ySiyia@0^xWp(D2WbG67q_?y@{8k364TRD zi*7OH<=x`&Oi9fv$t<b7CE#3?UtH{(S5lN;Q0bFjTzrc&xhS(FwJ0+`Pg4aP@I|0H z2I3Bo?GR%@bq2&LP?-;ExTWSMrKa5C$%`*2N-Zf$%*=!EK<&49xE!c;2j%fX+Ip~Z ziVrMRkeCvmnU|7Uaf>B2CpZ5V4~UFU$}f&j%`d*il9XCha*H=F9z;Wnvs>J`nHBId zj0Y@Jke{EEnU{Wx55j|+$&r?sms(PqmwJmkFTNlr7v>VM^I&FxGbE_kgcYRF!kHh& zhn1I{dGU!w$?>^41-CfC?N|`ANC%X&Sc{Vrb5d_{BD}*{nwJgr8C!NasH`q>0;%MT zk5A4?EG~|ZF9s#71O+?*A_>g_wxE`Y6z+l))U+$U$;iO)<HwH%h7T@`44jg^texyV z>{mD>E^wG$;4qzQHq&B`#eDl&_G`^nTCB0SC~a~@+5{qZfy49z8-sz>MGl<~mMa`m zGhD97=-lAu@3FkXEwg~_61Um~ZnY0g%;Ksa7%+(r_YU_DTukD89~dx+4)+fn3_Joo zmOb_}QZ8{TUEo%_p`^J$eTB*z%_~|qI|8q0*<Vz0xT56H;c|sX9<Q8Y^aU6KDVDpy zBlkd2V}bYzku{Q6G_5Zx+FVhz0n0p)R+?eHz+{Q#6=h?HM?wCQ_`n8pO5!DM`3v0g zcjXiplq{*dqV9Mg<VfU^_zU3?7hNMRsz=_?&{@NIMZ@WY_XlQ1`AEi(3?T9gnCx)r z@rQZ}DR}P6X~JqASVbhGFvs(XjLr_h1Kt-RVy;9ae_&;jPi6eb03yGDNsw6`{$Dv5 z<Q3;+&&-{Z3lexLDSbs!=c1(E6-m7gmL9$iz79S}A<hcvQ?Y{bS@A8lqSTVoqP%2K zEe<PuK}{AA|FZ*lB%qyZIzuM|j^doLhG`iS1H)=iSqs+R#ns6L8Zl^PN?}T2Yz2=V zv@)e3_5QoKIvKDR`kf4j`VrA+OJRm~T9`Vy@}%LWGh$cG&4A5L)Jmt88N1#TW@rZ> z2)Pr7X!vz7ba16HrLeScl)yU~;HEg-_eid00(AvY?R7!xK&G&+VZ#VLh6SMT2Ztpx z(aD8s7ATw%UBVb<28LReTGm>&PKE`X$ogPxbp4=iXBSs3dndyJc-If67DS_~ujS}u zSO6*`K$0jJLnUVoM-68Ua}9eMOE7~bdm<ML0|OVVm~t#iFSdg7K%(IEsGv~?Zm#P2 z<maV_q~;ap7in54BqT&9C6**-fLp#g3dN~~@j0n^u?Y!!C?<eR3C}M|QOL|o$xKcy zMwJC8bOjC2xK}iWC9#^QjsY3vsF0IcT%wSlrU254-B6Iakc?CXQ2SgVvsfWDvm_(6 z2#14p6w)#)pe|R)OjAfm02!Q+0MeL{pbo0Y)DsdE@<IC5K~<1?LV^y455dwn!b2e+ zWPN#NaVo0cLC$nZO-n4zDFKD1Uw&RHDDdEB2Z3`xT7(osMq3m#>cFFf(U6FNM2e0A zco-2yEH)NrROu+>K@2O7O-O*-3UU<)LyQFZ+ekMhGdDG_I5R&lF-M^U9RCU>paDw- zjm$I!Bi(|W#Jt2Jg`}dy<m}Xv%)E4k<opy6m07HilnP>$7N@3YDwJnrCTA#Q<maRm zE0koUVpv(6oL`h$42s*toE(LM{Nm!wq?}X*a3c#X-4ug{n&9aY;#RyK1&vH$^QH&b zH8^Zefsdvs6s6`QmSpDVVYs6tF&&FL6tJZQP=JF*#z=MtNRvWZevv|IVseH8C{LoM zq{5v1;$jR}V1#d2YH~?_kwRf<VqQsR71%opAe{)q{J^~ja6ba23jr$iz+H$8Xdfz_ zp@tz=ua>csIfWsGp_QqIv6DFqUh<?cg4(SRF7_T)6&C|T4I`)&Ze@a)fLserWa`le z_qV{#0gaCrXCxM+g4@(ZE}%Xa%Pl57gIkQ5kT$Iqs5=1a<|rsMKw4D4xNJb>1gL{+ zSEY;Duu97>Do-p*LGGYt7MFmP7lRCQgY+#fNM%FNiNG0#GXg<y0pkM0CFUy(mso9J z*}}Pn|Dv+}0mX~T&KDG14kUu$1zGni(jE|P7o@Vm75ht2C8WuCi#a7TSCi)!8?^Na zvIXI(B2`cuk~ulC<Q8jDVqSV`kt?Xpp9vD>Dl3eKy1B>!B<ctX1#XD<L8H4xsUT&n z;Eus9E=0k6iyPEzg%-}Y7~^lTf)mRvc4$Fzixr%eioih#szM;`Qcwxt0PdaLVu#vW zC5bZ_gF!*&0B)W(Fnlmz;1%rm?(&|&I-~R=kLnd3)egoRJiHx=AUHvAg3tt^34tKk zk<sJb!T5oVK~Qu$|0MneAxk2c#P49dq-uFV)p7yj0>&MM2LwUzf=lRulp~o(@-MiC zUT_J$5FP<VjuBVvBQFX>T@i@tV8v|x35ZVNghvE~aWyC$+*V7x5|Mr(BlBWJ=Eb0_ zD?wQoq_QtcWnYoXzED_nL7@1eK=BoU;tt0f0wQ3iF<ul<x+0*|;rM}#K}~&0_(cw- z4z3B_3j{x~F^EV^x1VIc!0@85>J?$tPL2-74$}{848r2qg;XvHsVoS*D5QQxNWFvo zhJeU*0fkEf3JU};3MgL@Q0`!Tz%K?0rUj`N__Z%^XoC|=Q3WW1D?tP(E#6{-6o9u_ zKxNo17EobuizPR)I6E0M_6Esi3=E(w3T_ydF@mOu+Sx%3LqwKD40EI~LK{*_oeT>= z=@MoFoUUQ)L>ecqVL|4hHi_~yOF;HQb#}0WN4%L@IFOrYHH<YZsJhUbTBwbuT8<h} za|XN1n2_C4!-~v9wWErcfdSMkLJ9%UKoHoa@J6dD9-Ekv&8}fX=3%p`h66laSY*n; zz<^S8f(8zZLF1!I;G)x;fstW4sPNPTHS%g1YneJ(7JyxaPJoJ3L@`>!)QQwgM|D9M z!*oVQh8``@IBgMV;7F6P$O}|Huoi*5e~S%Lz1?C>2UT`Ob)b|59)tmfhytR_<g`go z%}cE)D6*^4#LVm9ngTJP2UFS$%KM$5;_?N<3x)=U4-5?Pj3rD^>LUY#A5%1l=f@NR zqQaP>nJ&a9Uyskd6rXz`ujE2$<(0gu4-5>oj7}hVXC`;1FCd-=(?<q|1V&E~4@5x? zB!YruBG5p!CL5%5bq4tu6e72ni%WBFF;`_4fQLIYIUxloYKAMS1}U!r5w#!!6kfMj zK;AC~wceoxWP$>?cr0oIb=}3V2Uim)Y`%iR2Gna8W3YE-+>^N{|3YBsCA-iIcA*_5 z{dHY+Gtw8N%*kC5w!vjh%td~yEBsa$_^qx+#}VPxuM7<FOi7?{OJ>RfQ8`RSpm2+4 zDh7och=Q8(5fUw5Ak;?&h8V^YkP;Bp!SaBEX9CM~zDayDN*9F8sb1l-L1c~BMFI0G z0_GPv%sW^fpp6yW;1QVMGTm>I-vZMWB1^0{uxtp~!gW!^`ihA4MIP%8mmB=T9o*n} zNCu@bSkeaN1#lU~#R!_0uVDZsPlzOz@=3IY5qtTBKK`F4i(CpJmpv)WEeth`sJR8L zv|+7bBF>gtHWc^5{guK3?E;I|FcW7|9%BkaEqe`X4O<O+8gnp%CaWK~+<5u_|Ns9e zg$F3G!0j&3KoqFhz+P0OFrs=2(st?q6#<O5*b<A<a}z5x86kB%Xhav9bit$2T9`=} zGH8k1Hi8WGPX{Gu(5PVp!-d$m>#?bqVpA`qWn7HSyb_xU8)C)CcU|Cy3An#-i#azD zn)5iY<~(p#;|AAvppnOv;#-`cG1Y>iR1mWyF&!dW4667*O%xCYXG74`3}}e8N&=U6 zrh**bz`(%J!0<rFV2$S*{~aZlbeu2fI8R8Qo;N9PLC{4pjVodr7sNEqik>aL5S$4@ z*+m!qi?8?>U-T@w;#tzceM3ZYy3Zt^1wt1^RIZ4qbZ|lkk}P+GUD9yApy52h6<Pj* zh{_3(4$d3=QZqakR9@gWxWHim&K8hjnjbX4oR^rJ8Xtd)D?UCqKczGW#O8^QFDy;W zfyyvv=9LtIN}eK6U3-hUxTL5E6aYn_QA0?hkqy!VDgrgA!6j1B1W>5+LdPSMQ*(0S z<24zJK#NL>K`8*zwkrZP_`n2cn4wsK2|O>;zyN_CxEK^vZYZeSkXOB-ta?LI=7yXi z7%AM4SGu8~ctcG2hMe{dF{vB!3O8isZ^)^D1f}F}$jX5fD5>61Qof<6azk1Ugk%+N zh)dj%mboD<^TCnPjgeLV0|SV>Atn2P8N_%Xt*}6JLGco)6~PPSuSgqyU<HYOU}KPy z{lE@pa)6keU?vxXwA=@7Fp~$w<OMVN7$jt7I8Ukkzz^nv&4<{6g$!WQW!3q>pv$T= zBXmv-n6W`+L+O^9D@HD0-i3hB3t`b$!ji58B!dOei8w|<R*?sSViQV1CR`EMTH(6J z=YqJ!6+z1ntb(i}AJ`ZKM0;vJu!Gnf5H=@>&BY)nHX(I}>l~jeVwx*V*VtSTGruBW z@qrs8$-}@e(v$On7sTd+u=zo30SH?V#1?|Eg+XivR6>oF)o@1Y0@oF)Yjm!tnC}qX zBXdE;^@^O^2L@JF!xN=vYQT&ODVbMN3c$=8qEb_0J}|Sg8iKj_2}tS%r5jCtNZR9o z3_;}O6}f}b95;B{P!Bw9SOhA+Zt=oJN^??+Arl>-((@KnX=zDjPBC<XrKGYTGcO&S z&>?9YobEx^6<LGoV$f6<IK%(quz_S3yP~-a3=E(&UA&8df#Cx)BO|Cw!N}Xd1A;dg zL@%JC8w|1+P|*zrtqa)D4F<UjsOScR>IK~B14{rCqu~bz?BopAk6@WEU=mXmIAj4j CL@h}G literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95e1cddfd1b7d2af2f9bbf1573def416297a278b GIT binary patch literal 12083 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b16ba48675cbab2d7e21471d46322179b0928fb GIT binary patch literal 25291 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 PeFV#V0h5@j!0815$xn+h literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7df4678723720a507453f379f951e9dbd859a3a2 GIT binary patch literal 3766 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..027f048a42a233403d83761297506d43e3d196b9 GIT binary patch literal 7098 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 BzHk5l literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/sl/model.py b/tania_scripts/supar/models/dep/sl/model.py new file mode 100644 index 0000000..79e5ec7 --- /dev/null +++ b/tania_scripts/supar/models/dep/sl/model.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.model import Model +from supar.modules import MLP, DecoderLSTM +from supar.utils import Config +from typing import Tuple, List, Union + +class SLDependencyModel(Model): + def __init__(self, + n_words: int, + n_labels: Union[Tuple[int], int], + n_rels: int, + n_tags: int = None, + n_chars: int = None, + encoder: str ='lstm', + feat: List[str] = [], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_arc_mlp=500, + n_rel_mlp=100, + mlp_dropout=.33, + scale=0, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + # create decoder + self.label_decoder, self.rel_decoder = None, None + if self.args.decoder == 'lstm': + decoder = lambda out_dim: DecoderLSTM(device=torch.device("cuda" if torch.cuda.is_available() else "cpu"), + input_size=self.args.n_encoder_hidden, hidden_size=self.args.n_encoder_hidden, + num_layers=self.args.n_decoder_layers, dropout=mlp_dropout, + output_size=out_dim) + else: + decoder = lambda out_dim: MLP( + n_in=self.args.n_encoder_hidden, n_out=out_dim, dropout=mlp_dropout + ) + + if self.args.codes == '2p': + self.label_decoder1 = decoder(self.args.n_labels[0]) + self.label_decoder2 = decoder(self.args.n_labels[1]) + self.label_decoder = lambda x: (self.label_decoder1(x), self.label_decoder2(x)) + else: + self.label_decoder = decoder(self.args.n_labels) + + self.rel_decoder = decoder(self.args.n_rels) + + # create delay projection + if self.args.delay != 0: + self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay + 1), + n_out=self.args.n_encoder_hidden, dropout=mlp_dropout) + + # create PoS tagger + if self.args.encoder == 'lstm': + self.pos_tagger = DecoderLSTM( + input_size=self.args.n_encoder_hidden, hidden_size=self.args.n_encoder_hidden, + output_size=self.args.n_tags, num_layers=1, dropout=mlp_dropout, device=self.device) + else: + self.pos_tagger = nn.Identity() + + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words: torch.Tensor, feats: List[torch.Tensor] = None) -> Tuple[torch.Tensor]: + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + s_label (~Union[torch.Tensor, Tuple[torch.Tensor]]): ``[batch_size, seq_len, n_labels]`` + Tensor or 2-dimensional tensor tuple (if 2-planar bracketing coding is being used) which holds the + scores of all possible labels. + s_rel (~torch.Tensor): ``[batch_size, seq_len, n_rels]`` + Holds scores of all possible dependency relations. + s_tag (~torch.Tensor): ` [batch_size, seq_len, n_tags]`` + Holds scores of all possible tags for each word. + qloss (~torch.Tensor): + Vector quantization loss. + """ + + # x ~ [batch_size, bos + pad(seq_len) + delay, n_encoder_hidden] + x = self.encode(words, feats) + x = x[:, 1:, :] # remove BoS token + + # s_tag ~ [batch_size, pad(seq_len), n_tags] + s_tag = self.pos_tagger(x if self.args.delay == 0 else x[:, :-self.args.delay, :]) + + # map or concatenate delayed representations + if self.args.delay != 0: + x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay+1)], dim=2) + x = self.delay_proj(x) + + # x ~ [batch_size, pad(seq_len), n_encoder_hidden] + batch_size, pad_seq_len, _ = x.shape + + # pass through vector quantization module + x, qloss = self.vq_forward(x) + + # make predictions of labels/relations + s_label = self.label_decoder(x) + s_rel = self.rel_decoder(x) + + return s_label, s_rel, s_tag, qloss + + def loss( + self, + s_label: Union[Tuple[torch.Tensor], torch.Tensor], + s_rel: torch.Tensor, + s_tag: torch.Tensor, + labels: Union[Tuple[torch.Tensor], torch.Tensor], + rels: torch.Tensor, + tags: torch.Tensor, + mask: torch.Tensor + ) -> torch.Tensor: + + loss = self.criterion(s_label[mask], labels[mask]) if self.args.codes != '2p' else sum(self.criterion(scores[mask], golds[mask]) for scores, golds in zip(s_label, labels)) + + loss += self.criterion(s_rel[mask], rels[mask]) + + if self.args.encoder == 'lstm': + loss += self.criterion(s_tag[mask], tags[mask]) + return loss + + def decode(self, s_label: Union[Tuple[torch.Tensor], torch.Tensor], s_rel: torch.Tensor, s_tag: torch.Tensor, + mask: torch.Tensor): + label_preds = s_label.argmax(-1) if self.args.codes != '2p' else tuple(map(lambda x: x.argmax(-1), s_label)) + rel_preds = s_rel.argmax(-1) + tag_preds = s_tag.argmax(-1) if self.args.encoder == 'lstm' else None + return label_preds, rel_preds, tag_preds diff --git a/tania_scripts/supar/models/dep/sl/parser.py b/tania_scripts/supar/models/dep/sl/parser.py new file mode 100644 index 0000000..af95475 --- /dev/null +++ b/tania_scripts/supar/models/dep/sl/parser.py @@ -0,0 +1,323 @@ +# -*- coding: utf-8 -*- + +import os, re +from typing import Iterable, Union, List + +import torch +from supar.models.dep.sl.model import SLDependencyModel +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, PAD, UNK +from supar.utils.field import Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import AttachmentMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch +from supar.models.dep.sl.transform import SLDependency +from supar.codelin import get_dep_encoder, LinearizedTree, D_Label +from supar.codelin.utils.constants import D_ROOT_HEAD +from supar.codelin import LABEL_SEPARATOR +logger = get_logger(__name__) +from typing import Tuple, List, Union + + +NONE = '<none>' +OPTIONS = [r'>\*', r'<\*', r'/\*', r'\\\*'] + + +def split_planes(labels: Tuple[str], plane: int) -> Tuple[str]: + + split = lambda label: min(match.span()[0] if match is not None else len(label) for match in map(lambda x: re.search(x, label), OPTIONS)) + splits = list(map(split, labels)) + if plane == 0: + return tuple(label[:i] for label, i in zip(labels, splits)) + else: + return tuple(label[i:] if i < len(label) else NONE for label, i in zip(labels, splits)) + +class SLDependencyParser(Parser): + + NAME = 'SLDependencyParser' + MODEL = SLDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.TAG = self.transform.UPOS + self.LABEL, self.DEPREL = self.transform.LABEL, self.transform.DEPREL + self.encoder = get_dep_encoder(self.args.codes, LABEL_SEPARATOR) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 1000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + tree: bool = False, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def few_shot( + self, + train: str, + dev: Union[str, Iterable], + test: Union[str, Iterable], + n_samples: int, + epochs: int = 2, + batch_size: int = 50 + ) -> None: + return super().few_shot(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + tree: bool = True, + proj: bool = False, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 500, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + tree: bool = True, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + if self.args.encoder == 'lstm': + words, texts, chars, tags, _, rels, *labels = batch + feats = [chars] + else: + words, texts, tags, _, rels, *labels = batch + feats = [] + labels = labels[0] if len(labels) == 1 else labels + mask = batch.mask[:, (1+self.args.delay):] + + # forward pass + s_label, s_rel, s_tag, qloss = self.model(words, feats) + + # compute loss + loss = self.model.loss(s_label, s_rel, s_tag, labels, rels, tags, mask) + qloss + + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> AttachmentMetric: + if self.args.encoder == 'lstm': + words, texts, chars, tags, heads, rels, *labels = batch + feats = [chars] + else: + words, texts, tags, heads, rels, *labels = batch + feats = [] + labels = labels[0] if len(labels) == 1 else labels + mask = batch.mask[:, (1+self.args.delay):] + lens = (batch.lens - 1 - self.args.delay).tolist() + + # forward pass + s_label, s_rel, s_tag, qloss = self.model(words, feats) + + # compute loss and decode + loss = self.model.loss(s_label, s_rel, s_tag, labels, rels, tags, mask) + qloss + label_preds, rel_preds, tag_preds = self.model.decode(s_label, s_rel, s_tag, mask) + + # obtain original label and deprel strings to compute decoding + if self.args.codes == '2p': + label_preds = [ + (self.LABEL[0].vocab[l1.tolist()], self.LABEL[1].vocab[l2.tolist()]) + for l1, l2 in zip(*map(lambda x: x[mask].split(lens), label_preds)) + ] + label_preds = [ + list(map(lambda x: x[0] + (x[1] if x[1] != NONE else ''), zip(*label_pred))) + for label_pred in label_preds + ] + else: + label_preds = [self.LABEL.vocab[i.tolist()] for i in label_preds[mask].split(lens)] + deprel_preds = [self.DEPREL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)] + + if self.args.encoder == 'lstm': + tag_preds = [self.TAG.vocab[i.tolist()] for i in tag_preds[mask].split(lens)] + else: + tag_preds = [self.TAG.vocab[i.tolist()] for i in tags[mask].split(lens)] + + # decode + head_preds = list() + for label_pred, deprel_pred, tag_pred, forms in zip(label_preds, deprel_preds, tag_preds, texts): + labels = [D_Label(label, deprel, self.encoder.separator) for label, deprel in zip(label_pred, deprel_pred)] + linearized_tree = LinearizedTree(list(forms), tag_pred, ['_']*len(forms), labels, 0) + + decoded_tree = self.encoder.decode(linearized_tree) + decoded_tree.postprocess_tree(D_ROOT_HEAD) + head_preds.append(torch.tensor([int(node.head) for node in decoded_tree.nodes])) + + + # resize head predictions (add padding) + resize = lambda list_of_tensors: \ + torch.stack([ + torch.concat([x, torch.zeros(mask.shape[1] - len(x))]) + for x in list_of_tensors]) + + head_preds = resize(head_preds).to(torch.int32).to(self.model.device) + + return AttachmentMetric(loss, (head_preds, rel_preds), (heads, rels), mask) + + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + if self.args.encoder == 'lstm': + words, texts, *feats, tags = batch + else: + words, texts, *feats, tags = batch + mask = batch.mask[:, (1 + self.args.delay):] + lens = (batch.lens - 1 - self.args.delay).tolist() + + # forward pass + s_label, s_rel, s_tag, qloss = self.model(words, feats) + + # compute loss and decode + label_preds, rel_preds, tag_preds = self.model.decode(s_label, s_rel, s_tag, mask) + + # obtain original label and deprel strings to compute decoding + if self.args.codes == '2p': + label_preds = [ + (self.LABEL[0].vocab[l1.tolist()], self.LABEL[1].vocab[l2.tolist()]) + for l1, l2 in zip(*map(lambda x: x[mask].split(lens), label_preds)) + ] + label_preds = [ + list(map(lambda x: x[0] + (x[1] if x[1] != NONE else ''), zip(*label_pred))) + for label_pred in label_preds + ] + else: + label_preds = [self.LABEL.vocab[i.tolist()] for i in label_preds[mask].split(lens)] + + deprel_preds = [self.DEPREL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)] + + if self.args.encoder == 'lstm': + tag_preds = [self.TAG.vocab[i.tolist()] for i in tag_preds[mask].split(lens)] + else: + tag_preds = [self.TAG.vocab[i.tolist()] for i in tags[mask].split(lens)] + + # decode + head_preds = list() + for label_pred, deprel_pred, tag_pred, forms in zip(label_preds, deprel_preds, tag_preds, texts): + labels = [D_Label(label, deprel, self.encoder.separator) for label, deprel in zip(label_pred, deprel_pred)] + linearized_tree = LinearizedTree(forms, tag_pred, ['_'] * len(forms), labels, 0) + + decoded_tree = self.encoder.decode(linearized_tree) + decoded_tree.postprocess_tree(D_ROOT_HEAD) + + head_preds.append([int(node.head) for node in decoded_tree.nodes]) + + batch.heads = head_preds + batch.rels = deprel_preds + + return batch + + @classmethod + def build(cls, path, min_freq=2, fix_len=20, **kwargs): + args = Config(**locals()) + + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + CHAR = None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + pad_token = t.pad if t.pad else PAD + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t, delay=args.delay) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True, delay=args.delay) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len, delay=args.delay) + TEXT = RawField('texts') + TAG = Field('tags') + + + if args.codes == '2p': + LABEL1 = Field('labels1', fn=lambda seq: split_planes(seq, 0)) + LABEL2 = Field('labels2', fn=lambda seq: split_planes(seq, 1)) + LABEL = (LABEL1, LABEL2) + else: + LABEL = Field('labels') + + DEPREL = Field('rels') + HEAD = Field('heads', use_vocab=False) + + transform = SLDependency( + encoder=get_dep_encoder(args.codes, LABEL_SEPARATOR), + FORM=(WORD, TEXT, CHAR), UPOS=TAG, HEAD=HEAD, DEPREL=DEPREL, LABEL=LABEL) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if CHAR: + CHAR.build(train) + TAG.build(train) + DEPREL.build(train) + + if args.codes == '2p': + LABEL[0].build(train) + LABEL[1].build(train) + else: + LABEL.build(train) + + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(LABEL.vocab) if args.codes != '2p' else (len(LABEL[0].vocab), len(LABEL[1].vocab)), + 'n_rels': len(DEPREL.vocab), + 'n_tags': len(TAG.vocab), + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index, + 'delay': args.delay + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser + + + diff --git a/tania_scripts/supar/models/dep/sl/transform.py b/tania_scripts/supar/models/dep/sl/transform.py new file mode 100644 index 0000000..8603cb8 --- /dev/null +++ b/tania_scripts/supar/models/dep/sl/transform.py @@ -0,0 +1,102 @@ +from supar.utils.transform import Transform, Sentence +from supar.utils.field import Field +from typing import Iterable, List, Optional, Union +from supar.codelin import D_Tree + +class SLDependency(Transform): + + fields = ['ID', 'FORM', 'LEMMA', 'UPOS', 'XPOS', 'FEATS', 'HEAD', 'DEPREL', 'DEPS', 'MISC', 'LABEL'] + + def __init__( + self, + encoder, + ID: Optional[Union[Field, Iterable[Field]]] = None, + FORM: Optional[Union[Field, Iterable[Field]]] = None, + LEMMA: Optional[Union[Field, Iterable[Field]]] = None, + UPOS: Optional[Union[Field, Iterable[Field]]] = None, + XPOS: Optional[Union[Field, Iterable[Field]]] = None, + FEATS: Optional[Union[Field, Iterable[Field]]] = None, + HEAD: Optional[Union[Field, Iterable[Field]]] = None, + DEPREL: Optional[Union[Field, Iterable[Field]]] = None, + DEPS: Optional[Union[Field, Iterable[Field]]] = None, + MISC: Optional[Union[Field, Iterable[Field]]] = None, + LABEL: Optional[Union[Field, Iterable[Field]]] = None + ): + super().__init__() + + self.encoder = encoder + self.ID = ID + self.FORM = FORM + self.LEMMA = LEMMA + self.UPOS = UPOS + self.XPOS = XPOS + self.FEATS = FEATS + self.HEAD = HEAD + self.DEPREL = DEPREL + self.DEPS = DEPS + self.MISC = MISC + self.LABEL = LABEL + + @property + def src(self): + return self.FORM, self.LEMMA, self.UPOS, self.XPOS, self.FEATS + + @property + def tgt(self): + return self.HEAD, self.DEPREL, self.DEPS, self.MISC, self.LABEL + + def load( + self, + data: str, + **kwargs + ): + lines = open(data) + index, sentence = 0, [] + for line in lines: + line = line.strip() + if len(line) == 0: + sentence = SLDependencySentence(self, sentence, self.encoder, index) + if sentence.values: + yield sentence + index += 1 + sentence = [] + else: + sentence.append(line) + + + +class SLDependencySentence(Sentence): + def __init__(self, transform: SLDependency, lines: List[str], encoder, index: Optional[int] = None): + super().__init__(transform, index) + self.annotations = dict() + self.values = list() + + for i, line in enumerate(lines): + value = line.split('\t') + if value[0].startswith('#') or not value[0].isdigit(): + self.annotations[-i-1] = line + else: + self.annotations[len(self.values)] = line + self.values.append(value) + + # convert values into nodes + tree = D_Tree.from_string('\n'.join(['\t'.join(value) for value in self.values])) + + # linearize tree + linearized_tree = encoder.encode(tree) + + self.values = list(zip(*self.values)) + self.values[6] = tuple(map(int, self.values[6])) + + # add labels + labels = tuple(str(label.xi) for label in linearized_tree.labels) + self.values.append(labels) + + + + def __repr__(self): + # cover the raw lines + merged = {**self.annotations, + **{i: '\t'.join(map(str, line)) + for i, line in enumerate(zip(*self.values[:-1]))}} + return '\n'.join(merged.values()) + '\n' diff --git a/tania_scripts/supar/models/dep/vi/__init__.py b/tania_scripts/supar/models/dep/vi/__init__.py new file mode 100644 index 0000000..18dc355 --- /dev/null +++ b/tania_scripts/supar/models/dep/vi/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import VIDependencyModel +from .parser import VIDependencyParser + +__all__ = ['VIDependencyModel', 'VIDependencyParser'] diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..78075f4745b4926add51043c086c330542182c05 GIT binary patch literal 287 zcmd1j<>g{vU|`^9Uz9$Ffq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$1j9UCQVUY^Qd0AhD}D1*QgbvJZwVm_ z1|$|0rxq1~>?mSpU|{gmWWB|j3sMOdyTw)jQ2>&=#U3A@n3EG9zmlPdoq+*D{BqUL z$j?pHFG(!POw3EvOUg-1$xJQMPtMOR$k$CTDA5I*re9oIkXWP-W*6(Hq!#FxW$MSr lXXa&=#K-FuRNmsS$<0qG%}KQbIlY*Tfq{XCiHDJg2>>_3NX7sF literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01b920378d10fc9cdbec8a67d9522ea76e4b0702 GIT binary patch literal 356 zcmZ3^%ge>Uz`&q%Uo~S60|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w*<pHT~Z5D^HNgtk}G}lQ&Mv@8E*+83kD<> z6{i*zF*7hQ6tOTcF!*V*-eS!KsRWDNVk>|s0Lk5AkB?8x$%&6&$?zHEs$aqS8Tq-X z`Xz}anTdIcdPzBnDVeE7`pNmZ1^K!qsTC!<sbz^d`Xz~ZnThem$wiq3CB^#1r3Hya z`d}-H^;1#{^vg2!<Kr{)GE3s)^$IF~aoFVMr<CTT+7)p#Fff2TQf$S*!0>^Yk&*EO l8v~>21qKylbb~?d0xEjIEq6h|<N}vz13L&7aWXJ4003*_Vxs^6 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a980f9eebf2cc021c1f6a146c773ebb86340a75 GIT binary patch literal 10828 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d903b7c1fad5509a97624f635495068bf48f4a90 GIT binary patch literal 14278 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..daf22311cfc35994234b5e1731ac3cb9e418b269 GIT binary patch literal 4732 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 WBZ@&;MSzKeiHC`Y5dk@vM3@0cNiekl literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94aaa00287400fd00c2dabd76be8508ea9161706 GIT binary patch literal 8333 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/dep/vi/model.py b/tania_scripts/supar/models/dep/vi/model.py new file mode 100644 index 0000000..8ad8c3a --- /dev/null +++ b/tania_scripts/supar/models/dep/vi/model.py @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- + +import torch +import torch.nn as nn +from supar.models.dep.biaffine.model import BiaffineDependencyModel +from supar.models.dep.biaffine.transform import CoNLL +from supar.modules import MLP, Biaffine, Triaffine +from supar.structs import (DependencyCRF, DependencyLBP, DependencyMFVI, + MatrixTree) +from supar.utils import Config +from supar.utils.common import MIN + + +class VIDependencyModel(BiaffineDependencyModel): + r""" + The implementation of Dependency Parser using Variational Inference :cite:`wang-tu-2020-second`. + + Args: + n_words (int): + The size of the word vocabulary. + n_rels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [``'char'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 100. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .33. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 800. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_arc_mlp (int): + Arc MLP size. Default: 500. + n_sib_mlp (int): + Binary factor MLP size. Default: 100. + n_rel_mlp (int): + Label MLP size. Default: 100. + mlp_dropout (float): + The dropout ratio of MLP layers. Default: .33. + scale (float): + Scaling factor for affine scores. Default: 0. + inference (str): + Approximate inference methods. Default: ``mfvi``. + max_iter (int): + Max iteration times for inference. Default: 3. + interpolation (int): + Constant to even out the label/edge loss. Default: .1. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_rels, + n_tags=None, + n_chars=None, + encoder='lstm', + feat=['char'], + n_embed=100, + n_pretrained=100, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.33, + n_encoder_hidden=800, + n_encoder_layers=3, + encoder_dropout=.33, + n_arc_mlp=500, + n_sib_mlp=100, + n_rel_mlp=100, + mlp_dropout=.33, + scale=0, + inference='mfvi', + max_iter=3, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.arc_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout) + self.arc_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout) + self.sib_mlp_s = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout) + self.sib_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout) + self.sib_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout) + self.rel_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout) + self.rel_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout) + + self.arc_attn = Biaffine(n_in=n_arc_mlp, scale=scale, bias_x=True, bias_y=False) + self.sib_attn = Triaffine(n_in=n_sib_mlp, scale=scale, bias_x=True, bias_y=True) + self.rel_attn = Biaffine(n_in=n_rel_mlp, n_out=n_rels, bias_x=True, bias_y=True) + self.inference = (DependencyMFVI if inference == 'mfvi' else DependencyLBP)(max_iter) + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor, ~torch.Tensor: + Scores of all possible arcs (``[batch_size, seq_len, seq_len]``), + dependent-head-sibling triples (``[batch_size, seq_len, seq_len, seq_len]``) and + all possible labels on each arc (``[batch_size, seq_len, seq_len, n_labels]``). + """ + + x = self.encode(words, feats) + mask = words.ne(self.args.pad_index) if len(words.shape) < 3 else words.ne(self.args.pad_index).any(-1) + + arc_d = self.arc_mlp_d(x) + arc_h = self.arc_mlp_h(x) + sib_s = self.sib_mlp_s(x) + sib_d = self.sib_mlp_d(x) + sib_h = self.sib_mlp_h(x) + rel_d = self.rel_mlp_d(x) + rel_h = self.rel_mlp_h(x) + + # [batch_size, seq_len, seq_len] + s_arc = self.arc_attn(arc_d, arc_h).masked_fill_(~mask.unsqueeze(1), MIN) + # [batch_size, seq_len, seq_len, seq_len] + s_sib = self.sib_attn(sib_s, sib_d, sib_h).permute(0, 3, 1, 2) + # [batch_size, seq_len, seq_len, n_rels] + s_rel = self.rel_attn(rel_d, rel_h).permute(0, 2, 3, 1) + + return s_arc, s_sib, s_rel + + def loss(self, s_arc, s_sib, s_rel, arcs, rels, mask): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of all possible dependent-head-sibling triples. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + arcs (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard arcs. + rels (~torch.LongTensor): ``[batch_size, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + + Returns: + ~torch.Tensor: + The training loss. + """ + + arc_loss, marginals = self.inference((s_arc, s_sib), mask, arcs) + s_rel, rels = s_rel[mask], rels[mask] + s_rel = s_rel[torch.arange(len(rels)), arcs[mask]] + rel_loss = self.criterion(s_rel, rels) + loss = arc_loss + rel_loss + return loss, marginals + + def decode(self, s_arc, s_rel, mask, tree=False, proj=False): + r""" + Args: + s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible arcs. + s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each arc. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + tree (bool): + If ``True``, ensures to output well-formed trees. Default: ``False``. + proj (bool): + If ``True``, ensures to output projective trees. Default: ``False``. + + Returns: + ~torch.LongTensor, ~torch.LongTensor: + Predicted arcs and labels of shape ``[batch_size, seq_len]``. + """ + + lens = mask.sum(1) + arc_preds = s_arc.argmax(-1) + bad = [not CoNLL.istree(seq[1:i+1], proj) for i, seq in zip(lens.tolist(), arc_preds.tolist())] + if tree and any(bad): + arc_preds[bad] = (DependencyCRF if proj else MatrixTree)(s_arc[bad], mask[bad].sum(-1)).argmax + rel_preds = s_rel.argmax(-1).gather(-1, arc_preds.unsqueeze(-1)).squeeze(-1) + + return arc_preds, rel_preds diff --git a/tania_scripts/supar/models/dep/vi/parser.py b/tania_scripts/supar/models/dep/vi/parser.py new file mode 100644 index 0000000..3808a3d --- /dev/null +++ b/tania_scripts/supar/models/dep/vi/parser.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- + +from typing import Iterable, Union + +import torch + +from supar.models.dep.biaffine.parser import BiaffineDependencyParser +from supar.models.dep.vi.model import VIDependencyModel +from supar.utils import Config +from supar.utils.fn import ispunct +from supar.utils.logging import get_logger +from supar.utils.metric import AttachmentMetric +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class VIDependencyParser(BiaffineDependencyParser): + r""" + The implementation of Dependency Parser using Variational Inference :cite:`wang-tu-2020-second`. + """ + + NAME = 'vi-dependency' + MODEL = VIDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + tree: bool = False, + proj: bool = False, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + punct: bool = False, + tree: bool = True, + proj: bool = True, + partial: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + tree: bool = True, + proj: bool = True, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, _, *feats, arcs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_sib, s_rel = self.model(words, feats) + loss, *_ = self.model.loss(s_arc, s_sib, s_rel, arcs, rels, mask) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> AttachmentMetric: + words, _, *feats, arcs, rels = batch + mask = batch.mask + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_sib, s_rel = self.model(words, feats) + loss, s_arc = self.model.loss(s_arc, s_sib, s_rel, arcs, rels, mask) + arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj) + if self.args.partial: + mask &= arcs.ge(0) + # ignore all punctuation if not specified + if not self.args.punct: + mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words])) + return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, _, *feats = batch + mask, lens = batch.mask, (batch.lens - 1).tolist() + # ignore the first token of each sentence + mask[:, 0] = 0 + s_arc, s_sib, s_rel = self.model(words, feats) + s_arc = self.model.inference((s_arc, s_sib), mask) + arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj) + batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)] + batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)] + if self.args.prob: + batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, s_arc.unbind())] + return batch diff --git a/tania_scripts/supar/models/sdp/__init__.py b/tania_scripts/supar/models/sdp/__init__.py new file mode 100644 index 0000000..633e238 --- /dev/null +++ b/tania_scripts/supar/models/sdp/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from .biaffine import BiaffineSemanticDependencyModel, BiaffineSemanticDependencyParser +from .vi import VISemanticDependencyModel, VISemanticDependencyParser + +__all__ = ['BiaffineSemanticDependencyModel', 'BiaffineSemanticDependencyParser', + 'VISemanticDependencyModel', 'VISemanticDependencyParser'] diff --git a/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02080dfc284fa4d868f12d9e49fca7f0775a90f5 GIT binary patch literal 396 zcmd1j<>g{vU|`^9Uz8re$iVOz#6iYP3=9ko3=9m#It&a9DGVu$ISjdsQH;4vQA~^= zK2r{JE=v?kE^8DkBSShv3iBeyD7F-qU<OUrmy8Sy44O>0<ef4T)6z2YQiD@-6Z1+k zlU-5^Qu9($^O7rl^HWlDZYkha5Rh0@oLZ#GbW1YK6PI==Y*J8-EJYv>6frX}Fch(X z2v!CL20u;qTO3JHM<Ep4Vk*l-D7wWSAD@_$6Cb~lp@<Wt6GZ%S($C1xP1P?+EXhpF zOVmrsNleL1Ez(cU&n?K;O)n_X%?0^Lzqqs@u}B}xF4iwjDbSCP&&<m#iI3MSsJz8t ZlbfGXnv-e=3ZG&&1_lNJCILnsCII-mY&rk{ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f809f66bbc799ef64855403f747872f7bcc4dc85 GIT binary patch literal 487 zcmZ3^%ge>Uz`&q%Uo|6uk%8echy%k+P{wCH1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL zb1q91OD<~^D<eZXLkjaE#wfNFmS6@=)|ZS73=En~x8$8N6VuW%^HPITa})DQGLv0W z3sUn^QuC54ee+XNb8ac%RuGU_RGeC*$#hFH%oCS(DQr?ujVwjX3=9lKEFgjvM6fY1 zF!*V*-{MGuItroS7E@Vf5nRzN_W1b3oSgXhl?<Ojq3|m}KO;XkRlg*$Br`EDQ7<Vc zF(os#NIyA0w;*4)B(<VMH?=G=N53R7FEcT|IJqdZprly8xU?X#NIw_k&0_uHlmh+u z_{_Y_lK6PNg34bUHo5sJr8%i~MZ63Q44}{|4q#wl_`uA_$oPScfiZ&d0z)_^y20Rj Z0UP?j!pQB$_<;dIHn4+W5jO(^0|4UdjUNC2 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/__init__.py b/tania_scripts/supar/models/sdp/biaffine/__init__.py new file mode 100644 index 0000000..ab2feee --- /dev/null +++ b/tania_scripts/supar/models/sdp/biaffine/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import BiaffineSemanticDependencyModel +from .parser import BiaffineSemanticDependencyParser + +__all__ = ['BiaffineSemanticDependencyModel', 'BiaffineSemanticDependencyParser'] diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4845ca571234eecab6e183073d4864e1ec667a85 GIT binary patch literal 321 zcmd1j<>g{vU|`^9UzC1@fq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$<ef4T)6z2YQiD@-6Z1+klU-5^Qu9($ z^O7rl^HWlDG#PIx;8qflSX7)^R0OiWh?#+b!B3O*7Hcj@A6V=bTLDA?NbVMUe0*X~ zPJH}Ih9Y(b1_<%XTR$T|H&wqRu_QAwFHtWkCov^6wMaiXKer%XH@%=l7i^k-acMzf zkv^DRtY4f`pq~VFwtjqkW?p7Ve7s&k<t+}I-29Z%oK!oI=Ze`F7#Mh%co=z@06(-= A)c^nh literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9896718732a155aafb0ff99c6979f1448f90fcda GIT binary patch literal 390 zcmZ3^%ge>Uz`&q%Up3<j0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#x8$8N6VuW%^HPITa})DQGLv0W3sUn^QuC54 zee+XNb2J%mDd1KTkXTflT2#c$z`#(%!oa}br^$MYH5a50EOv{n0HOdScZ)qfJ~1aJ zK7J*`XON43Me1kd=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>z1Tel<20GCFbatB<5u% z#uq0SWfqha>lc?6Bo^s|tti$nPASk&g1TQnK0Y%qvm`!Vub}c5hfQvNN@-52T@g0} z0|Usb#a0Xq3?G;o85uvYF)$imU@$^PHyBJVprQxdIv4Z;E^q}lu!CR`Cj$cm0Jnp2 At^fc4 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3927ea658cbef06b9e352886b378c4743b3c16b GIT binary patch literal 9519 zcmd1j<>g{vU|`^9UzGk*je+4Yh=Yt-7#J8F7#J9eJs21mQW#Pga~N_NqZk=MY^EHh zT;?cdFq=7tC6_gdHJ2@l4a{fBVbA4=;$UQOXGmd9VQXPXVM}FhW{%=aVGL%_WPb^= z!%vg(7OQW5N@|WK(=BFSpMYB&PML{mX_<McnvA#Dob&V2GSibmDv_}QlvCWrz`&5o z5XG3n5XF?j7{#2z1cuD%3@I#&7(uqCu%@u5aHMdiaHVjk@T4%M@TTyk@TYL52&8bP z2&M?72&ZtRh@^<5h^BC*h^26*h^HyEGo&%5NTf)%a7MADD5XfHNVhOXv8E`c$fU@& zFh;SZ$fd})FhsGZD5NO1Fhp^*Gq5m3aRxJJD&LZaxjr~GH!-gyGub7zAT=)~H7~gm z?8`(4AqEC61qB6#kc?D?%-n*U)ZEm(lEjkC{5*yHGzFM;1(<#XgaHZxiABY!MG98Q znI)-K2`Twii6y$ZiFtXMdFi@F28I^8#b5)A67;yhRyY==7h8c@APe*2%kzs;iWM|6 z^GY-k!XPP-TZ%KQQb8^#$w*ZIDO4!SPfkoK%}Fe()I%~OCow5C2d5!<rMXF|MId9K z>N4{bKn9i+rKTn&=4B(BRFarZggF8J!3rRiItoRpg{7HAsVNGXX$nwLh1A@n)RdIW zy!2v)#G+J%(&E$<Jq4H4w8YY!5-Wv-1i$>e)Pw|NTaz;qi-@omq%1MHB(<m*)nd4~ zZcb`hYK}rtYC%zIF)Rj&c12EVZf+tG&VZ;xbplw7WS^(zCFiH47Aa^HmlUDJzAIF! zBp(!jh`<7+jD!UBoZ^yP^@Ic~1*c4(;1FL0s7V;=l2VIGAnII$LUeO7vr`ocic(98 z5;OBsQxtL%^U_Nb(^D04L781aBQ3v30hG&2N<qn2Q%50HFI`VZAt6B>WR7l9VsWZ& za$<36iaK)qft-XCy)d^S+>(}>SfZfelUZC6U0hNWi{?|ul$1<RPD{*D04XdjN-b7^ z_!>2c6B3}Fw8gXm<b;F-^^(MNuxBw-BEm6HrJyteR_mORSOiW~I1*24MG06wMIotD z0i+ld-WbM#;~#9E4=5EOr34J6pr8b+baD*}K~JkX3i%}&sYSRWsaOFVi9z`w-HG4~ zmY7qV4+^^C%%q%DRO{f;5)Fz(NbrE;6Y7018|L;{gx<V(a3&^HEP;z8uu5=tN6O`f z1_sEcA*DG2B^{DVu<2-d8QBUWQ)DYZX@@vhgH)ClrJ@HtveBrn2L%>!MuSv>6BAMb zP$*6<D$C4ES4b>Y$jmD!Ehz>S#juown#N0uK?-4VNG>u(2~LnT@fn#ZDXDpcq6n(0 zxFoS8l^lyvA`)zGL1IdLW?o8a1um;0lKE-iN~RzYToovk<Y%YmDL`u;kU5ZGLeytO z1_V+#q~_%2V=FrS5_92|CQ@>8_3_PDC`wJwEG|g}*I0Q92_P|7Saqf69}wc{@0WlS z><J0#`9+!OnR$sh@uo>Ar5?!k_@w;e_|*Jj1&xr>f}GUor2PCGjN(n91SAKF^OEv> z1(1@|#5{$v#GKMpP=ZLwOinBT#d>*0Dmd$x<SS&SrWPm^mn0UI=%?nTC?w^V=A|SS zWkMnlWU)eiX$dGLAu<4{ScB*GganO{qS90y1-HbU;#5uK!WvZiU<<V1g4E>9G>{eL z8JWo$3fY-?DIhnaRS~d)ndpikBqOs}A+s2zp@3A9gPfzDkf4xXqyS0#pkfVFn3aI) z0X=YoEUh#rM<FM(xI`g2F;5{WRUr)&9-y?8P*RkbSDcn#l$%;qoDh#QG%#BnAbaC; z5-U@&w>uD_k&$1nkeirSsgRRcT%rKg0Sg7>)(`QXf;ZeiaRzGTrGe5HEJ_v1^GkD5 zK;A4*%}mcINlj5GF3kl+1*px2k)2C2Qj1fe?!w`J6NGqfW<`8TQGP*wX^DbHT26i< zwnisRK@q3{46+y;ClIfr=2GJQjA;MqA?09jEEMGD=YY~bmPSwjRH{6&64WF}Pc4C# zBS>`)N@yk|q-7Qrmw*~ZC5hRo;1UQdqEK9#1TKQ~6cQ3ZQHi1iB!HqKH#IR2t|CzZ z#8t>IOD$4J%*oM1u@NcHfmESqwRj3kOK{NRDkO;ye(X+0iV0||FI7PUR6wD%&^*%= z5)!~gNkW2-LRwL3YE^16C@2&P5{nXZQ!!iQki3jk_(D<-O34Z}5D}bt@dY`##MQF_ zKE6mbte%2rnu382sG(d8j&kH~6Otp~sRq*CMRE;NNPrcQkx9T+JBp*=Nkh*F*^|&# zERpp$RJ8(1#z%6wp%H3Z1*#rT*#;_c5M4s3dRPg9$fw2#H$&Bs5hzfd5Yv%dt!Ip6 zd|rHNN_uL1ZcYKV7KLj{da8o2Pk;g_Qjv@>L-jYfYYR35n;|}+4l+SgV9p@NqcB%u zBy>IGW-8p3WLN>#3-$x19mv6%nOBlpRFIzoD!s8b51sS#ic1pnKxL^yYFTO?sOAA@ z8?X)fpiofA$uBNO3T!<?L~5Y0L<7}g;Fdk2R70`|DI=EVWs}g(EX~W#%P-G^)(_Bj zCT@ESp`$T+dJ6H#jR?dLOh!pbL9vy-etKp}Mro2>a(=FUMrnF_W?p()VsffJvL<lp z>UWC;)G60wzQtUUn0|`|)W*HV3hrCIOkrSPcv%Y~j2IXgGAA%HFcdK|FfgRcx4sVC zA$QgO7B^BeQ<Evg?Imb@FC99f#&C-TRJXXL&zcDWC+#ygurM&ZWCocP!NkA-Rd>N2 zs$i%6OOWZw$}s&53=Ap^3=C`x3=G_$F~emH3=Aa<%?w$LDQuYxB}~l>3z$n-ni&={ zE@A9rWMn8|tzpPw%VMvQsgX-zOkwI}sbPrcz$(fK7nQA%hpXknD#~5LQzMhYoWhdA zlEMl$ledJYMz)3tNrbP2e}TY4h8l)=!4wA2h@_vJCd)0By!gz#TdaBU`K2Yd*r5%S zTU?3BC7EU5bpDcwfq@}Jlch+Qfq|h&gn@zK7F$wgVsU&0l&)OKpeb~VwYan(wdfW{ ze0*kJW=VW}5i3|_X+cV2N$M@Ooc!d(oZ=!-z}{j>EJ`oFC6E^nEyJMY^(`(?{s0v; z@hM2`j9c8`+yj+B;$#$oqVg6eSX*LAN!~3kh)OV<DKGDqfOAoPaj|P&Nl|`5rB8lw z@h#5eqRf)iqRjj}O_f_L#i==Ix7eX0g||5J;=%fhZ?WaYg9hP1QlP|E43+|oJ`~?# zhdTNe3#hXTQUR{kZt>*BBkDsC4<rq#azQ+hF;E_FUObowsdsMifjRK3e~SmqheZSn zs84c>2SmcUM7LN#jk{aCdGR0`S{>cuMrwfG;sMJ*n}4_XAUs&-@)ifINpg!DsbO%7 z7wi#O@mT~KbViOONYQwUAL@UYx+pG0B?B@K9D<;@iV^_FOKwg9T&W;j5+-zu7o|+S z#fb<9PIxJGi!Hkxlw?*i-r|gpPtHj!E{=~cl44+B_~oIWk)NBY4;oNT%uCcu%1KPg zOfAw+&d)8#*G(@d(FG5`=@*w4Bo^s|*~R+BDFymT&_Q>Im|j6;kqmffoq?fPfPsNQ zMn#NCj1dHdn1mSl7^^g31J$r`YQ!)#c$`}gmh6*3xdm1@fY_iU>I^CwTo@P_Y8X=( zN*Rk3N*J;j7ckW@E@Z4>h-a>0%wkDllw_!3$YRZ6%Vq}2FJMO%UC0C~Cu%_XmdUS3 zh=GAYle0)2l*KsVz3f~3X+`<D$jOikDM_*xXCxM+7RiHhu`x&^n@?t5YGTnXE=ar= z6y;}WG8Jioq*%d1;2?$&J|I#4oczQTB;%)myak#|;b7!r6k?QMWMQn*ClpX<W+a13 z1Xy^1%mS69;PA=;g%`sDh8o5iriDzk%ry)P7;BgpGS;%xFf3pKvsh~w7BGWZY&8rE zSimgy8ioa|H7qr(3z-(Mfl5tKsko4(mZOGY0ecNw4Lh1RXAMUUXBty5gC=X@O(y7M z1*rRoI-39z0o8fM3L14K`9;YYdOrDi=^?3k#rZ{=prQBZq{NcsjQHZrs#G0?;?%<U zoYcHn<UR|?1P~6-FG^9!%uC5kPAx`M{U8}oiBSw4&Bd?;eeeUM!4cAT&rbt)>#-XO zQU_|6f*b}KElAA-4}~NoU~{mJLRw}8)a9UghlB)>n-UU08WR%KK_wG(NC7%<t)7se z1FoY%*1&Lnkpgz(V?o0aAnVIBi_wNtL3-h>dc;Hq-0Yy#lG36)r0E@y252BbVnIg% zg^OrzfK-AoC=?()))H{Ef%@OzJb}Zt@MzRgFao(eBR?mlSfMyMA2f`fp9blr<rjm; zh7~|%9a?n4>?}@A&WDWn5NTT;v>Jk23J(R4ksyr25#ZvrSRp@8AvG~M1MDV53IjKb zio`+LUl2rq%MgxRY|!#t5hSJrB0z1MB2c5INEMXp*$YyOa!X56i_}1c4i~h50Oy5U ztf1ske2cLniVYM1@hMO`BZ?jDmiQDHBjXlZF}O2wi@g})JxIX<D#eSyr3-sneo=X1 zQOayksRAm5d4#x_xEMiDf?0xzgQ-fLP}u@CAsN*4fR!m63=9k)KDbN?1C=Sv3m8&B zB`=EuLoKKTVXR@SVUc90VFi&3m=-cDWU2*~CyX^rHLQ{hHOwG#AyX}T4MP@l7E2Ag z2tx`Jge}2P!zRKY4l0$I6SMJ`9uV)tiw{Vm#aVQqB|bznf}$UUgNaUu(C{Y1W~78j zv;)BLjw=m<91c}LLNN*t3#{cSC|e^kbb5YHiY}-RmXcTmnuSYB%|XkSxrxQu@UU>o z&(9$c6F4me8w8ryO9qW!fyUWD9k9|o(71eR3Z%PK4DAeoJWjX>!(L{ArxZcPgL{tf zvH+5w!MT|A7E^j^ktQg&vgG9Fr9&!tH&A}%0O!}DC{V_Z1}R{Jg#RrTkn^J;ZD%AV z$PQRD8pKA=r7R%9-JmQA%2<4Y5{x2@GK^I!gt8_`8%kXds`ugfQVx_anIQRc0b>m# zl*N?7w2(1{aUrO7W=@>Ph_`kg$@vSODDb5*M1uu0odp!7rer3AM#Le>gXp>uC3n31 z|NsAgNaK|G7F%LbdTwIHEgn$nN==DR%go7%zr~bOqREVwCehOvTS_Wu^8O+ym4TYj za=cY)gwhv8izcI=CKsp=nwOZH8Xtd)D?UCqKczGW#O8^QFDy;Wfy%JQ$EV~c$H#-) z{Y4?5>=6SZl0XEg*MEx_+SN!-&B=jwHy{r60x1DiSw*0>DksR5ehdr@91JXsOmR$% zAjk$LK`hcR-#spUE_MzD0Wq-IAiqEwn|XPV#y&T=C!+`M$rORY<`yqpq%<cL(!qvw xi=j$OOEPnc!JToikq|F{Yh5q_^2aR>8%QYGfyOq9L9K8eCLTrsMjl2HW&jcx>J<P0 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c1c571e2bcd578989340f70f59cc638e9cb644e GIT binary patch literal 11764 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 JV57hR1OR(;uR8z$ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9143362fa65ddfd6a27203f97dd01c2a6a45f3e GIT binary patch literal 8024 zcmd1j<>g{vU|`^9Uz9#wj)CDZh=Yt-7#J8F7#J9eFEB7Lq%fo~<}gHoXr>&-T&5_d zT;?cdMi8Gdhb4+7g&~DGhc%ZiiVZBrlEa?M5yb&!v*vK-az$~0*=#x7xja!kxx7)l zxqMN4U@`U_{#=15fn32T!CavzA+Q)nj&QC>lt`{<lxVJ4lvu8KlsH(NGe;s<GD;H6 z=E{-Em5!1Iv$=C*a%H1r!EBx!xm@`uc}9j*$y9}A#wbO1h7{fuz7~cQzErMe<|w5U z#$X0b{+A%X`e`!V;_xg<ElNzvNxj7ynwOcMr^$GW)j8kK$48U#mb_DDVp>{eUTSb^ zZem_ZX0l6aL26z~YF=`sZ+=Q@jwa(Rwt&Q<;?yEd=38ve`FUxX>9^Qj5=#<`Q%i1f zy5=UOrle%%rE4<ZVs`QmzQr8i=yHoW)X!U!<rbH7Mq*KkTV`rb$}Lt1#SxTP4q@>G zmnN0x7o~uCnvA!&(o;*~bMn*EQ;ReiZ*haQ`lgl?WhQGf-VzBZO3W)x%P-1JEegrc zPR+}#0xM&6N-RmvNCtTn8B0Pr#Z`<945<uJj42FJOeu^}%qdJ!EUBzfZ0!tbj48}1 zEG-;S?3}EeY@F<z9Gsk-T%6pT+?+fqhAF(M9I2eCTxm>_pg={i`H{p0Qn^zEQ@K-w zQn^!vQ@K+_Qn^z^Q@K;bQh8FuQ+ZM(QhCxOz&1&yNVV`r@p7_rO2h3iN|8Y_3uFd1 z{d{2kvMF*cyit6d@|^OV+$g3PqnM(Q%9)~=%9)~+$^&*4HWNj_CMu_>wD3mpr>Le1 zq^P9|W(lRSq^PH8w6H`8rwT3*S;zpD5lv%B(M-{5VQFTJ5<`&@NMlLSPSF9&h^I=V zn55{Z7_=}pGe$|aGq5m3Nd+@#n%+{toxC8asw$mJK|w(wBqLQJGq)foH8(Y{B(Wqj zKTjb)4X#-MmN*p<sZ#->U%@Ilvn16jAtk>mu|zjFF)uGOFJ0Hjz|cas7;Iosf*#n0 zDw!l`O4luhCUxBucv??pgeDmf#mvCK04f{!L1lvp0|P?|Lo-7bV+~^_Lk-gs#y&<y zh8l(}rYz<fhInQ$i=~Dko)yeut6_*|PhkjVSjp(8$#ILdxU?X(=oUwOd}dx|Nqqb* z&JtKkzQyX}>g(%xi#Y(4Z9*K~Z?Oh=xH`JrV)b!!a`n+<zQt0Unv-^mC9x>I_!e7s zIf!1#c#AVWJ~=0`xHvw3CBrXI{fzwFRDDp8CFUjSCFLZhWTqDBC+FuD<m;vvl<4My zGO>PfX+dI<KA2ssUz}2)4+{(Z0&w2eE2u1zU|?X71NoSPfq_AYk&B6ok&m%TlTZZe z!MyhJ1v3M~%M=C%hL;_}3=A(pA^K8*fq|h2#BvL{#adF7n3;ErIVH917E4KLamg*V z)PnrvjN)4y1&Jk@sd>q%x44o(89Kf=vnur#Pia9)Vo7RzaY<@H@h$eG(&X&alHyzJ z<@rU~sYS)Nm=kjgZm}jOCTFDHVlPWAO3E)zP38qfAQba4Ffgz&Ffed4Ffe?UfyZMC zV<tlhQ!~Q?<`R}>hJ}ov7!77v$>dk0!oa|w$yy{1a<n#xU}s=pxWxu>$1S#;{N%)( zVokmxd5|1ffewhJ3nKJDgg%Hc01<{D!U#kdg9uP6Dl!GJ%s_-9h)@C%AS;VhK`fAY zAVx700|SGMK$RN7kOzn7OHg#(Vo6CXNlXSYp?+uJMDl!*ImiMFgzs)~q?RS-lqQy> z7J<B2WC@bD0?BhiJZA$E0DFWaKiD!bFo5iW_<@^<)B|&e-z}DcqSTaIEIEmJ=^%D~ zQZgvsVBX=u>m7EG-pu3@bl>nG`Nj_9C3_G7s`HCT_nadG1A_}FgMcH5uS$bp1VLSO zixr%zZ?P4nmXsFdC4=<C`~{09XOO`$3=9l4j1w5+7;BkonQK{U7_%5^S!-AqFs3jr zWCYVp3mF|4YFSg5YgkhlQW#p9Qkc`2Y#3@77BJN?)i5t)ieai{t7Qk3MGKf~*lO5o zSZY`ovea_aa0D}GviKEgf-)$`1>kI{$#RP&H?cVT7H4T*abam{YE|kjR&Y6SizO$& zxL6aK9-KfKffZC=7vEw{OHC{(zQvZ4n3S4RT;vLpVk?eMO-WC^#a<i_7B2Dt1vEHu zg9%W=zQqMju;Bb00`e{>fATQ0F^Vt>FbXgVF|sgLX%h@ngc&H|2x{qpk}^0P+h`e% z3|UMISU@4Wkg1llgtdmFhI0X14J$uG3d=&K8Wse*nK_t2lNA!;MJ}N502PEU|NsC0 zUy~giY(;J$QFjml3a?viDXGc%DXB$5pdjT2#Y<{Rd|GBsjwTl*A%mi!$P=XA3q*K> z2vGPJ`G8oyAOdU<H#idFLFum;T&h6`a4c|wvK%-PVnLB0z`(%3!-R+gK1Kz`DlLN1 z05=3B7C@;PR0x4;(BdcHSb(HuP)e?0%wkMolwerEw2*;`sg|XdwT5K@GdN{~Xh_Ot zNnx%5wYA|XyM!f+wSysxt%D(pJ&PlSrI)E+fRUktVF4#{dJktvVPIikVQ6M%WXR(% zWGJ>PXJljm!AJ&>>MYI$T#z_hz+J<_&yd2pkg1jf+!SI<VQ=9m;i+M*;b>-ZVQ6No zVT|Vm+s0Q^kiwC|-ogNuWm~|X!n%-gfxtorxH`caP)nN=J&rXQZ?UK5fm+-tMg9y7 z3>d8oP&f&LLLXGlrZdzq#7f05)iTyHl`t$|1iOkMg|UUBhAD-qh7pv<K_sX#3JN=r z8y7N8WGZ9=<!BVMLHU}Mfq?;RHmEWOo6TK|Y$hW}KU6mphHg;12do>EZNa+vY8h)7 zQy8*Yi}*SivcT;iNrpVe6qpN`zy*n)CQ}i}!dt9m`N@e%noPHt^bBq>X0Bv}q+F13 z;Ck*BmrYJ)aS5n}Vpj+X0+5?k7^*@DCOJ@Q2B%v+8%RxTr-v{KI}@DjHJOUSKpBd; zD8IZY0+dJKjwy;{U|;~d0@O}mV_;$w`(NcrHJ5-3TR%<aB2cK_;!i5g%t?taO3eW` zaEouTmE?nhLX#QnzM^oDBUzI{eI}gF1Ql~^3~Wq%|HK%1{#V&i=2Vo}2jy8%C<KEd zMT3EX0UY}RkaStYl)?Z?gDH$45}Xnl7Baw65!9cIx0sU)N|C)&1g>hq!3`!r1rRvQ zOF@=^VqSwmQwUrZ-eSo~%_}YfRe|7Q@fK@Ieo=D9Esn&}lKkXEP-`(IwJb9^wFum% z1UIO_C1(IAMgu`%$6S?JPy{X$LDt@4FV0UZ$xW=d#a5b^l$n=ui?yIAKMAEuLn=$b z#b`XpEJRrv1mc1n4o)^8*WcoVC&LVoA3)7Y4kj^h9VW&o#3=J$f{BZfgNfrG2eSgG zMk8F5!VP>0s=!`~fC>yyf`K&=1Q{3@K+RfEbEvq88Ppv~QOIN{VQgjqHC=02OPI2l zOPI1)7O>VZE@UhaOkqr6N@4D0Vq^e|vVla49BWv!*oz%&7_vA(x@%a$df93ivN*wf zwk$4?NDW&&cMV$>_X3_8wk+N(z7!TohAe(iu~);ECAbjO^<fKUC=ps93@Qv68A?P_ z*h)l8#7e|dm{Qn#Svwh0IAU09*=sp!IcvFUxocRnBvLrDnTm=_Bx_i+q?#FPc}k>H z*lKvPWNLV_WNUb`<Z4*6<ZF0RxO&+-8ESa46gn8<74lNBm<%#av5cXpy+kC1r$ju3 zx0k7wJ%z7^H47v<twcJ7AL15}i75iTthF2|f>7BdB_b(85Lt*zYdKSdp>n%ZSW-lC zlya3j85tQ$R8oYS8Ed)P8QK}sm{LSj#9BCNxZ+h)IH9VqqxggqyH9GlK|ZPBj#nsA zOA#+o&(cVd=w+(qEm7}asNtyLs^Ly!so|_)ui;IR>}9FtE77b0`9mv>DU$&jH~i4B zW1hfRq}#!;fV~DJqFuw9#Xo_uh_ggz0SAb^kTH)jMJh!)MXZHkAqyiz4SR}IDdPmj zBFP$dkREWHaX`hCYdGLyoKP{{8cw(vFPz1?Ko@F1(*(vM`x3nlhAf3<#yn;aouyx* zSHlb9!)*&F(W_wxiGW;F1G6u>M6ZSeLo}s^Bg+7+4(5jZ61^HuxH@jA%PMNPA?i99 zvJ5&HvJ5*IvW!w>=5T@h1WJQ7e6tx~>=aoL3!a|A>3acBiE#%*id-|u5A!=1viL!^ zE@Z3~0P7Z*&5$BLmkFY;hP6hZhOe2qmJOW#1(4Ibreb0$69WTyAOSR7;RGtl6%rMa ziW2iubn{Znp`#Hx3YmGyIi;WhF$GYEKQl2WvkF|=gN8E_b8-|w{WOI%(2!WMLSkNu zLN2I(u27Izl$e`Zl3G-(#|5{<u_(RR3eE#rTaZ|ip`cM*QlyD04w3_npn&D`(-cZF zQlSQy<SQhlDikM{rKUiJK|o4DI5#sdKCLLV5T9|mnR%JHrMU_qb)}#YL4~~3)Rfc| zg_3-zKT{PF6-q$kaSEAvU|YeJe`!u)QKg=OOKMtTX-<iiIjYTRnHBLlsd)+-nRz8R z{E?ejp^%fBmtK+q3$|j&V4*@mW@>V3u^xE5D77LvwYV4*b|oNXsfo!M5P602%$yvM zze|cr^O6%w(ESebe^6>+X=YJsib7_ZLTPbkUb+Hk#L*`>#8=<RH7Eqt$si3d-zXRv zph`jpW)w7BGLy0S$5A0AGr2?|BR>b6DnL<FnwOlPS6rH#nxc?clwJxN@+wA{S;eHM zAEL>4izBrnv$!NaKO5Y>suBjLIgmp^MnF;!xcbs$xy4+Nm~xA`G%x!Wb5efsE!Ld; z^3)<tRzDE9#gdd-RHDgRlntuPazI2bsIp{-#=|WRa0G$|T$oD|({HhqB&HW@G8Taq zv4C15x4><ZVoeq_BZ>+@=CJ0Z=H@2eVgpmfw^&kha`QDAZ}EV;yzwRZ@tG;bDD4bT zCkWKm0Jkzhy^jvY8ir=Z1q>YwS&R!AgBgm%Km!p>x0p)ui;@@^7*;agVysxnbc-e2 zKggx1666DLoeZvyIc#zgbCXgM?UsOQV^E7ifT7BQV6zC^6hm%DLJR@79yA$mF{R~! zdd6=4LB2&&APc2Ige(ICgCB-pKvgxk%>?Ss)-Zrt@HGqz8KoKEJ}F871r&2}NlH;Q z$Q-ci!34+)MfD5}4C`R7=VQ?1y2YLs59w-i<UzXA#kbh<;z1Duk^;p^@hv_O6<?5; z5}%oul3H;Kq!bhr#kcrC5soCoiBQB@nwJe#&zY283}IFYp(HJEiFAuK6*RJci;)Y` zgf@YUtbm4yZZYK--{Qzk%uY?oEGoXm0xEQFv8QAf<t65(-eLo%+TvTR;1C84A|$5V zV)gZRarJ>T+(2!%Tl_isi7BA&DY!SEno<NBu`g-_1x_!Br~(n7xCafofu;m*v1I0@ z<rjg1xCqn^DguoM6@gmApq>`E(_92fP(}G5ouE{OEwL7bf+B(iG=6bQG%+V9H7_rx zKrc5xr8FnCSPztPA;}9g@Oz6L)J4fJPAvkpy&x@k$Q%V^*aOtfEz$;=#{nx#i$L8v z@L1X{=A6_#P@I7(fub&uo4P?n4@f<GMq+VdNlB5W;4S9loZ_O1Aes3f0+gYOz+;1; zHtsDp$lz=dsEv7x#o5C#2%H#ivAFv9`rl#!l~cDEOTgVONC1MIQv?cNaHJL0g3JUb zu_+7;3>Bax1|kH6q!@)51sFvb<rrBQxtN3)`53tvxfo>_xfq3*xEOgDxfn%2Y(@~9 zgHZq~%fZOUD8VSg#KWis76IvjU=~IhMh-?XMo<G7gjpCtkmDN<4;PaLqW~ih6CbE4 zOn5{SoM<#Ti_}0aR|gTGjtIDWQKSXpf(j2ew-8OXBCv!tvKXhIpBolorXo;7y(kk@ zs7QlG;z8*&KK>S0d^{xP<Ku7f#K#wwCgwn8*yH0<@{{A^Z?X6}`nnc@I@CqeKsJGf z$UzNohFi?VB}GM`(&iR(W?soHmZbdr9B^tV0u6x{frbi;Kn;0F)@KVz%`46?D)IwI ze_nokdQoBuc$B9IRB{xhgT%SPqx!k2B^miCMW6_~#S0zjPfpFriI0cGDY)1Gj~s&| zR+NE(0aRQTA7Wr&;9y{3WMN@p<Y8jsVPZsuET6fUnEr7wGyUaaVfw?w%JiFwjp-K? zJJU}l4yGSWoJ`-DxR|~%aWj2o;$iy2#LM@YNfcoM%MXxlCT6C;Oc=WPelQ6jR6<xR zUvaBPwvF$rhyWX>2qPPp2qP1}2xAe*Kbp!#{h$D0E2%8V%u5FcGdR>CfvF6h%mC%u z)SP0yl+*$}*kpztd~OAtU85vXR2HWoRD$F577s)on#(|a-&@=eq0*AfoMK3k2hQi9 zjD1T8Nlq_0KQ}i&4_pEv3Zy7OWF_D_8d7?I%Pml;QUofRZV4kR1I>AYyb0>&MWNV{ z3!eT2r;}Tv$XZ}Eb`iMDLz9EeFG14ZN>I9;0U|&_i<E}I2?>;jZgJQ^@_`*Fa}|RI faX6R+7&(}Dn0Od@7)2OG7$q1%ED+{k5@7}aEYHvZ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3e9e25a0966252386b63bb170c782847ca49afb GIT binary patch literal 14949 zcmZ3^%ge>Uz`&q%Uo~U890S8+5C?`?p^VRO7#J9)Go&!2Fy=5sfoP^2#$2W-rd;MI zW=0U7F^46JC50h{IfpfuEs6~+#*)LH%Mrx^X0zsS=5j@Gf!S<1+_^kaJh{A4yt#Z) zd|)y59R6H^D1ltTD8XEzC?T*IM~-l=NR&vfXq0HKSd>_<c$7F;oHIuvS29Wx%;w6G z%9W0i2D7<yWO8MrWWj8n9JyTiD0xN(CWchWRE1@X3=FFop}t{=Qe<LqXGq~~VMyUi z<yywfz_6MbE~k{j7|fu_{}LqNr^$4S!?Pr{C^0D~^%iSrUS@utCgUwu=X^gOA5F$v z@=lqFX=#~xsllnaiFqZN$u6k{sd*`>dC8T&`6;P6nvA#D0uqagQ;Rg2Z?QS&=cQ$) z-(q)3EJ-X*ExE<%nwylGl9HL1uE~6h*~vfn7IT23%Pr<mKW|NzTU^c=iA5!DnW;G` zw^$(*M^IupgvAqFnpB=&lmg~yGT!1!Pc4bh$xlyDEz)GX#SPZ#n_5zonXJipOC+Qy zF|Rl+zbH4gC?r2SH7~OYtc=wuu_QSo8RStImV`1szhh)zXlIztkjfCnn8Fanl)@Or zoWc~vlFAyz*1?d*n8Mt`5yj5QfDThMQ+QH2QaMw((wJa|F)*a?ViDuRBF3M}og$FR zog$dZog$RVog$pdog$LTog$jblOmSNlOmqVlO_SSU!sLKiWk}T6s;5~EGB|X!e$B| z*c9m&-Y7m~Qy}aVZLDU=rgEmprE;dor}BVZh|OFPu(=8?yixoqim3uAN~wZbLeNlU zNMlJ+ZefWMW@1Pc%o2f#E@NO|SPkPaKy`_xv81T9u%OCCi4mbwAdMwO6+@?Zszi!T zibe|~nu(Gf3>Az~Qo#(Gy0;W?Cuc}1u1e=pP*6|^$w*bm%q_@C%}vcKNi50C&r`@x zgKJiRWd;RAZcu>eSFlRXEJ?LWNXf5CEYZzP%*)HnOV>3rFtpGu1{+wEpa-_0N+t=K zvviB0SxYwsp0|?WIhlch0aQluGcYiGUckV>FqLsS0~13Dl02$+v*0o{jF}8IOiLL1 z7#SIA7_yjP;hzOB32GSPk=RHoSYT>v7~(;;gSjYXuz`gb7#M08;@M&B6oz1im5hFx z9Jg4DOAAtqZgIrNXXa&=#K+&_EP>_FTdY2=zP^sPm;*q?L5QRKE!F@JS4WpytUiuT zu0EP9w^)i(bJA|HBo?I?-(t%y2h*JK@yR)f#l`XQ#URHiC@3`i3fIrb&rQ__#ZO{h zqFz!?VoGLek$!T1Zb80oNoqxjZfaR#j($mEUS?u^adJ^+K}oTGacMzfk$x_y>?+nT zPASlbMT33;xERwbs4S9ZU|^`yB$QP2V4jm>U|=YAXJBCX(ZFznL!y_plf8%i3WvlD zl?xo23)C)fXhP5fQOPNBS41^CSbDf_2#Zg#yCSUG!P3KV14+DttApz^C_G=jU}j)= znZm%p@Ulagf#D@6T3;$KFfbH>BGN777HdgSVrJeg=9JX3TP!81#U;1cQVa5vGm39< z6eN~prsgH5-r`CEm4ETYnN_K`cuEUW5=&C!i%U`qif^$el_qDWmK5J&FV8Q^PAw|F z#hjR1aEmoLF*zgk7JFH0QBr<!YBDd#DNxM8z`(!_N`^foCBqcPOokG8B4S`bO|A>z z2@q-vm@44}Q(yvBJ!&-vO5DK=E1CROGH9|ENr6H~7es)ZdW#L>;ahAu`N@en#hUy@ zN+3C~0zD8*A4C{{2tyEI1R{(<gb9c+1rcT-!W=|cfCv>3p$dv_P<{jz6bRf<qy~}& z8DFJFFztXN4{Q?1o*xYi9~2k_WP3|H%X`XuYA^6xUf{Q!TQ;*|PR0ECS@mnnR#vR3 zxF~ONMcx7;cY(vQNF9_oz+PoZNi0cB1~I`w#=yV;Vh_s5Dzai=fJN3V4p0UyO)N<* z0=c)y1{8p{AbBoGT-k#J!0|#vlz<v}@aTZXh9hw~8RiU7Oc#UV926m93<3&}2)V*9 ze}UiT0>8~twS^i>G?wcx(%-7KQDck7MJ4MiO4bm$3mi7!81cKsQc#qda*HJ=F)tm& z&QD4P#l+Bx8Fr8#GLuWtBZe0#Vw^y+;|wBPKm@Vz1S(VD@dPT!AsNRF6jd4oGY-^U zARCKeSx1IJKpqlPJ@ps(tuOFfFBMxTu|#6I{37|SVjCs4NL*C3x}s<Wk-NZQ4UVW= ztl-k|7F$tjNoi4DGN@dIMG~lb1C>mlzks_1HH;G&;}~n1YME<UY8bO%su*fnYgiY6 zN@lnSjFG~KT2kRu$Aqe`ijje#mNkXBhBbvDg`t%xg*lB0lr3r)79hJ1W(`9PQw{Sn zCI*JpaM>6p28LR;T6W~>8ha^Q!&bvy!&1Y#jD>+=HK<kvn_A0J!x7A&$>LX}4Juzi z=7OsnP{o{^Se$)}vox=`urxKbD)kmCxE{U5l9OLttjP&U8lZ~s7AvUfUVMu+Ej6*E z_!e7EVp3{OagjFz1H&!0;`r2*^weAI#qnU_B0o@h3M%m7i2|G;ZgGLjNN{~srA;th zAQXpy%&TQ!U}#{tp`dz^L$-r;0_%jb8~h?YRUIrh_=WrHy6R>mUgTG}!mqHvWVziU zyA6sLl})ZFn_T2K>0r4bD%Qc$5eR}47&}5bxo$|w&DWZxwIFnb>qRM}D^f<C{2go) z*l+L)_f+-Qch%1*TTs4%Z3oLme%mYjwqPqdxWP#bB~5{fIB=Sp!wBkXj<7U^)Bs%o zPix==2PHtM5j7>(a+V+!oHZOZoC`qt5~?0S)v)q2q_CjstzjWvEo%2Tm_d^jlJ<+d zK*bs;1HAnI|NnnYc5nhN@&SqZf(TH`y~UQ2nw+1KS|kig+}xlXlA02qmYI{I39ZCH z8KTG^q&@&d1cC@qPACcjv4TMa*dT6jc8CWRaK*(am6-x0LvVtsDM)_MBA6fGYGXm! z;RHB4JQ$elASN{>>$;fwB{B6CY#Z1widkF{v*_Ty%P%#<WP$W`MT<*{7CTgSh#p|N zsOWq}(fL5wb=UAquHhFVV=qL+UWiY;=$drJHR&RM@)iE%3mnOqISbSQ0q3kWOprc( z4YagIE~{%85nZDc#wsob93?7hd$X3cmZgRTd-;h`#^X|lt&C?$VXgrUCn1&b$gSQi zc#FA{Aq$@BI~lS-eg!A}EKqp@X01U>`=$(x44n)MKt(E89+|*hUx4bH6b95>#K@4x zt;}G^P|Q-!RKXm{P|nE65Xry@Ha`n){sK^9MYaUY#>~$Pka9Cv37Dv1;b%x;MYXq< z13bpS*1}PO7-C_lVXfgnRp)}%o2X%o2emH1=AwiZA6N*K)m&28TNuzxWm^Dh&cl?z z=@eGfx_N;BTndSSnqCOHPY|ZH1~drAfnL&RGTvfO%>xa_r4)rRFfgDD1b{*uRLp#y z1nq&PGt@A|I)iI`##$!iK><Ws?_f@2Okrr@s9{QBtYK_rN?`(#$YWR7TNbGPLJw)w zkeSHT;}XoE$&BJ!P$>^~tq!tl1!@^Pn4m6VL^pLJQ;%RUgC-+(b3koA(C`P?*D|$? zHH;|?+2DLqB-F`-Xq6%SUc-n;K6#8Oj1!r9WP=$rnZOMiKTW10MNpy5T9%)jn54;k zi%HMm7Goy38B+`@PZSg&-H2aYHaVHaC7^)?yQ&a^MK7oX2N%<NHju8TogP9zc4i@{ zkOnoNe>5;$&`*V;nAih_Cmauz9VpwtvW4r4fx`j8D+bON44f|nheMU<r-F;aB5P2u ziMc2d<R9ju{BlfB6oH08t30XZda#pSA)_827#Q_~8Ij2w#%3Rw84S`G;qJVUm~ufs z^`d_275!9Xl@K<>7oZlWpC)q=C{l0nCzWRAq{J7c=70y_if^%%<b$F?lLhR}q9l-C zS(8Cy$PnLx5*(sG0rsvPW!?q*u^Z+`CJ6_|4-5$Mp^VB5#~GzxSs5hdu1M%YJc3Ey zu(ChEctG(0^MRlPi3frXu<y~kZsmW;%KxHO;1#RD56qyj`v?xfFJST`1EXXJ;}<ZA zY#)RT4k?rj0;(Rs84c9(oz4Kx9;&cHp@u1i0hHk(nI9$F!%89)8a3NbWa?1^XBbG# zFy3NLE-2N6q%&{?6oE1&G_ydODUftVVZfJy@&jndrGepsR4N2*G~ZyjA!UZi0>%Z3 z3z!!KEl6Atw19n%?R9CLOVT<QrS+~z>p@grkb>k2O(AfL?G{T;YF=?s8mRaOHQsKq zmgE;DXWZgQEG@}TP6UmdrKFZ+CZ`rDgOq^!|3%>TT{wsv0ZL}fRhb1v;FcT6zqi<n z^V3Rl6Dw}9mF6X7=B3<XEhx%QLg@k_wfMk|Jy7w4)Z&W-c@R{dC%}3=&^8{t@Tel( z#)GTP0GT$K5j+C<Kti^I7u4msAu2T`YJut!trdj}^&rhGNH@461>8p=wHtJoSEwg$ zhRYo94I*14x5!@LwZF(~e}&in0|O(cIheR1r!+rnR@Ms94XhXC%&y3pb^3R>O>qCf z3{wDB^%1203y1)7aS}g%{J<vn09$kNx|qu)F_!}=2SQIcT@>@bBIe)0{ecOQRUugi zLO#{dUg5Gq`=W;36%D%&tRO`n!MXYinCxKf;rYPEz$4IO*<%NCKpNu>a1z{`d_d&{ z+j+iId>6taFM32>@rb(ak$A}?@uEla6_4bLb}3ivQZ7iPUX)6`B9+?V+T(qLU!;Sl z7&JF>h)K#xgZYpKi<1ufA$>+C9rl-?hTKcg3`sJm+=AsnQ1b=UO#1walYyaKuw7_6 z%2<Djd?rH)sA__$N6oFE;m}%E<iS?NSbqtUEm?5(0#Hc{H48!2pbcIWFs3l3Fs(rw zXkcW(VJ4_NLKp^Rp_^G$Qp1X9%ogV|f#xXSO<IsYYgoblVFSy6vI^KFunb!k7nsAq zzyMNH!xj$;Gq6w%TNa$XfCnsuM%1unfkGK9ngwqdrm!HI3R&>xAZjxQdjqhBEeqbL zLsienP{S6?Py!k?2HVEKumDs}L)i!ly`jm-P@;(>%T}U=;FW+{Q&4V+9+bhrz>vbU zhJ6_;1H)=~jCKj8aKx}OFx0Zwa@2Cxa@BIzux3fXbfj=*gL<|MMcyT#F>k1F4Qm!? z6dlY%^-C>J321Z_EW^N%!dAnRB?IL!)bM1<BC$d9Az*F|YnD8i0h%Y`S;MuAje%h` zJau#l*6?J3W;DP`ItAn5><Nr{Qd9~7ke@+~Jg^;Q3`Jrn=JFti;2K`k#(OP$3SSLt z7P4*)lrZ2YCSH)kV2uE34ApX^2%_1bjN(2aVr;;S`C85tVKj3UQdm+%a+GqFyM!1S zN<6{A0VYy}(c+n_L$E_AjVVR6g`<Wm9yCP(QOAj9q9<ADhLiGiQ_GE<Zfdv@>81o! zYlB_Oz>p$V0vc6;^0G9b42Cu0XtB&&0velvN_Ps@aMW<saHp}<aMrNb@UD?S8yw{; z0S(wdRo8&h2Rv`4F=aA9%PfAhoCYqji<&zH7l2BAsBQ#R15yuaVS$BeSP|t<kz@&| zr2rOZU_f;Fk=3BaUmjzMWQtS^1FE|j8EV)YMQhk`*^g=lBSQ^Gqi78W(W*HcMQb>T zR?SPaO4bFS=`^VC5fobJLdr3b63|E&R8glOqGUn!TOK#EToz~!5UdATcMUHt-8Jlu zDE8E_<5CHVhZ+tv)f@y=v)6EBfhHuuE&`jtiDm*PUK6+**=x8_P3ROv@H+*wKr@|S z(>n#TK>bZHJ4Jd97iuUm5>ac_@Xcl*T~~?>x*jG_&5v5YgKK{5wRcH6*vVj`Q!qsq zH8&TrcM2kM4=4mtZL1X^TpQO2%w|ZDn~OGR2U=%U0~&%7sNq8$Fs@}oX>(v5BqG#C z&{RlFWny3euM7co2%JD&Uxh@4q@u*U6y3bka_I6B9fi!i<eXB_iYf)r%8JayoXje4 z_ZYN3B{3&Q0W=e=kOo>)RjiPhm!gmhTIrxrkXV$Mn_7}uRIJAZx5Tk1z1RxQ16f;; zSdyWjQCw1_i7F0~11*UG%jc&llw_nr4KB%7NJ>>GPAp4Jfvjr*DFxx&%)I!tqSQis z#^q+_W#*RVDuC3Lf|isi<fW#jq^2m8<U{?Ls*tEq0$R|ekeLUz6+Bc^nv+;msi)wQ znwD6aQ(|R~YI9m<MSM<bo`ObZUI`9=<R(@q<fP`Mmt??#tr)V}Oran%H956d54->< zwIVsSxEK_6B_L&~iOCrdd4=-KoE(t9ONvVKk`qhN{SNYfP-<amW>IR2LS~vmX>n#= zx&mm)non?uufCIOPzb7%K^kDbQ7|$<m4vK-QP6P7OvdIPM}?Hk<PwF9{2Xwq07Xq{ zUUGh3acOR9ib7&hdMRiPQ!&EKDkeSs5KYEg9H|wV#U=6i+2GNzDq(P%1346A1SAE4 zJF%K9x0nkOQ*JSr=4IbvPRcL7#hQ~}o?4{I>IVY1SdvnUN;FxE%0a#53J_5V>N2xK z<KY$uI08XSP?$>+({HhqB&HW@G8Taqv4DneZh;4JiZxl#j3}xBnZufsnwy(=iw#T_ z-(pG4$<5bfyu|~ayp1o(kIzggMi~wPRkomJ_Gi%a%~U4Pa;Z+H8nmJcw3G^5hM*9g zNOJ_J1xGML5vYHl$#jdUB)=#ZJlb}PvEmj>xPOpKQ7fqb4YF6E0XkyHVUv@Xo0O7h zS7kwP2nsyTg*;XW(YXX<D5(AXqk&<C%nF$ei7VyT$Y0mAzNBfr!)1^6MNN+@njQ@d z-~l1<;DjdQEvB?Q&_u19e~@nxs7+o3YK#|wTGoCjfduLSf&&Ru-ArewLFr{84WOb0 zTNO7013V~-vO)2~TwIc($yn3@axG{o96Acr#lXNozTek@OaldY1H*;fysL#}R|=~x zRM%WAti4iLdoi~b>T6A|TkLu9khx}#Jji@<@h!Hzcu*PxNr94A@hv_O6<?5;5}%ou zl3H;Kq!g5>if{3O(k_w=CqfZtX<jx|J!evWF@#wqgpy0Zh3hTWRM0BdTZ~+gQCJhm znhDT4mRn5u#kV+e6SGrOGK-3Dv4G0YTkI*BMR|$2skhj`8L;>kD>wmwX3-N<Zn66M zySVy5MxsE?*<1WM`H3l@SwZj&cWO!zsM}QpT7y+I6O`H7K?Ep4-eQ9+kG;i`nU|Jd z1nR>UfjYoNpx$l~s8bA@S^&>g7J<ecimE|6L0wmD`K~Ad6uB&*3H)24i8(o`d3iYn zdb#;2r8%j^dZ0`QPW45g>h2ahXlOjYIJF4Wora9wLe}d-=KVpHdl9H5cZ&m7EfjHq zEC;P@xW$~4ng@zAP<>W34J14rM9cu$&z_N3oLEv)q$zxhIXS1eXf8+ww2~BDHWYz+ z*5IJJ#RgfuR|Lv0w^*D#9D~5g{}zj@kFWnN7EqCUi?IYe-VX^tkaHlTe4QXO!8sU| zAwWej3U+V+kIWT;N(>?vc7fv(R0<ZaXJKIY@uPv^s|tgF*ad#Y3;c?6*=BOg;efC^ zSnhIg^>9yhn&Lj)f0F+Kmy05rS41=~h#0O2+2L}5!|@`A;}s6a3mlGjxp{lc`|Y~y zW~f}`mcPO+|AB#pQ)&gv8ZI#7hN$d>;3*LoL{%?{sxDxG&>e0!q*Z1Z&#}B9ZG1u6 zctP2cY6z>tt;gpEk5G@#bsmjNJQ^#+u4r0b(X`u9ctz9kil+NT9*-+L9@lxiFY$Pv za699Bktga3Pt*mTs2jqP9llRF`1-lKxG#ukUgXfa!l8A6L+dWT$b|5v%4?0cI`1gC z!0&RA-{lIwO9#shb?1v5Djm!nArnkzs4QT)!Oh=eGsEl>x8enE#k&G33qqDeUKG&3 zBB0;lcvo0{0sD%;HK98g_plx?JYsqwDC|m5+=a}n3&PnKg|n{+XLq>Vkd&Gu-r>^Y z)#>$ASYn3w(&V+pdzlZIToCrSDC}`X*rUVc2EWJ*mN}e|@VzT0J;QA+^93=Ti()!g z#B?Sw-{2RWAu>nu0>9D)ex<wO$_w1L3hz}uYJ4Fe<Vrxy1@YL6;;~o6V<)iO;1`>r zGDq_Qzw!ls<+~EHGcwjXZw=m?d_v@cgx^I8zbg`c6IfA9yCGnA0Tta9mtVkkQC$6s zxcUT^8}c3(kkAB{DLg3J?}})w5LqL6QN;L)i17qQklWlgFm7SpVYtWiK;n_q3!#x$ zLK83K<X#ZZyC|M_MLcf;%MDq%IpGsnrf}UAkeXq!mi3B;#RUP&ivpHc1S~sP?}|t+ zU|Eo|!exWX1$pxwr6-gxghpKuiM}WjeMKa?gY&6?_zcbkCQGa?2$)?EFxwykp*vVn z;^_vDK)+X)*M!m;DRXj9xSa92pqH>Vb4}ikkUdcs^*pZVd0f!*xDb<YA-VQKa_vQ) zx+^?&7kKJ!@C$X+-w+U<&N+#5hU!HDg)0II7X%b;@C#qym%kw(GM#G@*9_B(0*Y4z z6fX!U-ryIxz^`yaKy*6yB<>lm7X_5A2q;|;P`bgv+t1y_J;C)Nhtw4gsS6xZH#m4e zA~&@3*68d|yQJlCLCaxk@eGqWRuk)|)K92Cka8sJid*<y3F#TGbG$D~Xk3xdxS^rF zf`4lA4COhR6Z59zO~~63azjh+f|eDEMwS}}CKn7GW~9u?n~`@Q<%W*o1s&VD%m`yH zNN5}|K~p3tJ4fyYocJKhEz0$Qfm@X8BLg=l_ZJZH0YrS2VBq8jxqCw81iy<M%2zm) zFK{Ts^OD9z4$UjzHNrOpBquOW;k*D2l^HG&`nrJOB>}^u>?c@Gq+fIhyW$Xb!6;#a z$`-8+S{GsxE(#=G5lHM{y$i{i6G|uefZ#<A#VZ_&7dR9j2#QP)o)9v_bb;nYL7gjt zIvs2`IQV*a`uV%~XRyuTy~v?<g+uKEhuRH((GK1s(2`P3&LYrgNfBrWvIsP~0bU4J z1R8e)w-nvnLNwVR5_X`X6V&|%iE;Y*xnU7zDk=u4DgiZ_q(LjfL3Lkz{4K8dct~v$ zAAgG{KEALtF$XHc9v`2QpBx{5i^b2;*R=>VU|6&WWCmzmb`hxMa*MgRq^Jng;JU?} znOAa)B`H5Y2VBDxfmVDLfz}chiGs9%n<#7{sd>fuMMa?bv0LnU`SIyRi7DU(J4I0- zMMa>hh8w)TJU6u@BR>UP*x%xXt~pOm&B=+6*JLaL4Tcqi+BncEK^&wRM2LZ!D?H5L z`IiO;2>igr#LDr30Yq>x@Mtx-+~Cn}aQ(o-%BuB&0Sh6)ATE7FLi&c3+zlDo8{(2T z#3gQsNZt^Wz9Av=L0W*->H~uStJMR3kqN;wG$zDe;aC2^3KC^w;1ix;JcDC`?G;|d z59}Zz4hDXa3C=SlCiq_AQ~JOO65?VI6#2jnV(~Bti+$h)vG^E7B|h+jSON^<QXd3C zEFlIV(GS8PmI#O?3Sx;d@Ckho2eBj=1Vlbaf>=@vLShJ4ft`j<Xfa63gFJ!k4?%8L z+Yb!fthNvMgb^-e1&OkOT*D4xae!>*1hKe4EN&2s2jm7`5Q`7w27VAr0OSU^iC|;V z2?YjG$r~aPH$<gC;VLcxat}OE#rarmJ}~gH+MqfHB+ACXFZ6*O#Nq(4I6*8f27ciW z+#nVY$f>*_79Yrg{2-P9h$RSO34xp{3}T6ZoGJ=piGiF7w-0P7I-$VMDzbp}0|Ps& z$O_dpI$#DmA;iEY+z{Fl+Zf*x|AC2vHHC3T=?4Z7y+Rs7Ba<JQ8Q4T&3O|UT=;dV< z1!?7F6<s0vfq|D5iGXVZiOMms34UM-WMmclz<?k@N(5V?F(r@{feVu&Q1;MNE}G52 zz;KJLq_QA0FCCn5!TA`{gHQ(V$pE!2Q*(;-Qc?@_V0$w3;JZd3jY>%rmBlFtmEcn1 z77s)o+7<+jwcg@}2$hy(<`hF3=HS*SsQGzI2uV&aIX^cyKM&kaMl_pm2_h>2cZwlx zTyX0e)b=d`HK1<^BP#<n!$IBzP5hzSk(&zIum&!9Ziymmfpw9Kia;%MG&$JL8Ayq? z6;$Ye`i9`31$Q|hAr0Do@QcF+QmEP$onc^L0F_n6F^mihAD9^#89%TwFmg3;g5V7X zr3={50|uT3FnqvZdI1&PU~s*Fif%B-UqD4S7>q99MmHFAF5pHt7~C%qLN^$+E}$Z8 zB4!sDP|ytq^$V!z0jF?>)C7-<oU&IqWgFN&u$3?|ihW?fPA(|>2$uN*CNWikLmvPP C#ZJ-y literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/biaffine/model.py b/tania_scripts/supar/models/sdp/biaffine/model.py new file mode 100644 index 0000000..7a7afa4 --- /dev/null +++ b/tania_scripts/supar/models/sdp/biaffine/model.py @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- + +import torch.nn as nn +from supar.model import Model +from supar.modules import MLP, Biaffine +from supar.utils import Config + + +class BiaffineSemanticDependencyModel(Model): + r""" + The implementation of Biaffine Semantic Dependency Parser :cite:`dozat-manning-2018-simpler`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + n_lemmas (int): + The number of lemmas, required if lemma embeddings are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'lemma'``: Lemma embeddings. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [ ``'tag'``, ``'char'``, ``'lemma'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word representations. Default: 125. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .2. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 1200. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_edge_mlp (int): + Edge MLP size. Default: 600. + n_label_mlp (int): + Label MLP size. Default: 600. + edge_mlp_dropout (float): + The dropout ratio of edge MLP layers. Default: .25. + label_mlp_dropout (float): + The dropout ratio of label MLP layers. Default: .33. + interpolation (int): + Constant to even out the label/edge loss. Default: .1. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + n_lemmas=None, + encoder='lstm', + feat=['tag', 'char', 'lemma'], + n_embed=100, + n_pretrained=125, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=400, + char_pad_index=0, + char_dropout=0.33, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.2, + n_encoder_hidden=1200, + n_encoder_layers=3, + encoder_dropout=.33, + n_edge_mlp=600, + n_label_mlp=600, + edge_mlp_dropout=.25, + label_mlp_dropout=.33, + interpolation=0.1, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.edge_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False) + self.edge_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False) + self.label_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False) + self.label_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False) + + self.edge_attn = Biaffine(n_in=n_edge_mlp, n_out=2, bias_x=True, bias_y=True) + self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True) + self.criterion = nn.CrossEntropyLoss() + + def load_pretrained(self, embed=None): + if embed is not None: + self.pretrained = nn.Embedding.from_pretrained(embed) + if embed.shape[1] != self.args.n_pretrained: + self.embed_proj = nn.Linear(embed.shape[1], self.args.n_pretrained) + return self + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first tensor of shape ``[batch_size, seq_len, seq_len, 2]`` holds scores of all possible edges. + The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds + scores of all possible labels on each edge. + """ + + x = self.encode(words, feats) + + edge_d = self.edge_mlp_d(x) + edge_h = self.edge_mlp_h(x) + label_d = self.label_mlp_d(x) + label_h = self.label_mlp_h(x) + + # [batch_size, seq_len, seq_len, 2] + s_edge = self.edge_attn(edge_d, edge_h).permute(0, 2, 3, 1) + # [batch_size, seq_len, seq_len, n_labels] + s_label = self.label_attn(label_d, label_h).permute(0, 2, 3, 1) + + return s_edge, s_label + + def loss(self, s_edge, s_label, labels, mask): + r""" + Args: + s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``. + Scores of all possible edges. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each edge. + labels (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + + Returns: + ~torch.Tensor: + The training loss. + """ + + edge_mask = labels.ge(0) & mask + edge_loss = self.criterion(s_edge[mask], edge_mask[mask].long()) + label_loss = self.criterion(s_label[edge_mask], labels[edge_mask]) + return self.args.interpolation * label_loss + (1 - self.args.interpolation) * edge_loss + + def decode(self, s_edge, s_label): + r""" + Args: + s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``. + Scores of all possible edges. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each edge. + + Returns: + ~torch.LongTensor: + Predicted labels of shape ``[batch_size, seq_len, seq_len]``. + """ + + return s_label.argmax(-1).masked_fill_(s_edge.argmax(-1).lt(1), -1) diff --git a/tania_scripts/supar/models/sdp/biaffine/parser.py b/tania_scripts/supar/models/sdp/biaffine/parser.py new file mode 100644 index 0000000..c28f6c2 --- /dev/null +++ b/tania_scripts/supar/models/sdp/biaffine/parser.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- + +import os +from typing import Iterable, Union + +import torch + +from supar.models.dep.biaffine.transform import CoNLL +from supar.models.sdp.biaffine import BiaffineSemanticDependencyModel +from supar.parser import Parser +from supar.utils import Config, Dataset, Embedding +from supar.utils.common import BOS, PAD, UNK +from supar.utils.field import ChartField, Field, RawField, SubwordField +from supar.utils.logging import get_logger +from supar.utils.metric import ChartMetric +from supar.utils.tokenizer import TransformerTokenizer +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class BiaffineSemanticDependencyParser(Parser): + r""" + The implementation of Biaffine Semantic Dependency Parser :cite:`dozat-manning-2018-simpler`. + """ + + NAME = 'biaffine-semantic-dependency' + MODEL = BiaffineSemanticDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.LEMMA = self.transform.LEMMA + self.TAG = self.transform.POS + self.LABEL = self.transform.PHEAD + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, *feats, labels = batch + mask = batch.mask + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + mask[:, 0] = 0 + s_edge, s_label = self.model(words, feats) + loss = self.model.loss(s_edge, s_label, labels, mask) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> ChartMetric: + words, *feats, labels = batch + mask = batch.mask + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + mask[:, 0] = 0 + s_edge, s_label = self.model(words, feats) + loss = self.model.loss(s_edge, s_label, labels, mask) + label_preds = self.model.decode(s_edge, s_label) + return ChartMetric(loss, label_preds.masked_fill(~mask, -1), labels.masked_fill(~mask, -1)) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats = batch + mask, lens = batch.mask, (batch.lens - 1).tolist() + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + mask[:, 0] = 0 + with torch.autocast(self.device, enabled=self.args.amp): + s_edge, s_label = self.model(words, feats) + label_preds = self.model.decode(s_edge, s_label).masked_fill(~mask, -1) + batch.labels = [CoNLL.build_relations([[self.LABEL.vocab[i] if i >= 0 else None for i in row] + for row in chart[1:i, :i].tolist()]) + for i, chart in zip(lens, label_preds)] + if self.args.prob: + batch.probs = [prob[1:i, :i].cpu() for i, prob in zip(lens, s_edge.softmax(-1).unbind())] + return batch + + @classmethod + def build(cls, path, min_freq=7, fix_len=20, **kwargs): + r""" + Build a brand-new Parser, including initialization of all data fields and model parameters. + + Args: + path (str): + The path of the model to be saved. + min_freq (str): + The minimum frequency needed to include a token in the vocabulary. Default:7. + fix_len (int): + The max length of all subword pieces. The excess part of each piece will be truncated. + Required if using CharLSTM/BERT. + Default: 20. + kwargs (Dict): + A dict holding the unconsumed arguments. + """ + + args = Config(**locals()) + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + if os.path.exists(path) and not args.build: + parser = cls.load(**args) + parser.model = cls.MODEL(**parser.args) + parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device) + return parser + + logger.info("Building the fields") + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True) + TAG, CHAR, LEMMA, ELMO, BERT = None, None, None, None, None + if args.encoder == 'bert': + t = TransformerTokenizer(args.bert) + WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t) + WORD.vocab = t.vocab + else: + WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True) + if 'tag' in args.feat: + TAG = Field('tags', bos=BOS) + if 'char' in args.feat: + CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len) + if 'lemma' in args.feat: + LEMMA = Field('lemmas', pad=PAD, unk=UNK, bos=BOS, lower=True) + if 'elmo' in args.feat: + from allennlp.modules.elmo import batch_to_ids + ELMO = RawField('elmo') + ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device) + if 'bert' in args.feat: + t = TransformerTokenizer(args.bert) + BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t) + BERT.vocab = t.vocab + LABEL = ChartField('labels', fn=CoNLL.get_labels) + transform = CoNLL(FORM=(WORD, CHAR, ELMO, BERT), LEMMA=LEMMA, POS=TAG, PHEAD=LABEL) + + train = Dataset(transform, args.train, **args) + if args.encoder != 'bert': + WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x)) + if TAG is not None: + TAG.build(train) + if CHAR is not None: + CHAR.build(train) + if LEMMA is not None: + LEMMA.build(train) + LABEL.build(train) + args.update({ + 'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init, + 'n_labels': len(LABEL.vocab), + 'n_tags': len(TAG.vocab) if TAG is not None else None, + 'n_chars': len(CHAR.vocab) if CHAR is not None else None, + 'char_pad_index': CHAR.pad_index if CHAR is not None else None, + 'n_lemmas': len(LEMMA.vocab) if LEMMA is not None else None, + 'bert_pad_index': BERT.pad_index if BERT is not None else None, + 'pad_index': WORD.pad_index, + 'unk_index': WORD.unk_index, + 'bos_index': WORD.bos_index + }) + logger.info(f"{transform}") + + logger.info("Building the model") + model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None) + logger.info(f"{model}\n") + + parser = cls(args, model, transform) + parser.model.to(parser.device) + return parser diff --git a/tania_scripts/supar/models/sdp/vi/__init__.py b/tania_scripts/supar/models/sdp/vi/__init__.py new file mode 100644 index 0000000..2aae65d --- /dev/null +++ b/tania_scripts/supar/models/sdp/vi/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from .model import VISemanticDependencyModel +from .parser import VISemanticDependencyParser + +__all__ = ['VISemanticDependencyModel', 'VISemanticDependencyParser'] diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b7e00e74f70f0d965c505e8994b7e119a0dec34 GIT binary patch literal 303 zcmd1j<>g{vU|`^9UzEOwfq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$B*Q#|Q*#sZN-~pOQVUY^Qd0AhD}D1* zQgbvJZ%JX33`i_0PAw_|*;&NQz`)?A$$E=57o-C$c8je5q5vd!i#<L*F()TJekDT@ zI|BoR_~ojfk)NBYUy@jonV6TTmz0y3l9^hhpPZjtkguCwP@)SqO~1IbAhAdv%r4e1 tPASkY%hZpL&&<m#iI3MSsJz8tlbfGXnv-e=@=7rq0|NsO6AvQ~697BGPiz1H literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e17f748d964d58b705b5a14d52e4f3758f8318e7 GIT binary patch literal 372 zcmZ3^%ge>Uz`&q%Uo~S70|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w<N<ngHv-8^GY(4T~Z5D^HNgtk}G}lQ&Mv@ z8E;8plMF~KDo!mbVrF1qC}Lq?VDQsqy~Uaf(g7B`#Z~}O0Ft}K9v`2WlM^4mlHoJR zmA``ZGxBp&^-B^<G86L>^^$TDQ!-PF^po>*3-WbKQY%VyQ_B)_^h*-+G85yAlZ!G7 zN{aQ1OA8W<^ubmX>lddK=$B>c$H!;pWtPOp>lIY~;;_lhPbtkwwJYLgU|;}wtk{Zy tf#Cx)BO~JnHU>uB3k*8Q=mvw{1yuBaTkV2|%LOji26hlE;$&c8003|tY1se( literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cfb7bd073d93cc874641db0353d3cc92dcbf402 GIT binary patch literal 19591 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac266759295a48ebd875a15b1b28e225c633c0b6 GIT binary patch literal 24854 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 OEd2#SeZWS60|o$?Ob|-| literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ceb658d3c6b5f0ceae68bdf73fc482f9763c6d5f GIT binary patch literal 4845 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b28e31b2c498c355f12078f27de07f420d6c8a0 GIT binary patch literal 8540 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/models/sdp/vi/model.py b/tania_scripts/supar/models/sdp/vi/model.py new file mode 100644 index 0000000..12c20e1 --- /dev/null +++ b/tania_scripts/supar/models/sdp/vi/model.py @@ -0,0 +1,471 @@ +# -*- coding: utf-8 -*- + +import torch.nn as nn +from supar.model import Model +from supar.modules import MLP, Biaffine, Triaffine +from supar.structs import SemanticDependencyLBP, SemanticDependencyMFVI +from supar.utils import Config + + +class BiaffineSemanticDependencyModel(Model): + r""" + The implementation of Biaffine Semantic Dependency Parser :cite:`dozat-manning-2018-simpler`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + n_lemmas (int): + The number of lemmas, required if lemma embeddings are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'lemma'``: Lemma embeddings. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [ ``'tag'``, ``'char'``, ``'lemma'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word representations. Default: 125. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .2. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 1200. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_edge_mlp (int): + Edge MLP size. Default: 600. + n_label_mlp (int): + Label MLP size. Default: 600. + edge_mlp_dropout (float): + The dropout ratio of edge MLP layers. Default: .25. + label_mlp_dropout (float): + The dropout ratio of label MLP layers. Default: .33. + interpolation (int): + Constant to even out the label/edge loss. Default: .1. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + n_lemmas=None, + encoder='lstm', + feat=['tag', 'char', 'lemma'], + n_embed=100, + n_pretrained=125, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=400, + char_pad_index=0, + char_dropout=0.33, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.2, + n_encoder_hidden=1200, + n_encoder_layers=3, + encoder_dropout=.33, + n_edge_mlp=600, + n_label_mlp=600, + edge_mlp_dropout=.25, + label_mlp_dropout=.33, + interpolation=0.1, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.edge_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False) + self.edge_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False) + self.label_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False) + self.label_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False) + + self.edge_attn = Biaffine(n_in=n_edge_mlp, n_out=2, bias_x=True, bias_y=True) + self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True) + self.criterion = nn.CrossEntropyLoss() + + def load_pretrained(self, embed=None): + if embed is not None: + self.pretrained = nn.Embedding.from_pretrained(embed) + if embed.shape[1] != self.args.n_pretrained: + self.embed_proj = nn.Linear(embed.shape[1], self.args.n_pretrained) + return self + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first tensor of shape ``[batch_size, seq_len, seq_len, 2]`` holds scores of all possible edges. + The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds + scores of all possible labels on each edge. + """ + + x = self.encode(words, feats) + + edge_d = self.edge_mlp_d(x) + edge_h = self.edge_mlp_h(x) + label_d = self.label_mlp_d(x) + label_h = self.label_mlp_h(x) + + # [batch_size, seq_len, seq_len, 2] + s_edge = self.edge_attn(edge_d, edge_h).permute(0, 2, 3, 1) + # [batch_size, seq_len, seq_len, n_labels] + s_label = self.label_attn(label_d, label_h).permute(0, 2, 3, 1) + + return s_edge, s_label + + def loss(self, s_edge, s_label, labels, mask): + r""" + Args: + s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``. + Scores of all possible edges. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each edge. + labels (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + + Returns: + ~torch.Tensor: + The training loss. + """ + + edge_mask = labels.ge(0) & mask + edge_loss = self.criterion(s_edge[mask], edge_mask[mask].long()) + label_loss = self.criterion(s_label[edge_mask], labels[edge_mask]) + return self.args.interpolation * label_loss + (1 - self.args.interpolation) * edge_loss + + def decode(self, s_edge, s_label): + r""" + Args: + s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``. + Scores of all possible edges. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each edge. + + Returns: + ~torch.LongTensor: + Predicted labels of shape ``[batch_size, seq_len, seq_len]``. + """ + + return s_label.argmax(-1).masked_fill_(s_edge.argmax(-1).lt(1), -1) + + +class VISemanticDependencyModel(BiaffineSemanticDependencyModel): + r""" + The implementation of Semantic Dependency Parser using Variational Inference :cite:`wang-etal-2019-second`. + + Args: + n_words (int): + The size of the word vocabulary. + n_labels (int): + The number of labels in the treebank. + n_tags (int): + The number of POS tags, required if POS tag embeddings are used. Default: ``None``. + n_chars (int): + The number of characters, required if character-level representations are used. Default: ``None``. + n_lemmas (int): + The number of lemmas, required if lemma embeddings are used. Default: ``None``. + encoder (str): + Encoder to use. + ``'lstm'``: BiLSTM encoder. + ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``. + Default: ``'lstm'``. + feat (List[str]): + Additional features to use, required if ``encoder='lstm'``. + ``'tag'``: POS tag embeddings. + ``'char'``: Character-level representations extracted by CharLSTM. + ``'lemma'``: Lemma embeddings. + ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible. + Default: [ ``'tag'``, ``'char'``, ``'lemma'``]. + n_embed (int): + The size of word embeddings. Default: 100. + n_pretrained (int): + The size of pretrained word embeddings. Default: 125. + n_feat_embed (int): + The size of feature representations. Default: 100. + n_char_embed (int): + The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50. + n_char_hidden (int): + The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100. + char_pad_index (int): + The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0. + elmo (str): + Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``. + elmo_bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs. + Default: ``(True, False)``. + bert (str): + Specifies which kind of language model to use, e.g., ``'bert-base-cased'``. + This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_. + Default: ``None``. + n_bert_layers (int): + Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features. + The final outputs would be weighted sum of the hidden states of these layers. + Default: 4. + mix_dropout (float): + The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0. + bert_pooling (str): + Pooling way to get token embeddings. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + bert_pad_index (int): + The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features. + Default: 0. + finetune (bool): + If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``. + n_plm_embed (int): + The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + embed_dropout (float): + The dropout ratio of input embeddings. Default: .2. + n_encoder_hidden (int): + The size of encoder hidden states. Default: 1200. + n_encoder_layers (int): + The number of encoder layers. Default: 3. + encoder_dropout (float): + The dropout ratio of encoder layer. Default: .33. + n_edge_mlp (int): + Unary factor MLP size. Default: 600. + n_pair_mlp (int): + Binary factor MLP size. Default: 150. + n_label_mlp (int): + Label MLP size. Default: 600. + edge_mlp_dropout (float): + The dropout ratio of unary edge factor MLP layers. Default: .25. + pair_mlp_dropout (float): + The dropout ratio of binary factor MLP layers. Default: .25. + label_mlp_dropout (float): + The dropout ratio of label MLP layers. Default: .33. + inference (str): + Approximate inference methods. Default: ``mfvi``. + max_iter (int): + Max iteration times for inference. Default: 3. + interpolation (int): + Constant to even out the label/edge loss. Default: .1. + pad_index (int): + The index of the padding token in the word vocabulary. Default: 0. + unk_index (int): + The index of the unknown token in the word vocabulary. Default: 1. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__(self, + n_words, + n_labels, + n_tags=None, + n_chars=None, + n_lemmas=None, + encoder='lstm', + feat=['tag', 'char', 'lemma'], + n_embed=100, + n_pretrained=125, + n_feat_embed=100, + n_char_embed=50, + n_char_hidden=100, + char_pad_index=0, + char_dropout=0, + elmo='original_5b', + elmo_bos_eos=(True, False), + bert=None, + n_bert_layers=4, + mix_dropout=.0, + bert_pooling='mean', + bert_pad_index=0, + finetune=False, + n_plm_embed=0, + embed_dropout=.2, + n_encoder_hidden=1200, + n_encoder_layers=3, + encoder_dropout=.33, + n_edge_mlp=600, + n_pair_mlp=150, + n_label_mlp=600, + edge_mlp_dropout=.25, + pair_mlp_dropout=.25, + label_mlp_dropout=.33, + inference='mfvi', + max_iter=3, + interpolation=0.1, + pad_index=0, + unk_index=1, + **kwargs): + super().__init__(**Config().update(locals())) + + self.edge_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False) + self.edge_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False) + self.pair_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=pair_mlp_dropout, activation=False) + self.pair_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=pair_mlp_dropout, activation=False) + self.pair_mlp_g = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=pair_mlp_dropout, activation=False) + self.label_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False) + self.label_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False) + + self.edge_attn = Biaffine(n_in=n_edge_mlp, bias_x=True, bias_y=True) + self.sib_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=True) + self.cop_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=True) + self.grd_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=True) + self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True) + self.inference = (SemanticDependencyMFVI if inference == 'mfvi' else SemanticDependencyLBP)(max_iter) + self.criterion = nn.CrossEntropyLoss() + + def forward(self, words, feats=None): + r""" + Args: + words (~torch.LongTensor): ``[batch_size, seq_len]``. + Word indices. + feats (List[~torch.LongTensor]): + A list of feat indices. + The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``, + or ``[batch_size, seq_len]`` otherwise. + Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor, ~torch.Tensor, ~torch.Tensor, ~torch.Tensor: + The first and last are scores of all possible edges of shape ``[batch_size, seq_len, seq_len]`` + and possible labels on each edge of shape ``[batch_size, seq_len, seq_len, n_labels]``. + Others are scores of second-order sibling, coparent and grandparent factors + (``[batch_size, seq_len, seq_len, seq_len]``). + + """ + + x = self.encode(words, feats) + + edge_d = self.edge_mlp_d(x) + edge_h = self.edge_mlp_h(x) + pair_d = self.pair_mlp_d(x) + pair_h = self.pair_mlp_h(x) + pair_g = self.pair_mlp_g(x) + label_d = self.label_mlp_d(x) + label_h = self.label_mlp_h(x) + + # [batch_size, seq_len, seq_len] + s_edge = self.edge_attn(edge_d, edge_h) + # [batch_size, seq_len, seq_len, seq_len], (d->h->s) + s_sib = self.sib_attn(pair_d, pair_d, pair_h) + s_sib = (s_sib.triu() + s_sib.triu(1).transpose(-1, -2)).permute(0, 3, 1, 2) + # [batch_size, seq_len, seq_len, seq_len], (d->h->c) + s_cop = self.cop_attn(pair_h, pair_d, pair_h).permute(0, 3, 1, 2) + s_cop = s_cop.triu() + s_cop.triu(1).transpose(-1, -2) + # [batch_size, seq_len, seq_len, seq_len], (d->h->g) + s_grd = self.grd_attn(pair_g, pair_d, pair_h).permute(0, 3, 1, 2) + # [batch_size, seq_len, seq_len, n_labels] + s_label = self.label_attn(label_d, label_h).permute(0, 2, 3, 1) + + return s_edge, s_sib, s_cop, s_grd, s_label + + def loss(self, s_edge, s_sib, s_cop, s_grd, s_label, labels, mask): + r""" + Args: + s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible edges. + s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of all possible dependent-head-sibling triples. + s_cop (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of all possible dependent-head-coparent triples. + s_grd (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``. + Scores of all possible dependent-head-grandparent triples. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each edge. + labels (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + The tensor of gold-standard labels. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The training loss and marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + edge_mask = labels.ge(0) & mask + edge_loss, marginals = self.inference((s_edge, s_sib, s_cop, s_grd), mask, edge_mask.long()) + label_loss = self.criterion(s_label[edge_mask], labels[edge_mask]) + loss = self.args.interpolation * label_loss + (1 - self.args.interpolation) * edge_loss + return loss, marginals + + def decode(self, s_edge, s_label): + r""" + Args: + s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible edges. + s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``. + Scores of all possible labels on each edge. + + Returns: + ~torch.LongTensor: + Predicted labels of shape ``[batch_size, seq_len, seq_len]``. + """ + + return s_label.argmax(-1).masked_fill_(s_edge.lt(0.5), -1) diff --git a/tania_scripts/supar/models/sdp/vi/parser.py b/tania_scripts/supar/models/sdp/vi/parser.py new file mode 100644 index 0000000..dbb85c8 --- /dev/null +++ b/tania_scripts/supar/models/sdp/vi/parser.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +from typing import Iterable, Union + +import torch + +from supar.models.dep.biaffine.transform import CoNLL +from supar.models.sdp.biaffine.parser import BiaffineSemanticDependencyParser +from supar.models.sdp.vi.model import VISemanticDependencyModel +from supar.utils import Config +from supar.utils.logging import get_logger +from supar.utils.metric import ChartMetric +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class VISemanticDependencyParser(BiaffineSemanticDependencyParser): + r""" + The implementation of Semantic Dependency Parser using Variational Inference :cite:`wang-etal-2019-second`. + """ + + NAME = 'vi-semantic-dependency' + MODEL = VISemanticDependencyModel + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.LEMMA = self.transform.LEMMA + self.TAG = self.transform.POS + self.LABEL = self.transform.PHEAD + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int = 1000, + patience: int = 100, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().train(**Config().update(locals())) + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().evaluate(**Config().update(locals())) + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + return super().predict(**Config().update(locals())) + + def train_step(self, batch: Batch) -> torch.Tensor: + words, *feats, labels = batch + mask = batch.mask + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + mask[:, 0] = 0 + s_edge, s_sib, s_cop, s_grd, s_label = self.model(words, feats) + loss, s_edge = self.model.loss(s_edge, s_sib, s_cop, s_grd, s_label, labels, mask) + return loss + + @torch.no_grad() + def eval_step(self, batch: Batch) -> ChartMetric: + words, *feats, labels = batch + mask = batch.mask + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + mask[:, 0] = 0 + s_edge, s_sib, s_cop, s_grd, s_label = self.model(words, feats) + loss, s_edge = self.model.loss(s_edge, s_sib, s_cop, s_grd, s_label, labels, mask) + label_preds = self.model.decode(s_edge, s_label) + return ChartMetric(loss, label_preds.masked_fill(~mask, -1), labels.masked_fill(~mask, -1)) + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + words, *feats = batch + mask, lens = batch.mask, (batch.lens - 1).tolist() + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + mask[:, 0] = 0 + s_edge, s_sib, s_cop, s_grd, s_label = self.model(words, feats) + s_edge = self.model.inference((s_edge, s_sib, s_cop, s_grd), mask) + label_preds = self.model.decode(s_edge, s_label).masked_fill(~mask, -1) + batch.labels = [CoNLL.build_relations([[self.LABEL.vocab[i] if i >= 0 else None for i in row] + for row in chart[1:i, :i].tolist()]) + for i, chart in zip(lens, label_preds)] + if self.args.prob: + batch.probs = [prob[1:i, :i].cpu() for i, prob in zip(lens, s_edge.unbind())] + return batch diff --git a/tania_scripts/supar/modules/__init__.py b/tania_scripts/supar/modules/__init__.py new file mode 100644 index 0000000..981a6bf --- /dev/null +++ b/tania_scripts/supar/modules/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from .affine import Biaffine, Triaffine +from .dropout import IndependentDropout, SharedDropout, TokenDropout +from .gnn import GraphConvolutionalNetwork +from .lstm import CharLSTM, VariationalLSTM +from .mlp import MLP +from .decoder import DecoderLSTM +from .pretrained import ELMoEmbedding, TransformerEmbedding +from .transformer import (TransformerDecoder, TransformerEncoder, + TransformerWordEmbedding) + +__all__ = ['Biaffine', 'Triaffine', + 'IndependentDropout', 'SharedDropout', 'TokenDropout', + 'GraphConvolutionalNetwork', + 'CharLSTM', 'VariationalLSTM', + 'MLP', 'DecoderLSTM', + 'ELMoEmbedding', 'TransformerEmbedding', + 'TransformerWordEmbedding', + 'TransformerDecoder', 'TransformerEncoder'] diff --git a/tania_scripts/supar/modules/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c13e44da2a22e9ce2413ca58f980bfe9c2110b8 GIT binary patch literal 795 zcmd1j<>g{vU|`^9UzBdh%)sy%#6iYP3=9ko3=9m#9SjT%DGVu$ISjdsQH;4vQA~^= zK2r{JE=v?kE^8EPE?X2ESd2M`J(nYj1I%X0;mqZV;>zWY;s*0sb9i!jqj<q=wj91( z{wRJhn>|M$S1?L2S13vd%;(4v&J~Fg$rX(f%@vChV`NBYNa0+>7$u&<70jT?{gRP^ zfkBh$7Kc-2Vp>{eUg|B*kRm8kllhjAXI@HbL26z~YF>#;QGP*wX~`|#;Ecqg)D#$( zCnP^RH4n<uWV|KmUX)mn;hdjWmY-8vl9`{EnB$jPQl4Lw4YI~LBeBRQIK=lBe^_Es zW+Fr$B%sN7i`myFK$Gznw@Yereo87>nI_XMURNLAeAnEh)RdIWy!2ZlAw`LK#cBCP zxv52PQIJcK#GwY<5<(Jl%>x^HO9DwOJijOfVFrH@D2|Gl85kIfSU?0Th+qQ|>>z>z zL~w!#P)rwbgIGKuf)_*xfCxSi!Oy_J;HN2ZiwzQ>2vcvdr$B-b&G;zh^t`+xkR7*J za*9iGi{LgzG3VwK6oIU}#hwBQ6|lXxxC)9=ONtUR^HNia;BL6ZU4jUkBDh<MKu){G z9v`2WlM^4mlA%Zf<Vq0n%U(YtKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`UpKv=L^n4- zB{fICxU?X#NIy3}r8FnCSU)~KGcU6wK3=b&@)m~;MAQzHjEaRA7#IYYL>PG(1sHk2 JqzEGqGXTHg(EI=Z literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8dc3d835d3ccc7fab896ae595885b0226ecebc2 GIT binary patch literal 1028 zcmZ3^%ge>Uz`&q%Up2#!nStRkhy%k+P{!vj1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL zb1q91OD<~^Yc5+98(54vhdq}giUZ7M$>Gf9isH)Uj^YOMS#x-Dd82s2Y_=S}T>dD2 zFq=I`AXhL-Fjpu_2+Zfm5zZBf63G>f63rEh5@TdYXGq~(#26)>!WGP*$^DX%fq_Aj z=@y4mW@1`eW?t$o&X6J~Q<M3YkY`>>YC&pVN@`w-OHqD7erd@q-r$VHqSO=^mnS4Y zJ2el=(`39Q>0Xprkl~!4SC*esT9TQcmzd+1T2h{0lnt`RIU}*iCpg6S7Jpb`QD!1U z9wea2c#GNBCqR?&7Pm`ka(+rGSeYi%EnZh2-+b5Hq|}s@%)InlA|XYIdBth@MY*X( za8Zy;k;I_}+!8_(bIk)AdP@RHEIhv`1z`q%5i<h=LlFyzU<DCuAc7r4aDWI-5CMwf zB5n|i2So6K2tE)Y2qO4Fga88rgP*3vEjCDiB22x-o&pKNB2?pVF{kI{6@l!y#gbE8 zl3N6~=@xTtP661uTkI*2P$>f0dyA`}D7B<0F*7eUr3mhZTihjxuqlGOr3mD-TkP@i zi8(p(@hcfVgVN$JU;T{y+*JLN#FEU!yhOdEoWzvO)FS=l{M>?k-ICOb65Z6Y#2o#S z#JtSJ_~PWE%z~0){o>Ms#3KFN{FKt1)MEYk_{_Y_lK6PNg34bUHV{#}A~^;I22i3Z ze#OAR@PV0;k?{i?1Ea<T26aqygTdtjZghh|>jEme!JvHs8@j<Dasd_HU{JV#if%Ai hU%-YwFflTkd|)7jU}NVt|G)qv8rVUwNQQxd0RZ7AAYuRj literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/affine.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/affine.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39667f1870be23948663babfaa2080b05451c54f GIT binary patch literal 8011 zcmd1j<>g{vU|<knUzBdI%E0g##6iX^3=9ko3=E9LDGUq@DGVu$ISjdsQH+crHd78$ zE^`!fE=v>(n9rQU8pWEzkiwk9mdhT+4i;m{;mGBT;$&oSXGmd9VQXPXVM}Gt;%a7& z;&x|9VNc;`VMyVCitwZ`2Qz4Lz69B?$#{!9F)uH_B(WqjKd)Gm=@y4`VopwCQcmhE z4*vp>U}BD+CgUw;U!Q<vkPc+b0pTzf2Qe@(q%uS?rZ7Y?r7%V@r!b{3r?8~3q_Bcq zlgg6Cn#GpJk)qhnkj9uImLlH58^xX?ks{f`5XF%ql_K535XG6Ilp>#^(83bM)y}}e z5XBwLps9R|!znW{EiE%IHPL{Tfq_dwK|ui~qL7nVnOdZfmS3chmRVF>qMKiol3Jut zoSa{jnU}6$m7H0UYL$?ZUzJ#*n_7~XqibYfXs(+CH7`Mr3v60QMrN@>T4`P~$g2t& ziNy+u3MHv|#rZ`F`DqH}shQ~+CB+I>xrrqiRtez=3W<3s3Q3uX#R?^<MY+WanQ01n zsi`TcDSA-TQo#;Lh3P2PsL)ZU)Jy;wR+5pbP?nlpl3%1ykeFEnQvy?wS*(zppIcB` zlA5BB2)D8#E<_<*p;AF#AtkOjK?iJ0c}8kcszO2v#5D=U2?~itaHCT)b5rw*GxPJn zPAyJO%mIZ)S|ZrqqSWGo)Z~)PvecYPh>M{<tALmV<y9sqBq!!6B&8}O=jSCSmZat- zf?QReS(1U|d1wea7Nr+kf!zg)oxJ$WJOz!+yb?`>7)U%MBUPa|vnmx95Se)er6me! zsfi_}MX3;{fRyFM=a-h?(w|qFo0JNUm;BNakoM$^#Js%JoML4C1x5K;3L3Da8=aX~ z5{u>(&ol*4C}gH(rl#m9Bo-9pWTqA?`1%AuQdF@*Nxni+YD#G`W|$W1DY&GjC6?xt zSSchV_~qxNCL|y%PbtbT06QOUds<F@B9ZndDp)1wBo-H2B?M<A7Nw@RKnzQOI7$H= z_MjA01j?xj`FUUmL&5>sRR##>fZ{$?K?Cdtv><SUB!`lG1&AV$!Jv$jio+;SijS{Q z&`8S9&p|WFGfg2OA*84@H6cMqAu%Ndlz~9X!5IXcJE7SLnzkwuP{I(R6X9r(*7!=Q z*i?z%rj%4rcFQkLC2UzyYC%zIacW*ku>vThAf*B*lY)2!MfoYE$t9qKZKRNymy%kL znwOHASE7)cSW=Xkj1r^?32uow#VCm;GcU75K?7Fkq6IEYSOKIeGchN#3KaW!3c0Bz z8Tl#50hyPl2U4R~m0FZv91l&DFBusa82pMrWQf}>7Es>2#hjT}a*Gw5&u+2h#e=fT zFJ5?p1!b38?9hb#iytlyPDHV{Si#BV78^L0DsHiW(gT!Nd5aSsqPJK;ZYg4BU|_h# zR+L&&T9lUzuKytQ1p|l;!pxu=?+yb4LkUAO!ve;I42%plj5Q4LOf^h34Drl0%ry-0 zEHx}O4DqZrtThbrY&C2(4DswW>@^JW95oy@4Dp;boHY#bTs6!o45f@k#wFY}j5W+P zEX~Xa78A%Uo*IUD-WuitGqCx5H5|o0CHxBnN(2`Of$YlSt6>vosA0(Bt6>*sSjfB( z<O<<DnG*g5BADtHGA(3869wsFTF98j1kqW;us{^#n-qp%hLwzdnqs$Di%Sbqi*9km z$Af|<KE4Q4cNT#Hp@^G-fuV>OMDT+M0T3YsB7{MN2#8<>g(PckPC<OdEihGii#;zs zH$Npc=N405-Yw36#G=I9)RNSqTdXDdMadbr*h0XS*ey0lV!g!+SK*UcTyjeQl%7lC z3t-xcS90BADNfBvBgtJW8E<jM$AgQl`1q9!zijn0@^e%5L5+#TyhOdEoWzvO)FORw zKGRJvDA5JGSiiWmAhAe4H$SB`C$(4~QorjJR2E4vFfeE_FfbIWF)%Q2@vt$mF`_~a zCOJkfMixdDMkyvSMvnhH%vFN0=71h7WRpS39h%S>m>3usKy52$1_s8@r$B8h#u|n! zhS>~rnQB2S#uTP(mLlOA#uVlnhAc*qxH$t@h6$Xa6lxe#SZWxun2=<cQ&_WEigarj zQ`l-4vY3%%SW;NCnTxDy7*p757_wN9WLS$_YZy~FY8bLukwn>w0%{mjIBOWP*pNio zi=t~7Q@Cmvve=PCIkGrsGo*0WFwSO3;hD=4%&?NzuZk6vrEQDY85kI<ICK=ix!Sgh z6T|{#Y+G>Fuj0~CfaYjhkScH<2CIT(V+6C(wu(nb0iKO*e=%zOV$@v8MRcM7MI0!N z=OyN*#>cN@DpCO@T*l%ebx<k>6B-~9j`(;`nHnGO%fP_!S%HCpfrpWcQ2+(AF$yrk zum~ecL__rAj%Wi022f^ZC=vigstZFbJ19yQFx4<FWMpJ0WCLZ(8ioZ-AX$(Ih+ibe zz`(GQxd@!;KrSi*<vh3-GSR$Hq{P6$5D#)aC=atSaxwBSviuidu9Ac&Nc1dri?QMt z4>)(~K{F>~WiqIYge6us1_lOB1_lODVlBP~E*5JTQW%?=K>k?32y#8x)l3T+nV4!B zYeDX3E>bCBS-@JuSi-V^t%ecO@NQ*FW0GV56-Ozo3n2-ey~qNrjtQ)e39CAgc^pOI zB`ga#Q`kTSWfoToyClOx=2~X37zenh<Vs-yi?M*kI6=kjLgrf5JWep53!<-vX(3B3 zYYpoH?i3bKk(k9(!;r-*%plDW%%I7gSj-4*%!Ar|s0~PvNQHt1ayV&%8e7pxi6zMy z@t`)OjzV#2VSG+%9w?n>=EWkn!9dz8N!Jc<zXpM8E2IW3$iO;e*Pym*LDG)kHb1DD z4Q=Y=rzsR?Bo?G9BqX3X8=OCpTo3gIh6g}~g4<PK4Yr1$rWL5EfoR)<dOZmVVCjSe zh4Rdt98hb$xUe)ewF=aKC@sm)O)SYwPRxNd^g(78Nir}n==p)mi<kfZ|NsAsJE<a5 zCqGlyE-AkPTv+_#PO8k($<G3bR95jO<yYt=<yV4u6_r(j5Y<^aNtIv)6_uKNx7afh zixW#qiok{!Nr5stxC)a4Wpw7`#FAT_`FW|u@j02<sYUR5?G{^VW?pe=ZV@P}-C~Ej z98%DLszFUQaM@900W!}DWE4|*#Vw}t$|6waM$3%1*wgZh$`gxH(m=Hbs2brC5MyLx zRDxh85k?V40Y)JvF~%wZc=m*9(G-DL3d(qp`WVatSIRsf%fU4>ABY8VR}oki>_I`0 z7}!H#7P#O5vp@w0xbagY3Q_{f)|zY(pICwfK;9_=v%vBo)=HitJ&-54;z6}~X-;Z< z{4JjN_`=e}97tJui#<L*B|kYnzDNdS1jve8Y>>ttxZW%>1POx*r6O05LA=m<IXN{a zCq5o2yi`HzK!tD-$Xy^G7K2RWU|?ZnQea|4KsH8!Zyd@TLPG3dm1K7QS<yQGqA6nF z&cAqy1i14rnIeU=^UoPl1nsRShQoUQa3N^F2$T_uQ<L-aQn2^`t1=Sv(qa97BLm&k zw6x6R%+$ORopK}zLrYzVA#@!U&{3$u7#S!j$}Gr%4<CTX1|Z6C4-Zt04iSI~HwDlT z!{`t}MykRv8zR8yGJ~6~G#MknunOK5rrscd@gN%{0JjDpg9L8qRUyt=5Um0P*L|Qm z2~q7~bofDLfjj*Fz%5&<boeb1-TWGccpelUFA9&ZhPl87)HaRhui+>TDG^v8SR%AQ z7~G=ehj#w?YZ$Wl!2<x`Hfy{{o@$A}0#Qu0-~j*>6EH=<=75F-AcF}aH4F>HU_%1n zzJ{iFkvOO>1~pe8;STCa5IY)xXl+3T1geUpL56{<@*-If3)K87k_WLsEvzC%5DVNq zPzJHUtpIp`4BUcP0%|+y;Ou$xF@hkd_pQMw#U#Wi#>nxHhowpgULh0ifEQ_ktOoV) zi*!LOeGmb51egFfN<hsRP(QuM2-K%VF`YoKugDl=9H<vpWCCKDf(Wp|U;=D9C;&j? zO-1G))1?q@NAIhlwbpJiRwaXm5nw$vP$Lk8!96uLM$iBjw5KLk!+_dTt6^BcT*I`G zk(rr^8PsR11r0Q?6ls;Pg8FMEtP9xj^x8Oz?7-@n!0K@K+Bl0cN>~?gL3?f7&|Vu0 zSd0TSjF!a>?X|Ij#W=y~o;!sL+>>Jii*eVm)UejDEo7->&l3QP@IZ7fWUl1^^Lc9+ zYdF9?JN6p(1w7E69WQ9u4BE5fOWZx!dUoKZ0hFj3VjV+xS8+gkh(*?*9ApC`KtpO( z+(}j0I{De4zF<|6Edv9?OVH?Al@O$lSOx1RR#jA1@q?9SW`lc)Rhd~;BA}jQQhrq? zyzf|5QK`vaWCt=G)GLK_96`fDMc}#xTzuJsWF0^RxSIv8WgJ0VaFON&Vu6QIK^-$q zPP7hVksnCjnSp^JimAM+$OXg$^&M|9mLqkCz{LWn#{`;^1^0xwgrMC<Q1=nsbrfL~ zViaH!U=(Al5=0akbn8F*FfcG^a-fw+kp3gsi=h4^q^AjHxq&<iF7m(xxTFXB5@b#r zsE`L$5;*#MYT*7JNTnw4Ew1?Zw9=B&qSW~KB2ZM{Vk@aE$jnQJRPvzmum}`Qw>Tif zBYAn?zG;*oczjn6I=-uyn^RB(9=~Su1&{cGdy_>VE0CfA>{O5|Z*kZ_G}?jETrsHM T&BG+X#KFYF$ipbaELH^oF5vSb literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/affine.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/affine.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c47fed9d260e0af01681cd36e39620f2209a26b3 GIT binary patch literal 12963 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/decoder.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/decoder.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76a4b2187f9eabbe13f6151c3b2f5c962b577852 GIT binary patch literal 1746 zcmd1j<>g{vU|<knUzG00#=!6x#6iX^3=9ko3=9m#W(*7rDGVu$ISjdsQH+crHd78$ zE^`z!n9Z2O62;=qkiwk8(!!9!lFFFH+RPlqmckg!pvn3YWTKxY<1J=ipMYc#2O0A~ zImICi3=F9ZQH&`JQA{a}smv)%smv+Nsmv)Xsmv*?sVpgMsjO){?F?y*DeNg6Ej&?d zDV(Y7SsW=`ATo_5g*%0(g(ZqJg*Sz-g&~Tooq>fRiaVG=lm8aCOKNg{N@|f$aER|M zuFSlG(vtY%%&OE|+!>iEDXDo-PJU?#T!t&JG&epcu`;!&_!fIgQGP*wX~`|Nl+?1! z<kVz#sGC6)h|R&kz`zU&rU(WGh7yKmh6RiZ85kLA7;BiAm}(f}L72IQxrQO0rG}-3 zA)d8_EsGr_Tf>sVSi_pal)~K0R>Kg_QNmfnRKpAwVd({_<f;LQbEhzX0@BYdM3b!u z6emTj3=9lKAggcjCS|5%7NsVaWaj53<`jXPa*I1Du_QSoJ}tATxI~lX7E4}yX5KB< zy!iam5{Lq>#N?99vP6&`O`cn<#ia$QMYlNO<1_OzOXA~^tYCxN!<3hIiv=8jEIGv` zxkXG23=FrJb8`xcI2jliG}&*l6sP8-Vbcn>60B+^<1Nnk_~e|#;^O%Dl?=b^^fU5v zQ}s&{OEMGl67`aD5>ql$i}aK8a|`ly(+f&;bMsSDbM%W#3lfX;bMsS5b5e`-Qy_7v zS5R3bz`(!&a$&Iq0|NsWBOenRBO4<J6AL2?Bga1u7A8iH|6EK}B1o~X2lL}C#)?~P zMX4pFMR~~}uYjTwghBZMWTZ1FI_nr17-|@^7-E=fnQED9SxOieFx4<*G1q`dmW9j< zSZf%v*cLM45@%wnWvykaVORi)Y}OjKG^T}2F-*1WwH!4J3pi@n7l5N%grSBZi)A6x zLdIIo8cv8<4MP^!LgruwO~$HjE(IvCDo89!%vGqcQYgtUO3u&=NzE(HFH(qx#5O2F z>nIeb7RKkK=IJOPQh6-G0EmZ+iP4Xg84w0&a^GSt&PXgsy~PT4!Y$US)S~=ia7qNH z$y-b%`QWH75(cFl5l|vwFG>aLDFTJ7CRdRtNJa`I!-a79Eq18OZ!yN-V#+YM#guGt zizy@T7E^NGEjEZ_ia^l}AtXWC+0*ii$`gxHKn51`F)%Rjuu3pXFtYs@VUl1LV5|~G zj(DirWJXXdLotXA$}r%_Rsj`pj5Q2d46_+hKoQJ1n<0g{h9Qe-HbV*vDB5Q;%;f;* z!zytklQj?_ZCk~sqkvST*jDlCC?E<Fur$Og;1b7HlLaZifO0b=h!`P3gyvh0`1qpK zf};3%RZ!9drCAk5^t268pveQu%Xx{psqyi*xZ>j>IVV2;7EgS9VQFFxRE9Y-ujCeM zT26jq$t~vMk|J<+Dv||-EE^<g6={N^N(&^y3(dF5sX00E@sLOWJ5UUy1QZ=bpb`*N zE)|1<l!HNyQH)<e04%D>ev1Q~Ui9+viUdK%34-&q9>itEdZ1zi<Rhr<zTm75){0~k b*gB9+w>WGd8tp(42)2%gfrpWUQH%)y8nLvR literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/decoder.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/decoder.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6de6a887d7ce612ec0a7ef15992c489fb6b21aa7 GIT binary patch literal 2997 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/dropout.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/dropout.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9431bcc12f190fe9a1715caba2b9b9b578ef7e8 GIT binary patch literal 6173 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 W58PJbVd7!pVB%pEViwXCGXnrdC4;E| literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/dropout.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/dropout.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24e3f7b05eeb7b0809eb5b72992b12d9e5c160d4 GIT binary patch literal 8710 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 G4iNyULAJ{P literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/gnn.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/gnn.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c9899ee4c9fc3620942fc1768b69b489f133280 GIT binary patch literal 5471 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/gnn.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/gnn.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7471454ca9e111edcc54852b2bfeafb07ef79179 GIT binary patch literal 7820 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 BS+@WH literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/lstm.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/lstm.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b41ac7e996529a8790ae248cd831e01297c48eb3 GIT binary patch literal 10155 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/lstm.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/lstm.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbe023f8403b631f77886bc738ca050d7e7cf659 GIT binary patch literal 16394 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	GWhN*8#PK;6(<(0GH@4JkR0%mR-U(JQi6L|;*{ zyeMTkfn`GAMD`yyxP?A2uyQ&u-VhdtnB>>xcacZt3XjYMFaph*d3SlwV7bU6dxb~# z0*~wsaDrW{ytZNo%gVYnbr-bkE(qIS6t=%2Y~SH>S5Rz<<P5Wmf=X8el{(lS@QY3; z>8QEDAq`H<ez!Pa>uifa1BAb{VT*aA2{&JVSwPgFj^OJkKtz$7x@f(c*kn+l1+Bap zK$S4K-@?Jlz|bx<ouP&i)PsRY*DxX~UhK;*P#Yn&EVaxvEXd8qT2^rLnZ1^+hN(dh z*OCn6K~3bfJ>UirYYlS46=fZDEk_MU4M#0kEoYuw4Fis)6HGOXh&4c{%{*{ZgR_<k zR}%}DyFdfPNR4TfHHo#HHC)&mY-E|nh1}FaHUYJGc43&n7;9C_T_O&NIS`ozU!Vc% zEu#9o7BrXzA095!E0G21fZ!}p@dakqFeArh4Fl48c9eCTT|yl~(8f74Mq`n=h5`H1 zjT+_}&Km9%#x$fRa19r_NE&ER7*xALT*QrNF4v$fp8>}v518bw<*Q-H0!=7`brsbU za03g58&E{RZU9Y6gH5YJaYG90GFAqL)u2WhSQczQKbRD#6-0>-c%!+7r-na`DFv-F zRLg^+8Z^lbHnE1cMgYBuTg!_>EnkfwhFZQFo?7M_wgpIO18gvusNqFTNsJ6N>^M~N zp{tz0*ke;-2sQ>xfVx$P5(7Ek)i7qkBMx;9Z!I&5PY_|mhQ0&|hdOq2b!kksOn6HJ zgiBCTaV=8~a}5)uyOOBP3Z2siRpFRRhG6Bk0&L|_UY;JVSyi-YLa>1f1>nsW3gEf# zq?}ZRoYcJZk_^y7Bk*nv)Ty@&^c6}v3eY)V$Y2Im8%jXiK@>o}mi*$>6!08)dA>qP zDri++F=)0Fyrd{0IRVu!kn<8U5<u#~OKLz1fIxF2;Fe3V7Kn+MCecwq^qO>_`v|~` zl0gfDAWNG-6Yrog#LUDTr~=4*EquZgWFZKH_HuxyB~x=!b5rw5U=zk*8?d-BnKo_& z4M0)Hg`oN1j0*57hrIj}g@U5|vdom!6di@6{E`gh2vA5#1@D*u?d1TCtzvo>KKGiC z;Fq753R-;z4?ld1z3`+;9eC1(q#?pd3baBDyvQ89ZiBQG42oco{^Hc+{Ja#10gwcm zpEfXQ5@qcGDD5Sb*g}{2VaX9bnc1ldkhZ@LcrG219Tbui^AwU&6^c_qgW#a$4v>9A z2?-f`Wtpkv8lda~Q3{!xAtLK&A}t001se#1mYx)6=4R$37UfiecReLzCXxgy=Lkej z0NaQ)e88hRekk2cP>T}WC3XP~>o7t)nlhkHF=%)Kxx0xzREpf+2ethsGWEy?Gl2X2 znv6xDo}MOT2;&xGW|1eTdjx9Aq7GnaqxY%s49zewGB6Z_RuY1SW<-oGfYA!W34t?2 zW~9TqR5Q}&$X*mxgGgQwF#<Q;!Q<^AMYf=kC8=91DTyVCMc{s;BdGJ}3L?N0%+Vkg zXcoGt5Y$iQE6y(}Nd@m|%1llzzQqDcB#?eAXr$^EYjHtNW=T;ONEfIlTht9=fm$9# zQ$Va(5CK|EQ4|Mafd;lfUD3qkY)JnW)Qh+!PzoyIk*v`ahV*l%g7kp<x!@iz*u9`( zpj*rt@p-qHljHM>>Oe|BgJeYoAl599qnRt>GeJr+K}s@jF;~PVfw)N^ZW1IKKrJm$ zIz`2hPA_=9U6nYFXt@fC#T+K^{PhPj1}UXEvMV^QXxLoWaK5DBd{M*oiiT^4bqC`O zQH2G9Q{p<fZU~D`DC!9AV1B^O+hKJ>P-wdJB<UF;bK+N&T+w&BDC=~<>q0=tm4Jkc zf{9lI6FZzB8VWlcI~*Sfi(eO3yCkf(plF4~6>X=B!p>KOojYAXt0r&o@b<fPxlJ&c zVh@^VG~Xe0AmoZ`=tZ8eD?DKxj0B{gqRxf$a>{&U;N_I*aJ(xZI)!_N<BaNy0@_yu zv^yN3Jy9lJV`v{daRcL;lnpLhd@hPRUJ-Ykz;Xke3?b=l1LFk|ql+R&S44~^Fy4?; zx-MsMNzPz{;D*2rg*y~Clxzv#k$8adfZ+j_J?R%r+)l8Z;kghRc832#WXeUk)GKnS zo&Fup6Qw37Pbj{@FMNex@dE=3uigzMwd+bImy}F41nv;rVYnl4hshrC1BwS64-_77 zIih~S!s~>~8J`Q0QD^)w#AaN`%DbqPe?=*OBL4*DiBS`hXBgiVlb({fKzKp&0<INK z7sd3ii0MyY1_@>_FkZpDK<lEI?iDdztU@;ggh49=_`xe)i#z>${5$+_@St!z{h#tk z%`lviaYfE(gU1yU?-LPMeA6!Sq+j7l?_j*kE7TJ?p?HSlMP9ipymCufmvF97UQu{a z!SITL;RRm94yGHtg4cN!F7YZX5Lys%Mb+*iul*HX`wk}1B$QG|X$KED3u`iiGqGDy zI4BeIK&HV#U7sRweg(6@c^J$BXSzsGo&e`YP&2g%)Iu)`1?gsk3?G3eGmF4;Zh0V; zV0n<3CZn4s4|vk6s0bth&VwKc$beG`NDQ1C%Rns9&{GlEDzE_+ATiLerzTqwI0u6= zImEtcAStk-=^$5dLniC}L81X5A`nD?){lVa>%r5q;Bp93n1I&77J<gzi-JL!5VV{N znqxtJ0(%TJ!Uo#{1zGvp!0>@d6twmgM3^y1%iNGtz9A|7fme!E0knb@4`IOpTJ#Dh zMA%u?Kx<&3gb)|2$Oi^gLWMz6?gOtPtIP)mEQAjugSGt!b}LrV4-CW+;CKgnOjGz4 zSA2Y0DQHJre0&k88o9+*Qds~RLIh3a7J>S6MWFd~@NnTR4#<E?ULIs&kSKT~nI2@# zaj_nB%^qa%Q3R$GE?tzDR|J~Exg`Xbg7+1`13yKeB~`cBAghhQ3wyzi1P>fT+zi?z z^ozp=Vxe8p1_lOD-NjJM&B(y;ftit!@dFzJqw)m?C1mt~LE{2$^nih<0Ss?2h+aTN zHyHFUprRWLMi)@g4F=~6*w6<yKSoB-YG&M2M^R7ZM+UI`7YOwMN+mHBFfodLV8BjJ SNSc!Q5iIuwOk%172NnQIwNi8d literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/mlp.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/mlp.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..856587590500e87d19034d97b32fba8d05cf1ddb GIT binary patch literal 2397 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/mlp.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/mlp.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69c92f7adbd0833ce5ccf154ad0997ff3e2cb672 GIT binary patch literal 3517 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/pretrained.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/pretrained.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe5270597f6a76ea7e0866c0b20e3227024c7199 GIT binary patch literal 10694 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 ZrDD(!JP(rq69*FyxUV6^EL18M3IGHrEQbI9 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/pretrained.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/pretrained.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75014d025196b5be3ee840b78c519e0d692f6c4c GIT binary patch literal 16517 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 UV4A}DkpU$41x$XxAi;4706db;N&o-= literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/transformer.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/transformer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0aa648d7943086a791868bfe31ccd2dac17e4d0e GIT binary patch literal 17309 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	e}zpmtwCC5U8-6gUS$ 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/__pycache__/transformer.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/transformer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb5927d047ca6f9c5b2983417896033e2322681e GIT binary patch literal 36701 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/modules/affine.py b/tania_scripts/supar/modules/affine.py new file mode 100644 index 0000000..fe5defb --- /dev/null +++ b/tania_scripts/supar/modules/affine.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import Callable, Optional + +import torch +import torch.nn as nn +from supar.modules.mlp import MLP + + +class Biaffine(nn.Module): + r""" + Biaffine layer for first-order scoring :cite:`dozat-etal-2017-biaffine`. + + This function has a tensor of weights :math:`W` and bias terms if needed. + The score :math:`s(x, y)` of the vector pair :math:`(x, y)` is computed as :math:`x^T W y / d^s`, + where `d` and `s` are vector dimension and scaling factor respectively. + :math:`x` and :math:`y` can be concatenated with bias terms. + + Args: + n_in (int): + The size of the input feature. + n_out (int): + The number of output channels. + n_proj (Optional[int]): + If specified, applies MLP layers to reduce vector dimensions. Default: ``None``. + dropout (Optional[float]): + If specified, applies a :class:`SharedDropout` layer with the ratio on MLP outputs. Default: 0. + scale (float): + Factor to scale the scores. Default: 0. + bias_x (bool): + If ``True``, adds a bias term for tensor :math:`x`. Default: ``True``. + bias_y (bool): + If ``True``, adds a bias term for tensor :math:`y`. Default: ``True``. + decompose (bool): + If ``True``, represents the weight as the product of 2 independent matrices. Default: ``False``. + init (Callable): + Callable initialization method. Default: `nn.init.zeros_`. + """ + + def __init__( + self, + n_in: int, + n_out: int = 1, + n_proj: Optional[int] = None, + dropout: Optional[float] = 0, + scale: int = 0, + bias_x: bool = True, + bias_y: bool = True, + decompose: bool = False, + init: Callable = nn.init.zeros_ + ) -> Biaffine: + super().__init__() + + self.n_in = n_in + self.n_out = n_out + self.n_proj = n_proj + self.dropout = dropout + self.scale = scale + self.bias_x = bias_x + self.bias_y = bias_y + self.decompose = decompose + self.init = init + + if n_proj is not None: + self.mlp_x, self.mlp_y = MLP(n_in, n_proj, dropout), MLP(n_in, n_proj, dropout) + self.n_model = n_proj or n_in + if not decompose: + self.weight = nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x, self.n_model + bias_y)) + else: + self.weight = nn.ParameterList((nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x)), + nn.Parameter(torch.Tensor(n_out, self.n_model + bias_y)))) + + self.reset_parameters() + + def __repr__(self): + s = f"n_in={self.n_in}" + if self.n_out > 1: + s += f", n_out={self.n_out}" + if self.n_proj is not None: + s += f", n_proj={self.n_proj}" + if self.dropout > 0: + s += f", dropout={self.dropout}" + if self.scale != 0: + s += f", scale={self.scale}" + if self.bias_x: + s += f", bias_x={self.bias_x}" + if self.bias_y: + s += f", bias_y={self.bias_y}" + if self.decompose: + s += f", decompose={self.decompose}" + return f"{self.__class__.__name__}({s})" + + def reset_parameters(self): + if self.decompose: + for i in self.weight: + self.init(i) + else: + self.init(self.weight) + + def forward( + self, + x: torch.Tensor, + y: torch.Tensor + ) -> torch.Tensor: + r""" + Args: + x (torch.Tensor): ``[batch_size, seq_len, n_in]``. + y (torch.Tensor): ``[batch_size, seq_len, n_in]``. + + Returns: + ~torch.Tensor: + A scoring tensor of shape ``[batch_size, n_out, seq_len, seq_len]``. + If ``n_out=1``, the dimension for ``n_out`` will be squeezed automatically. + """ + + if hasattr(self, 'mlp_x'): + x, y = self.mlp_x(x), self.mlp_y(y) + if self.bias_x: + x = torch.cat((x, torch.ones_like(x[..., :1])), -1) + if self.bias_y: + y = torch.cat((y, torch.ones_like(y[..., :1])), -1) + # [batch_size, n_out, seq_len, seq_len] + if self.decompose: + wx = torch.einsum('bxi,oi->box', x, self.weight[0]) + wy = torch.einsum('byj,oj->boy', y, self.weight[1]) + s = torch.einsum('box,boy->boxy', wx, wy) + else: + s = torch.einsum('bxi,oij,byj->boxy', x, self.weight, y) + return s.squeeze(1) / self.n_in ** self.scale + + +class Triaffine(nn.Module): + r""" + Triaffine layer for second-order scoring :cite:`zhang-etal-2020-efficient,wang-etal-2019-second`. + + This function has a tensor of weights :math:`W` and bias terms if needed. + The score :math:`s(x, y, z)` of the vector triple :math:`(x, y, z)` is computed as :math:`x^T z^T W y / d^s`, + where `d` and `s` are vector dimension and scaling factor respectively. + :math:`x` and :math:`y` can be concatenated with bias terms. + + Args: + n_in (int): + The size of the input feature. + n_out (int): + The number of output channels. + n_proj (Optional[int]): + If specified, applies MLP layers to reduce vector dimensions. Default: ``None``. + dropout (Optional[float]): + If specified, applies a :class:`SharedDropout` layer with the ratio on MLP outputs. Default: 0. + scale (float): + Factor to scale the scores. Default: 0. + bias_x (bool): + If ``True``, adds a bias term for tensor :math:`x`. Default: ``False``. + bias_y (bool): + If ``True``, adds a bias term for tensor :math:`y`. Default: ``False``. + decompose (bool): + If ``True``, represents the weight as the product of 3 independent matrices. Default: ``False``. + init (Callable): + Callable initialization method. Default: `nn.init.zeros_`. + """ + + def __init__( + self, + n_in: int, + n_out: int = 1, + n_proj: Optional[int] = None, + dropout: Optional[float] = 0, + scale: int = 0, + bias_x: bool = False, + bias_y: bool = False, + decompose: bool = False, + init: Callable = nn.init.zeros_ + ) -> Triaffine: + super().__init__() + + self.n_in = n_in + self.n_out = n_out + self.n_proj = n_proj + self.dropout = dropout + self.scale = scale + self.bias_x = bias_x + self.bias_y = bias_y + self.decompose = decompose + self.init = init + + if n_proj is not None: + self.mlp_x = MLP(n_in, n_proj, dropout) + self.mlp_y = MLP(n_in, n_proj, dropout) + self.mlp_z = MLP(n_in, n_proj, dropout) + self.n_model = n_proj or n_in + if not decompose: + self.weight = nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x, self.n_model, self.n_model + bias_y)) + else: + self.weight = nn.ParameterList((nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x)), + nn.Parameter(torch.Tensor(n_out, self.n_model)), + nn.Parameter(torch.Tensor(n_out, self.n_model + bias_y)))) + + self.reset_parameters() + + def __repr__(self): + s = f"n_in={self.n_in}" + if self.n_out > 1: + s += f", n_out={self.n_out}" + if self.n_proj is not None: + s += f", n_proj={self.n_proj}" + if self.dropout > 0: + s += f", dropout={self.dropout}" + if self.scale != 0: + s += f", scale={self.scale}" + if self.bias_x: + s += f", bias_x={self.bias_x}" + if self.bias_y: + s += f", bias_y={self.bias_y}" + if self.decompose: + s += f", decompose={self.decompose}" + return f"{self.__class__.__name__}({s})" + + def reset_parameters(self): + if self.decompose: + for i in self.weight: + self.init(i) + else: + self.init(self.weight) + + def forward( + self, + x: torch.Tensor, + y: torch.Tensor, + z: torch.Tensor + ) -> torch.Tensor: + r""" + Args: + x (torch.Tensor): ``[batch_size, seq_len, n_in]``. + y (torch.Tensor): ``[batch_size, seq_len, n_in]``. + z (torch.Tensor): ``[batch_size, seq_len, n_in]``. + + Returns: + ~torch.Tensor: + A scoring tensor of shape ``[batch_size, n_out, seq_len, seq_len, seq_len]``. + If ``n_out=1``, the dimension for ``n_out`` will be squeezed automatically. + """ + + if hasattr(self, 'mlp_x'): + x, y, z = self.mlp_x(x), self.mlp_y(y), self.mlp_z(y) + if self.bias_x: + x = torch.cat((x, torch.ones_like(x[..., :1])), -1) + if self.bias_y: + y = torch.cat((y, torch.ones_like(y[..., :1])), -1) + # [batch_size, n_out, seq_len, seq_len, seq_len] + if self.decompose: + wx = torch.einsum('bxi,oi->box', x, self.weight[0]) + wz = torch.einsum('bzk,ok->boz', z, self.weight[1]) + wy = torch.einsum('byj,oj->boy', y, self.weight[2]) + s = torch.einsum('box,boz,boy->bozxy', wx, wz, wy) + else: + w = torch.einsum('bzk,oikj->bozij', z, self.weight) + s = torch.einsum('bxi,bozij,byj->bozxy', x, w, y) + return s.squeeze(1) / self.n_in ** self.scale diff --git a/tania_scripts/supar/modules/decoder.py b/tania_scripts/supar/modules/decoder.py new file mode 100644 index 0000000..2e9f97f --- /dev/null +++ b/tania_scripts/supar/modules/decoder.py @@ -0,0 +1,38 @@ +import torch.nn as nn +from supar.modules.mlp import MLP +import torch + +class DecoderLSTM(nn.Module): + def __init__(self, input_size: int, hidden_size: int, output_size: int, num_layers: int, dropout: float, device: str): + super().__init__() + + self.input_size, self.hidden_size = input_size, hidden_size + self.output_size = output_size + self.num_layers = num_layers + + self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size, + num_layers=num_layers, bidirectional=False, + dropout=dropout, batch_first=True) + + self.mlp = MLP(n_in=hidden_size, n_out=output_size, dropout=dropout, + activation=True) + self.device = device + + def forward(self, x: torch.Tensor) -> torch.Tensor: + r""" + :param x: torch.Tensor [batch_size, seq_len, input_size] + :returns torch.Tensor [batch_size, seq_len, output_size] + """ + batch_size, seq_len, _ = x.shape + + # LSTM forward pass + h0, c0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(self.device), \ + torch.zeros(self.num_layers, batch_size, self.hidden_size).to(self.device) + hn, cn = self.lstm(x, (h0, c0)) + + # MLP forward pass + output = self.mlp(hn.reshape(batch_size*seq_len, self.hidden_size)) + return output.reshape(batch_size, seq_len, self.output_size) + + def __repr__(self): + return f'DecoderLSTM(input_size={self.input_size}, hidden_size={self.hidden_size}, num_layers={self.num_layers}, output_size={self.output_size}' diff --git a/tania_scripts/supar/modules/dropout.py b/tania_scripts/supar/modules/dropout.py new file mode 100644 index 0000000..1e3c947 --- /dev/null +++ b/tania_scripts/supar/modules/dropout.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import List + +import torch +import torch.nn as nn + + +class TokenDropout(nn.Module): + r""" + :class:`TokenDropout` seeks to randomly zero the vectors of some tokens with the probability of `p`. + + Args: + p (float): + The probability of an element to be zeroed. Default: 0.5. + + Examples: + >>> batch_size, seq_len, hidden_size = 1, 3, 5 + >>> x = torch.ones(batch_size, seq_len, hidden_size) + >>> nn.Dropout()(x) + tensor([[[0., 2., 2., 0., 0.], + [2., 2., 0., 2., 2.], + [2., 2., 2., 2., 0.]]]) + >>> TokenDropout()(x) + tensor([[[2., 2., 2., 2., 2.], + [0., 0., 0., 0., 0.], + [2., 2., 2., 2., 2.]]]) + """ + + def __init__(self, p: float = 0.5) -> TokenDropout: + super().__init__() + + self.p = p + + def __repr__(self): + return f"{self.__class__.__name__}(p={self.p})" + + def forward(self, x: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): + A tensor of any shape. + Returns: + A tensor with the same shape as `x`. + """ + + if not self.training: + return x + return x * (x.new_empty(x.shape[:2]).bernoulli_(1 - self.p) / (1 - self.p)).unsqueeze(-1) + + +class SharedDropout(nn.Module): + r""" + :class:`SharedDropout` differs from the vanilla dropout strategy in that the dropout mask is shared across one dimension. + + Args: + p (float): + The probability of an element to be zeroed. Default: 0.5. + batch_first (bool): + If ``True``, the input and output tensors are provided as ``[batch_size, seq_len, *]``. + Default: ``True``. + + Examples: + >>> batch_size, seq_len, hidden_size = 1, 3, 5 + >>> x = torch.ones(batch_size, seq_len, hidden_size) + >>> nn.Dropout()(x) + tensor([[[0., 2., 2., 0., 0.], + [2., 2., 0., 2., 2.], + [2., 2., 2., 2., 0.]]]) + >>> SharedDropout()(x) + tensor([[[2., 0., 2., 0., 2.], + [2., 0., 2., 0., 2.], + [2., 0., 2., 0., 2.]]]) + """ + + def __init__(self, p: float = 0.5, batch_first: bool = True) -> SharedDropout: + super().__init__() + + self.p = p + self.batch_first = batch_first + + def __repr__(self): + s = f"p={self.p}" + if self.batch_first: + s += f", batch_first={self.batch_first}" + return f"{self.__class__.__name__}({s})" + + def forward(self, x: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): + A tensor of any shape. + Returns: + A tensor with the same shape as `x`. + """ + + if not self.training: + return x + return x * self.get_mask(x[:, 0], self.p).unsqueeze(1) if self.batch_first else self.get_mask(x[0], self.p) + + @staticmethod + def get_mask(x: torch.Tensor, p: float) -> torch.FloatTensor: + return x.new_empty(x.shape).bernoulli_(1 - p) / (1 - p) + + +class IndependentDropout(nn.Module): + r""" + For :math:`N` tensors, they use different dropout masks respectively. + When :math:`N-M` of them are dropped, the remaining :math:`M` ones are scaled by a factor of :math:`N/M` to compensate, + and when all of them are dropped together, zeros are returned. + + Args: + p (float): + The probability of an element to be zeroed. Default: 0.5. + + Examples: + >>> batch_size, seq_len, hidden_size = 1, 3, 5 + >>> x, y = torch.ones(batch_size, seq_len, hidden_size), torch.ones(batch_size, seq_len, hidden_size) + >>> x, y = IndependentDropout()(x, y) + >>> x + tensor([[[1., 1., 1., 1., 1.], + [0., 0., 0., 0., 0.], + [2., 2., 2., 2., 2.]]]) + >>> y + tensor([[[1., 1., 1., 1., 1.], + [2., 2., 2., 2., 2.], + [0., 0., 0., 0., 0.]]]) + """ + + def __init__(self, p: float = 0.5) -> IndependentDropout: + super().__init__() + + self.p = p + + def __repr__(self): + return f"{self.__class__.__name__}(p={self.p})" + + def forward(self, *items: List[torch.Tensor]) -> List[torch.Tensor]: + r""" + Args: + items (List[~torch.Tensor]): + A list of tensors that have the same shape except the last dimension. + Returns: + A tensors are of the same shape as `items`. + """ + + if not self.training: + return items + masks = [x.new_empty(x.shape[:2]).bernoulli_(1 - self.p) for x in items] + total = sum(masks) + scale = len(items) / total.max(torch.ones_like(total)) + masks = [mask * scale for mask in masks] + return [item * mask.unsqueeze(-1) for item, mask in zip(items, masks)] diff --git a/tania_scripts/supar/modules/gnn.py b/tania_scripts/supar/modules/gnn.py new file mode 100644 index 0000000..8f2108c --- /dev/null +++ b/tania_scripts/supar/modules/gnn.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import torch +import torch.nn as nn + + +class GraphConvolutionalNetwork(nn.Module): + r""" + Multiple GCN layers with layer normalization and residual connections, each executing the operator + from the `"Semi-supervised Classification with Graph Convolutional Networks" <https://arxiv.org/abs/1609.02907>`_ paper + + .. math:: + \mathbf{X}^{\prime} = \mathbf{\hat{D}}^{-1/2} \mathbf{\hat{A}} + \mathbf{\hat{D}}^{-1/2} \mathbf{X} \mathbf{\Theta}, + + where :math:`\mathbf{\hat{A}} = \mathbf{A} + \mathbf{I}` denotes the adjacency matrix with inserted self-loops + and :math:`\hat{D}_{ii} = \sum_{j=0} \hat{A}_{ij}` its diagonal degree matrix. + + Its node-wise formulation is given by: + + .. math:: + \mathbf{x}^{\prime}_i = \mathbf{\Theta}^{\top} \sum_{j \in + \mathcal{N}(v) \cup \{ i \}} \frac{e_{j,i}}{\sqrt{\hat{d}_j + \hat{d}_i}} \mathbf{x}_j + + with :math:`\hat{d}_i = 1 + \sum_{j \in \mathcal{N}(i)} e_{j,i}`, where + :math:`e_{j,i}` denotes the edge weight from source node :obj:`j` to target + node :obj:`i` (default: :obj:`1.0`) + + Args: + n_model (int): + The size of node feature vectors. + n_layers (int): + The number of GCN layers. Default: 1. + selfloop (bool): + If ``True``, adds self-loops to adjacent matrices. Default: ``True``. + dropout (float): + The probability of feature vector elements to be zeroed. Default: 0. + norm (bool): + If ``True``, adds a :class:`~torch.nn.LayerNorm` layer after each GCN layer. Default: ``True``. + """ + + def __init__( + self, + n_model: int, + n_layers: int = 1, + selfloop: bool = True, + dropout: float = 0., + norm: bool = True + ) -> GraphConvolutionalNetwork: + super().__init__() + + self.n_model = n_model + self.n_layers = n_layers + self.selfloop = selfloop + self.norm = norm + + self.conv_layers = nn.ModuleList([ + nn.Sequential( + GraphConv(n_model), + nn.LayerNorm([n_model]) if norm else nn.Identity() + ) + for _ in range(n_layers) + ]) + self.dropout = nn.Dropout(dropout) + + def __repr__(self): + s = f"n_model={self.n_model}, n_layers={self.n_layers}" + if self.selfloop: + s += f", selfloop={self.selfloop}" + if self.dropout.p > 0: + s += f", dropout={self.dropout.p}" + if self.norm: + s += f", norm={self.norm}" + return f"{self.__class__.__name__}({s})" + + def forward(self, x: torch.Tensor, adj: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): + Node feature tensors of shape ``[batch_size, seq_len, n_model]``. + adj (~torch.Tensor): + Adjacent matrix of shape ``[batch_size, seq_len, seq_len]``. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask for covering the unpadded tokens in each chart. + + Returns: + ~torch.Tensor: + Node feature tensors of shape ``[batch_size, seq_len, n_model]``. + """ + + if self.selfloop: + adj.diagonal(0, 1, 2).fill_(1.) + adj = adj.masked_fill(~(mask.unsqueeze(1) & mask.unsqueeze(2)), 0) + for conv, norm in self.conv_layers: + x = norm(x + self.dropout(conv(x, adj).relu())) + return x + + +class GraphConv(nn.Module): + + def __init__(self, n_model: int, bias: bool = True) -> GraphConv: + super().__init__() + + self.n_model = n_model + + self.linear = nn.Linear(n_model, n_model, bias=False) + self.bias = nn.Parameter(torch.zeros(n_model)) if bias else None + + def __repr__(self): + s = f"n_model={self.n_model}" + if self.bias is not None: + s += ", bias=True" + return f"{self.__class__.__name__}({s})" + + def forward(self, x: torch.Tensor, adj: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): + Node feature tensors of shape ``[batch_size, seq_len, n_model]``. + adj (~torch.Tensor): + Adjacent matrix of shape ``[batch_size, seq_len, seq_len]``. + + Returns: + ~torch.Tensor: + Node feature tensors of shape ``[batch_size, seq_len, n_model]``. + """ + + x = self.linear(x) + x = torch.matmul(adj * (adj.sum(1, True) * adj.sum(2, True) + torch.finfo(adj.dtype).eps).pow(-0.5), x) + if self.bias is not None: + x = x + self.bias + return x diff --git a/tania_scripts/supar/modules/lstm.py b/tania_scripts/supar/modules/lstm.py new file mode 100644 index 0000000..759f9c1 --- /dev/null +++ b/tania_scripts/supar/modules/lstm.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import List, Optional, Tuple + +import torch +import torch.nn as nn +from supar.modules.dropout import SharedDropout +from torch.nn.modules.rnn import apply_permutation +from torch.nn.utils.rnn import PackedSequence, pack_padded_sequence + + +class CharLSTM(nn.Module): + r""" + CharLSTM aims to generate character-level embeddings for tokens. + It summarizes the information of characters in each token to an embedding using a LSTM layer. + + Args: + n_char (int): + The number of characters. + n_embed (int): + The size of each embedding vector as input to LSTM. + n_hidden (int): + The size of each LSTM hidden state. + n_out (int): + The size of each output vector. Default: 0. + If 0, equals to the size of hidden states. + pad_index (int): + The index of the padding token in the vocabulary. Default: 0. + dropout (float): + The dropout ratio of CharLSTM hidden states. Default: 0. + """ + + def __init__( + self, + n_chars: int, + n_embed: int, + n_hidden: int, + n_out: int = 0, + pad_index: int = 0, + dropout: float = 0 + ) -> CharLSTM: + super().__init__() + + self.n_chars = n_chars + self.n_embed = n_embed + self.n_hidden = n_hidden + self.n_out = n_out or n_hidden + self.pad_index = pad_index + + self.embed = nn.Embedding(num_embeddings=n_chars, embedding_dim=n_embed) + self.lstm = nn.LSTM(input_size=n_embed, hidden_size=n_hidden//2, batch_first=True, bidirectional=True) + self.dropout = nn.Dropout(p=dropout) + self.projection = nn.Linear(in_features=n_hidden, out_features=self.n_out) if n_hidden != self.n_out else nn.Identity() + + def __repr__(self): + s = f"{self.n_chars}, {self.n_embed}" + if self.n_hidden != self.n_out: + s += f", n_hidden={self.n_hidden}" + s += f", n_out={self.n_out}, pad_index={self.pad_index}" + if self.dropout.p != 0: + s += f", dropout={self.dropout.p}" + return f"{self.__class__.__name__}({s})" + + def forward(self, x: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): ``[batch_size, seq_len, fix_len]``. + Characters of all tokens. + Each token holds no more than `fix_len` characters, and the excess is cut off directly. + Returns: + ~torch.Tensor: + The embeddings of shape ``[batch_size, seq_len, n_out]`` derived from the characters. + """ + + # [batch_size, seq_len, fix_len] + mask = x.ne(self.pad_index) + # [batch_size, seq_len] + lens = mask.sum(-1) + char_mask = lens.gt(0) + + # [n, fix_len, n_embed] + x = self.embed(x[char_mask]) + x = pack_padded_sequence(x, lens[char_mask].tolist(), True, False) + x, (h, _) = self.lstm(x) + # [n, fix_len, n_hidden] + h = self.dropout(torch.cat(torch.unbind(h), -1)) + # [n, fix_len, n_out] + h = self.projection(h) + # [batch_size, seq_len, n_out] + return h.new_zeros(*lens.shape, self.n_out).masked_scatter_(char_mask.unsqueeze(-1), h) + + +class VariationalLSTM(nn.Module): + r""" + VariationalLSTM :cite:`yarin-etal-2016-dropout` is an variant of the vanilla bidirectional LSTM + adopted by Biaffine Parser with the only difference of the dropout strategy. + It drops nodes in the LSTM layers (input and recurrent connections) + and applies the same dropout mask at every recurrent timesteps. + + APIs are roughly the same as :class:`~torch.nn.LSTM` except that we only allows + :class:`~torch.nn.utils.rnn.PackedSequence` as input. + + Args: + input_size (int): + The number of expected features in the input. + hidden_size (int): + The number of features in the hidden state `h`. + num_layers (int): + The number of recurrent layers. Default: 1. + bidirectional (bool): + If ``True``, becomes a bidirectional LSTM. Default: ``False`` + dropout (float): + If non-zero, introduces a :class:`SharedDropout` layer on the outputs of each LSTM layer except the last layer. + Default: 0. + """ + + def __init__( + self, + input_size: int, + hidden_size: int, + num_layers: int = 1, + bidirectional: bool = False, + dropout: float = .0 + ) -> VariationalLSTM: + super().__init__() + + self.input_size = input_size + self.hidden_size = hidden_size + self.num_layers = num_layers + self.bidirectional = bidirectional + self.dropout = dropout + self.num_directions = 1 + self.bidirectional + + self.f_cells = nn.ModuleList() + if bidirectional: + self.b_cells = nn.ModuleList() + for _ in range(self.num_layers): + self.f_cells.append(nn.LSTMCell(input_size=input_size, hidden_size=hidden_size)) + if bidirectional: + self.b_cells.append(nn.LSTMCell(input_size=input_size, hidden_size=hidden_size)) + input_size = hidden_size * self.num_directions + + self.reset_parameters() + + def __repr__(self): + s = f"{self.input_size}, {self.hidden_size}" + if self.num_layers > 1: + s += f", num_layers={self.num_layers}" + if self.bidirectional: + s += f", bidirectional={self.bidirectional}" + if self.dropout > 0: + s += f", dropout={self.dropout}" + return f"{self.__class__.__name__}({s})" + + def reset_parameters(self): + for param in self.parameters(): + # apply orthogonal_ to weight + if len(param.shape) > 1: + nn.init.orthogonal_(param) + # apply zeros_ to bias + else: + nn.init.zeros_(param) + + def permute_hidden( + self, + hx: Tuple[torch.Tensor, torch.Tensor], + permutation: torch.LongTensor + ) -> Tuple[torch.Tensor, torch.Tensor]: + if permutation is None: + return hx + h = apply_permutation(hx[0], permutation) + c = apply_permutation(hx[1], permutation) + + return h, c + + def layer_forward( + self, + x: List[torch.Tensor], + hx: Tuple[torch.Tensor, torch.Tensor], + cell: nn.LSTMCell, + batch_sizes: List[int], + reverse: bool = False + ) -> Tuple[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]: + hx_0 = hx_i = hx + hx_n, output = [], [] + steps = reversed(range(len(x))) if reverse else range(len(x)) + if self.training: + hid_mask = SharedDropout.get_mask(hx_0[0], self.dropout) + + for t in steps: + last_batch_size, batch_size = len(hx_i[0]), batch_sizes[t] + if last_batch_size < batch_size: + hx_i = [torch.cat((h, ih[last_batch_size:batch_size])) for h, ih in zip(hx_i, hx_0)] + else: + hx_n.append([h[batch_size:] for h in hx_i]) + hx_i = [h[:batch_size] for h in hx_i] + hx_i = [h for h in cell(x[t], hx_i)] + output.append(hx_i[0]) + if self.training: + hx_i[0] = hx_i[0] * hid_mask[:batch_size] + if reverse: + hx_n = hx_i + output.reverse() + else: + hx_n.append(hx_i) + hx_n = [torch.cat(h) for h in zip(*reversed(hx_n))] + output = torch.cat(output) + + return output, hx_n + + def forward( + self, + sequence: PackedSequence, + hx: Optional[Tuple[torch.Tensor, torch.Tensor]] = None + ) -> Tuple[PackedSequence, Tuple[torch.Tensor, torch.Tensor]]: + r""" + Args: + sequence (~torch.nn.utils.rnn.PackedSequence): + A packed variable length sequence. + hx (~torch.Tensor, ~torch.Tensor): + A tuple composed of two tensors `h` and `c`. + `h` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the initial hidden state + for each element in the batch. + `c` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the initial cell state + for each element in the batch. + If `hx` is not provided, both `h` and `c` default to zero. + Default: ``None``. + + Returns: + ~torch.nn.utils.rnn.PackedSequence, (~torch.Tensor, ~torch.Tensor): + The first is a packed variable length sequence. + The second is a tuple of tensors `h` and `c`. + `h` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the hidden state for `t=seq_len`. + Like output, the layers can be separated using ``h.view(num_layers, num_directions, batch_size, hidden_size)`` + and similarly for c. + `c` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the cell state for `t=seq_len`. + """ + x, batch_sizes = sequence.data, sequence.batch_sizes.tolist() + batch_size = batch_sizes[0] + h_n, c_n = [], [] + + if hx is None: + ih = x.new_zeros(self.num_layers * self.num_directions, batch_size, self.hidden_size) + h, c = ih, ih + else: + h, c = self.permute_hidden(hx, sequence.sorted_indices) + h = h.view(self.num_layers, self.num_directions, batch_size, self.hidden_size) + c = c.view(self.num_layers, self.num_directions, batch_size, self.hidden_size) + + for i in range(self.num_layers): + x = torch.split(x, batch_sizes) + if self.training: + mask = SharedDropout.get_mask(x[0], self.dropout) + x = [i * mask[:len(i)] for i in x] + x_i, (h_i, c_i) = self.layer_forward(x, (h[i, 0], c[i, 0]), self.f_cells[i], batch_sizes) + if self.bidirectional: + x_b, (h_b, c_b) = self.layer_forward(x, (h[i, 1], c[i, 1]), self.b_cells[i], batch_sizes, True) + x_i = torch.cat((x_i, x_b), -1) + h_i = torch.stack((h_i, h_b)) + c_i = torch.stack((c_i, c_b)) + x = x_i + h_n.append(h_i) + c_n.append(c_i) + + x = PackedSequence(x, sequence.batch_sizes, sequence.sorted_indices, sequence.unsorted_indices) + hx = torch.cat(h_n, 0), torch.cat(c_n, 0) + hx = self.permute_hidden(hx, sequence.unsorted_indices) + + return x, hx diff --git a/tania_scripts/supar/modules/mlp.py b/tania_scripts/supar/modules/mlp.py new file mode 100644 index 0000000..f26cdd9 --- /dev/null +++ b/tania_scripts/supar/modules/mlp.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import torch +import torch.nn as nn +from supar.modules.dropout import SharedDropout + + +class MLP(nn.Module): + r""" + Applies a linear transformation together with a non-linear activation to the incoming tensor: + :math:`y = \mathrm{Activation}(x A^T + b)` + + Args: + n_in (~torch.Tensor): + The size of each input feature. + n_out (~torch.Tensor): + The size of each output feature. + dropout (float): + If non-zero, introduces a :class:`SharedDropout` layer on the output with this dropout ratio. Default: 0. + activation (bool): + Whether to use activations. Default: True. + """ + + def __init__(self, n_in: int, n_out: int, dropout: float = .0, activation: bool = True) -> MLP: + super().__init__() + + self.n_in = n_in + self.n_out = n_out + self.linear = nn.Linear(n_in, n_out) + self.activation = nn.LeakyReLU(negative_slope=0.1) if activation else nn.Identity() + self.dropout = SharedDropout(p=dropout) + + self.reset_parameters() + + def __repr__(self): + s = f"n_in={self.n_in}, n_out={self.n_out}" + if self.dropout.p > 0: + s += f", dropout={self.dropout.p}" + + return f"{self.__class__.__name__}({s})" + + def reset_parameters(self): + nn.init.orthogonal_(self.linear.weight) + nn.init.zeros_(self.linear.bias) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (~torch.Tensor): + The size of each input feature is `n_in`. + + Returns: + A tensor with the size of each output feature `n_out`. + """ + + x = self.linear(x) + x = self.activation(x) + x = self.dropout(x) + + return x diff --git a/tania_scripts/supar/modules/pretrained.py b/tania_scripts/supar/modules/pretrained.py new file mode 100644 index 0000000..4805c88 --- /dev/null +++ b/tania_scripts/supar/modules/pretrained.py @@ -0,0 +1,256 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import List, Tuple + +import torch +import torch.nn as nn +from supar.utils.fn import pad +from supar.utils.tokenizer import TransformerTokenizer + + +class TransformerEmbedding(nn.Module): + r""" + Bidirectional transformer embeddings of words from various transformer architectures :cite:`devlin-etal-2019-bert`. + + Args: + name (str): + Path or name of the pretrained models registered in `transformers`_, e.g., ``'bert-base-cased'``. + n_layers (int): + The number of BERT layers to use. If 0, uses all layers. + n_out (int): + The requested size of the embeddings. If 0, uses the size of the pretrained embedding model. Default: 0. + stride (int): + A sequence longer than max length will be splitted into several small pieces + with a window size of ``stride``. Default: 10. + pooling (str): + Pooling way to get from token piece embeddings to token embedding. + ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all. + Default: ``mean``. + pad_index (int): + The index of the padding token in BERT vocabulary. Default: 0. + mix_dropout (float): + The dropout ratio of BERT layers. This value will be passed into the :class:`ScalarMix` layer. Default: 0. + finetune (bool): + If ``True``, the model parameters will be updated together with the downstream task. Default: ``False``. + + .. _transformers: + https://github.com/huggingface/transformers + """ + + def __init__( + self, + name: str, + n_layers: int, + n_out: int = 0, + stride: int = 256, + pooling: str = 'mean', + pad_index: int = 0, + mix_dropout: float = .0, + finetune: bool = False + ) -> TransformerEmbedding: + super().__init__() + + from transformers import AutoModel + try: + self.model = AutoModel.from_pretrained(name, output_hidden_states=True, local_files_only=True) + except Exception: + self.model = AutoModel.from_pretrained(name, output_hidden_states=True, local_files_only=False) + self.model = self.model.requires_grad_(finetune) + self.tokenizer = TransformerTokenizer(name) + + self.name = name + self.n_layers = n_layers or self.model.config.num_hidden_layers + self.hidden_size = self.model.config.hidden_size + self.n_out = n_out or self.hidden_size + self.pooling = pooling + self.pad_index = pad_index + self.mix_dropout = mix_dropout + self.finetune = finetune + try: + self.max_len = int(max(0, self.model.config.max_position_embeddings) or 1e12) - 2 + except: + self.max_len = 512 + self.stride = min(stride, self.max_len) + + self.scalar_mix = ScalarMix(self.n_layers, mix_dropout) + self.projection = nn.Linear(self.hidden_size, self.n_out, False) if self.hidden_size != n_out else nn.Identity() + + def __repr__(self): + s = f"{self.name}, n_layers={self.n_layers}, n_out={self.n_out}, " + s += f"stride={self.stride}, pooling={self.pooling}, pad_index={self.pad_index}" + if self.mix_dropout > 0: + s += f", mix_dropout={self.mix_dropout}" + if self.finetune: + s += f", finetune={self.finetune}" + return f"{self.__class__.__name__}({s})" + + def forward(self, tokens: torch.Tensor) -> torch.Tensor: + r""" + Args: + tokens (~torch.Tensor): ``[batch_size, seq_len, fix_len]``. + + Returns: + ~torch.Tensor: + Contextualized token embeddings of shape ``[batch_size, seq_len, n_out]``. + """ + + mask = tokens.ne(self.pad_index) + lens = mask.sum((1, 2)) + # [batch_size, n_subwords] + tokens = pad(tokens[mask].split(lens.tolist()), self.pad_index, padding_side=self.tokenizer.padding_side) + token_mask = pad(mask[mask].split(lens.tolist()), 0, padding_side=self.tokenizer.padding_side) + + # return the hidden states of all layers + x = self.model(tokens[:, :self.max_len], attention_mask=token_mask[:, :self.max_len].float())[-1] + # [batch_size, max_len, hidden_size] + x = self.scalar_mix(x[-self.n_layers:]) + # [batch_size, n_subwords, hidden_size] + for i in range(self.stride, (tokens.shape[1]-self.max_len+self.stride-1)//self.stride*self.stride+1, self.stride): + part = self.model(tokens[:, i:i+self.max_len], attention_mask=token_mask[:, i:i+self.max_len].float())[-1] + x = torch.cat((x, self.scalar_mix(part[-self.n_layers:])[:, self.max_len-self.stride:]), 1) + # [batch_size, seq_len] + lens = mask.sum(-1) + lens = lens.masked_fill_(lens.eq(0), 1) + # [batch_size, seq_len, fix_len, hidden_size] + x = x.new_zeros(*mask.shape, self.hidden_size).masked_scatter_(mask.unsqueeze(-1), x[token_mask]) + # [batch_size, seq_len, hidden_size] + if self.pooling == 'first': + x = x[:, :, 0] + elif self.pooling == 'last': + x = x.gather(2, (lens-1).unsqueeze(-1).repeat(1, 1, self.hidden_size).unsqueeze(2)).squeeze(2) + elif self.pooling == 'mean': + x = x.sum(2) / lens.unsqueeze(-1) + else: + raise RuntimeError(f'Unsupported pooling method "{self.pooling}"!') + return self.projection(x) + + +class ELMoEmbedding(nn.Module): + r""" + Contextual word embeddings using word-level bidirectional LM :cite:`peters-etal-2018-deep`. + + Args: + name (str): + The name of the pretrained ELMo registered in `OPTION` and `WEIGHT`. Default: ``'original_5b'``. + bos_eos (Tuple[bool]): + A tuple of two boolean values indicating whether to keep start/end boundaries of sentence outputs. + Default: ``(True, True)``. + n_out (int): + The requested size of the embeddings. If 0, uses the default size of ELMo outputs. Default: 0. + dropout (float): + The dropout ratio for the ELMo layer. Default: 0. + finetune (bool): + If ``True``, the model parameters will be updated together with the downstream task. Default: ``False``. + """ + + OPTION = { + 'small': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x1024_128_2048cnn_1xhighway/elmo_2x1024_128_2048cnn_1xhighway_options.json', # noqa + 'medium': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x2048_256_2048cnn_1xhighway/elmo_2x2048_256_2048cnn_1xhighway_options.json', # noqa + 'original': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_options.json', # noqa + 'original_5b': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway_5.5B/elmo_2x4096_512_2048cnn_2xhighway_5.5B_options.json', # noqa + } + WEIGHT = { + 'small': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x1024_128_2048cnn_1xhighway/elmo_2x1024_128_2048cnn_1xhighway_weights.hdf5', # noqa + 'medium': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x2048_256_2048cnn_1xhighway/elmo_2x2048_256_2048cnn_1xhighway_weights.hdf5', # noqa + 'original': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_weights.hdf5', # noqa + 'original_5b': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway_5.5B/elmo_2x4096_512_2048cnn_2xhighway_5.5B_weights.hdf5', # noqa + } + + def __init__( + self, + name: str = 'original_5b', + bos_eos: Tuple[bool, bool] = (True, True), + n_out: int = 0, + dropout: float = 0.5, + finetune: bool = False + ) -> ELMoEmbedding: + super().__init__() + + from allennlp.modules import Elmo + + self.elmo = Elmo(options_file=self.OPTION[name], + weight_file=self.WEIGHT[name], + num_output_representations=1, + dropout=dropout, + finetune=finetune, + keep_sentence_boundaries=True) + + self.name = name + self.bos_eos = bos_eos + self.hidden_size = self.elmo.get_output_dim() + self.n_out = n_out or self.hidden_size + self.dropout = dropout + self.finetune = finetune + + self.projection = nn.Linear(self.hidden_size, self.n_out, False) if self.hidden_size != n_out else nn.Identity() + + def __repr__(self): + s = f"{self.name}, n_out={self.n_out}" + if self.dropout > 0: + s += f", dropout={self.dropout}" + if self.finetune: + s += f", finetune={self.finetune}" + return f"{self.__class__.__name__}({s})" + + def forward(self, chars: torch.LongTensor) -> torch.Tensor: + r""" + Args: + chars (~torch.LongTensor): ``[batch_size, seq_len, fix_len]``. + + Returns: + ~torch.Tensor: + ELMo embeddings of shape ``[batch_size, seq_len, n_out]``. + """ + + x = self.projection(self.elmo(chars)['elmo_representations'][0]) + if not self.bos_eos[0]: + x = x[:, 1:] + if not self.bos_eos[1]: + x = x[:, :-1] + return x + + +class ScalarMix(nn.Module): + r""" + Computes a parameterized scalar mixture of :math:`N` tensors, :math:`mixture = \gamma * \sum_{k}(s_k * tensor_k)` + where :math:`s = \mathrm{softmax}(w)`, with :math:`w` and :math:`\gamma` scalar parameters. + + Args: + n_layers (int): + The number of layers to be mixed, i.e., :math:`N`. + dropout (float): + The dropout ratio of the layer weights. + If dropout > 0, then for each scalar weight, adjusts its softmax weight mass to 0 + with the dropout probability (i.e., setting the unnormalized weight to -inf). + This effectively redistributes the dropped probability mass to all other weights. + Default: 0. + """ + + def __init__(self, n_layers: int, dropout: float = .0) -> ScalarMix: + super().__init__() + + self.n_layers = n_layers + + self.weights = nn.Parameter(torch.zeros(n_layers)) + self.gamma = nn.Parameter(torch.tensor([1.0])) + self.dropout = nn.Dropout(dropout) + + def __repr__(self): + s = f"n_layers={self.n_layers}" + if self.dropout.p > 0: + s += f", dropout={self.dropout.p}" + return f"{self.__class__.__name__}({s})" + + def forward(self, tensors: List[torch.Tensor]) -> torch.Tensor: + r""" + Args: + tensors (List[~torch.Tensor]): + :math:`N` tensors to be mixed. + + Returns: + The mixture of :math:`N` tensors. + """ + + return self.gamma * sum(w * h for w, h in zip(self.dropout(self.weights.softmax(-1)), tensors)) diff --git a/tania_scripts/supar/modules/transformer.py b/tania_scripts/supar/modules/transformer.py new file mode 100644 index 0000000..8e7c967 --- /dev/null +++ b/tania_scripts/supar/modules/transformer.py @@ -0,0 +1,585 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import copy +from typing import Optional + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class TransformerWordEmbedding(nn.Module): + + def __init__( + self, + n_vocab: int = None, + n_embed: int = None, + embed_scale: Optional[int] = None, + max_len: Optional[int] = 512, + pos: Optional[str] = None, + pad_index: Optional[int] = None, + ) -> TransformerWordEmbedding: + super(TransformerWordEmbedding, self).__init__() + + self.embed = nn.Embedding(num_embeddings=n_vocab, + embedding_dim=n_embed) + if pos is None: + self.pos_embed = nn.Identity() + elif pos == 'sinusoid': + self.pos_embed = SinusoidPositionalEmbedding() + elif pos == 'sinusoid_relative': + self.pos_embed = SinusoidRelativePositionalEmbedding() + elif pos == 'learnable': + self.pos_embed = PositionalEmbedding(max_len=max_len) + elif pos == 'learnable_relative': + self.pos_embed = RelativePositionalEmbedding(max_len=max_len) + else: + raise ValueError(f'Unknown positional embedding type {pos}') + + self.n_vocab = n_vocab + self.n_embed = n_embed + self.embed_scale = embed_scale or n_embed ** 0.5 + self.max_len = max_len + self.pos = pos + self.pad_index = pad_index + + self.reset_parameters() + + def __repr__(self): + s = self.__class__.__name__ + '(' + s += f"{self.n_vocab}, {self.n_embed}" + if self.embed_scale is not None: + s += f", embed_scale={self.embed_scale:.2f}" + if self.max_len is not None: + s += f", max_len={self.max_len}" + if self.pos is not None: + s += f", pos={self.pos}" + if self.pad_index is not None: + s += f", pad_index={self.pad_index}" + s += ')' + return s + + def reset_parameters(self): + nn.init.normal_(self.embed.weight, 0, self.n_embed ** -0.5) + if self.pad_index is not None: + nn.init.zeros_(self.embed.weight[self.pad_index]) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.embed(x) + if self.embed_scale: + x = x * self.embed_scale + if self.pos is not None: + x = x + self.pos_embed(x) + return x + + +class TransformerEncoder(nn.Module): + + def __init__( + self, + layer: nn.Module, + n_layers: int = 6, + n_model: int = 1024, + pre_norm: bool = False, + ) -> TransformerEncoder: + super(TransformerEncoder, self).__init__() + + self.n_layers = n_layers + self.n_model = n_model + self.pre_norm = pre_norm + + self.layers = nn.ModuleList([copy.deepcopy(layer) for _ in range(n_layers)]) + self.norm = nn.LayerNorm(n_model) if self.pre_norm else None + + def forward(self, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + x = x.transpose(0, 1) + for layer in self.layers: + x = layer(x, mask) + if self.pre_norm: + x = self.norm(x) + return x.transpose(0, 1) + + +class TransformerDecoder(nn.Module): + + def __init__( + self, + layer: nn.Module, + n_layers: int = 6, + n_model: int = 1024, + pre_norm: bool = False, + ) -> TransformerDecoder: + super(TransformerDecoder, self).__init__() + + self.n_layers = n_layers + self.n_model = n_model + self.pre_norm = pre_norm + + self.layers = nn.ModuleList([copy.deepcopy(layer) for _ in range(n_layers)]) + self.norm = nn.LayerNorm(n_model) if self.pre_norm else None + + def forward( + self, + x_tgt: torch.Tensor, + x_src: torch.Tensor, + tgt_mask: torch.BoolTensor, + src_mask: torch.BoolTensor, + attn_mask: Optional[torch.BoolTensor] = None + ) -> torch.Tensor: + x_tgt, x_src = x_tgt.transpose(0, 1), x_src.transpose(0, 1) + for layer in self.layers: + x_tgt = layer(x_tgt=x_tgt, + x_src=x_src, + tgt_mask=tgt_mask, + src_mask=src_mask, + attn_mask=attn_mask) + if self.pre_norm: + x_tgt = self.norm(x_tgt) + return x_tgt.transpose(0, 1) + + +class TransformerEncoderLayer(nn.Module): + + def __init__( + self, + n_heads: int = 8, + n_model: int = 1024, + n_inner: int = 2048, + activation: str = 'relu', + bias: bool = True, + pre_norm: bool = False, + attn_dropout: float = 0.1, + ffn_dropout: float = 0.1, + dropout: float = 0.1 + ) -> TransformerEncoderLayer: + super(TransformerEncoderLayer, self).__init__() + + self.attn = MultiHeadAttention(n_heads=n_heads, + n_model=n_model, + n_embed=n_model//n_heads, + dropout=attn_dropout, + bias=bias) + self.attn_norm = nn.LayerNorm(n_model) + self.ffn = PositionwiseFeedForward(n_model=n_model, + n_inner=n_inner, + activation=activation, + dropout=ffn_dropout) + self.ffn_norm = nn.LayerNorm(n_model) + self.dropout = nn.Dropout(dropout) + + self.pre_norm = pre_norm + + def forward(self, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + if self.pre_norm: + n = self.attn_norm(x) + x = x + self.dropout(self.attn(n, n, n, mask)) + n = self.ffn_norm(x) + x = x + self.dropout(self.ffn(n)) + else: + x = self.attn_norm(x + self.dropout(self.attn(x, x, x, mask))) + x = self.ffn_norm(x + self.dropout(self.ffn(x))) + return x + + +class RelativePositionTransformerEncoderLayer(nn.Module): + + def __init__( + self, + n_heads: int = 8, + n_model: int = 1024, + n_inner: int = 2048, + activation: str = 'relu', + pre_norm: bool = False, + attn_dropout: float = 0.1, + ffn_dropout: float = 0.1, + dropout: float = 0.1 + ) -> RelativePositionTransformerEncoderLayer: + super(RelativePositionTransformerEncoderLayer, self).__init__() + + self.attn = RelativePositionMultiHeadAttention(n_heads=n_heads, + n_model=n_model, + n_embed=n_model//n_heads, + dropout=attn_dropout) + self.attn_norm = nn.LayerNorm(n_model) + self.ffn = PositionwiseFeedForward(n_model=n_model, + n_inner=n_inner, + activation=activation, + dropout=ffn_dropout) + self.ffn_norm = nn.LayerNorm(n_model) + self.dropout = nn.Dropout(dropout) + + self.pre_norm = pre_norm + + def forward(self, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + if self.pre_norm: + n = self.attn_norm(x) + x = x + self.dropout(self.attn(n, n, n, mask)) + n = self.ffn_norm(x) + x = x + self.dropout(self.ffn(n)) + else: + x = self.attn_norm(x + self.dropout(self.attn(x, x, x, mask))) + x = self.ffn_norm(x + self.dropout(self.ffn(x))) + return x + + +class TransformerDecoderLayer(nn.Module): + + def __init__( + self, + n_heads: int = 8, + n_model: int = 1024, + n_inner: int = 2048, + activation: str = 'relu', + bias: bool = True, + pre_norm: bool = False, + attn_dropout: float = 0.1, + ffn_dropout: float = 0.1, + dropout: float = 0.1 + ) -> TransformerDecoderLayer: + super(TransformerDecoderLayer, self).__init__() + + self.self_attn = MultiHeadAttention(n_heads=n_heads, + n_model=n_model, + n_embed=n_model//n_heads, + dropout=attn_dropout, + bias=bias) + self.self_attn_norm = nn.LayerNorm(n_model) + self.mha_attn = MultiHeadAttention(n_heads=n_heads, + n_model=n_model, + n_embed=n_model//n_heads, + dropout=attn_dropout, + bias=bias) + self.mha_attn_norm = nn.LayerNorm(n_model) + self.ffn = PositionwiseFeedForward(n_model=n_model, + n_inner=n_inner, + activation=activation, + dropout=ffn_dropout) + self.ffn_norm = nn.LayerNorm(n_model) + self.dropout = nn.Dropout(dropout) + + self.pre_norm = pre_norm + + def forward( + self, + x_tgt: torch.Tensor, + x_src: torch.Tensor, + tgt_mask: torch.BoolTensor, + src_mask: torch.BoolTensor, + attn_mask: Optional[torch.BoolTensor] = None + ) -> torch.Tensor: + if self.pre_norm: + n_tgt = self.self_attn_norm(x_tgt) + x_tgt = x_tgt + self.dropout(self.self_attn(n_tgt, n_tgt, n_tgt, tgt_mask, attn_mask)) + n_tgt = self.mha_attn_norm(x_tgt) + x_tgt = x_tgt + self.dropout(self.mha_attn(n_tgt, x_src, x_src, src_mask)) + n_tgt = self.ffn_norm(x_tgt) + x_tgt = x_tgt + self.dropout(self.ffn(x_tgt)) + else: + x_tgt = self.self_attn_norm(x_tgt + self.dropout(self.self_attn(x_tgt, x_tgt, x_tgt, tgt_mask, attn_mask))) + x_tgt = self.mha_attn_norm(x_tgt + self.dropout(self.mha_attn(x_tgt, x_src, x_src, src_mask))) + x_tgt = self.ffn_norm(x_tgt + self.dropout(self.ffn(x_tgt))) + return x_tgt + + +class RelativePositionTransformerDecoderLayer(nn.Module): + + def __init__( + self, + n_heads: int = 8, + n_model: int = 1024, + n_inner: int = 2048, + activation: str = 'relu', + pre_norm: bool = False, + attn_dropout: float = 0.1, + ffn_dropout: float = 0.1, + dropout: float = 0.1 + ) -> RelativePositionTransformerDecoderLayer: + super(RelativePositionTransformerDecoderLayer, self).__init__() + + self.self_attn = RelativePositionMultiHeadAttention(n_heads=n_heads, + n_model=n_model, + n_embed=n_model//n_heads, + dropout=attn_dropout) + self.self_attn_norm = nn.LayerNorm(n_model) + self.mha_attn = RelativePositionMultiHeadAttention(n_heads=n_heads, + n_model=n_model, + n_embed=n_model//n_heads, + dropout=attn_dropout) + self.mha_attn_norm = nn.LayerNorm(n_model) + self.ffn = PositionwiseFeedForward(n_model=n_model, + n_inner=n_inner, + activation=activation, + dropout=ffn_dropout) + self.ffn_norm = nn.LayerNorm(n_model) + self.dropout = nn.Dropout(dropout) + + self.pre_norm = pre_norm + + def forward( + self, + x_tgt: torch.Tensor, + x_src: torch.Tensor, + tgt_mask: torch.BoolTensor, + src_mask: torch.BoolTensor, + attn_mask: Optional[torch.BoolTensor] = None + ) -> torch.Tensor: + if self.pre_norm: + n_tgt = self.self_attn_norm(x_tgt) + x_tgt = x_tgt + self.dropout(self.self_attn(n_tgt, n_tgt, n_tgt, tgt_mask, attn_mask)) + n_tgt = self.mha_attn_norm(x_tgt) + x_tgt = x_tgt + self.dropout(self.mha_attn(n_tgt, x_src, x_src, src_mask)) + n_tgt = self.ffn_norm(x_tgt) + x_tgt = x_tgt + self.dropout(self.ffn(x_tgt)) + else: + x_tgt = self.self_attn_norm(x_tgt + self.dropout(self.self_attn(x_tgt, x_tgt, x_tgt, tgt_mask, attn_mask))) + x_tgt = self.mha_attn_norm(x_tgt + self.dropout(self.mha_attn(x_tgt, x_src, x_src, src_mask))) + x_tgt = self.ffn_norm(x_tgt + self.dropout(self.ffn(x_tgt))) + return x_tgt + + +class MultiHeadAttention(nn.Module): + + def __init__( + self, + n_heads: int = 8, + n_model: int = 1024, + n_embed: int = 128, + dropout: float = 0.1, + bias: bool = True, + attn: bool = False, + ) -> MultiHeadAttention: + super(MultiHeadAttention, self).__init__() + + self.n_heads = n_heads + self.n_model = n_model + self.n_embed = n_embed + self.scale = n_embed**0.5 + + self.wq = nn.Linear(n_model, n_heads * n_embed, bias=bias) + self.wk = nn.Linear(n_model, n_heads * n_embed, bias=bias) + self.wv = nn.Linear(n_model, n_heads * n_embed, bias=bias) + self.wo = nn.Linear(n_heads * n_embed, n_model, bias=bias) + self.dropout = nn.Dropout(dropout) + + self.bias = bias + self.attn = attn + + self.reset_parameters() + + def reset_parameters(self): + # borrowed from https://github.com/facebookresearch/fairseq/blob/main/fairseq/modules/multihead_attention.py + nn.init.xavier_uniform_(self.wq.weight, 2 ** -0.5) + nn.init.xavier_uniform_(self.wk.weight, 2 ** -0.5) + nn.init.xavier_uniform_(self.wv.weight, 2 ** -0.5) + nn.init.xavier_uniform_(self.wo.weight) + + def forward( + self, + q: torch.Tensor, + k: torch.Tensor, + v: torch.Tensor, + mask: torch.BoolTensor, + attn_mask: Optional[torch.BoolTensor] = None + ) -> torch.Tensor: + batch_size, _ = mask.shape + # [seq_len, batch_size * n_heads, n_embed] + q = self.wq(q).view(-1, batch_size * self.n_heads, self.n_embed) + # [src_len, batch_size * n_heads, n_embed] + k = self.wk(k).view(-1, batch_size * self.n_heads, self.n_embed) + v = self.wv(v).view(-1, batch_size * self.n_heads, self.n_embed) + + mask = mask.unsqueeze(1).repeat(1, self.n_heads, 1).view(-1, 1, *mask.shape[1:]) + # [batch_size * n_heads, seq_len, src_len] + if attn_mask is not None: + mask = mask & attn_mask + # [batch_size * n_heads, seq_len, src_len] + attn = torch.bmm(q.transpose(0, 1) / self.scale, k.movedim((0, 1), (2, 0))) + attn = torch.softmax(attn + torch.where(mask, 0., float('-inf')), -1) + attn = self.dropout(attn) + # [seq_len, batch_size * n_heads, n_embed] + x = torch.bmm(attn, v.transpose(0, 1)).transpose(0, 1) + # [seq_len, batch_size, n_model] + x = self.wo(x.reshape(-1, batch_size, self.n_heads * self.n_embed)) + + return (x, attn.view(batch_size, self.n_heads, *attn.shape[1:])) if self.attn else x + + +class RelativePositionMultiHeadAttention(nn.Module): + + def __init__( + self, + n_heads: int = 8, + n_model: int = 1024, + n_embed: int = 128, + dropout: float = 0.1, + attn: bool = False + ) -> RelativePositionMultiHeadAttention: + super(RelativePositionMultiHeadAttention, self).__init__() + + self.n_heads = n_heads + self.n_model = n_model + self.n_embed = n_embed + self.scale = n_embed**0.5 + + self.pos_embed = RelativePositionalEmbedding(n_model=n_embed) + self.wq = nn.Parameter(torch.zeros(n_model, n_heads * n_embed)) + self.wk = nn.Parameter(torch.zeros(n_model, n_heads * n_embed)) + self.wv = nn.Parameter(torch.zeros(n_model, n_heads * n_embed)) + self.wo = nn.Parameter(torch.zeros(n_heads * n_embed, n_model)) + self.bu = nn.Parameter(torch.zeros(n_heads, n_embed)) + self.bv = nn.Parameter(torch.zeros(n_heads, n_embed)) + self.dropout = nn.Dropout(dropout) + + self.attn = attn + + self.reset_parameters() + + def reset_parameters(self): + # borrowed from https://github.com/facebookresearch/fairseq/blob/main/fairseq/modules/multihead_attention.py + nn.init.xavier_uniform_(self.wq, 2 ** -0.5) + nn.init.xavier_uniform_(self.wk, 2 ** -0.5) + nn.init.xavier_uniform_(self.wv, 2 ** -0.5) + nn.init.xavier_uniform_(self.wo) + + def forward( + self, + q: torch.Tensor, + k: torch.Tensor, + v: torch.Tensor, + mask: torch.BoolTensor, + attn_mask: Optional[torch.BoolTensor] = None + ) -> torch.Tensor: + batch_size, _ = mask.shape + # [seq_len, batch_size, n_heads, n_embed] + q = F.linear(q, self.wq).view(-1, batch_size, self.n_heads, self.n_embed) + # [src_len, batch_size * n_heads, n_embed] + k = F.linear(k, self.wk).view(-1, batch_size * self.n_heads, self.n_embed) + v = F.linear(v, self.wv).view(-1, batch_size * self.n_heads, self.n_embed) + # [seq_len, src_len, n_embed] + p = self.pos_embed(q[:, 0, 0], k[:, 0]) + # [seq_len, batch_size * n_heads, n_embed] + qu, qv = (q + self.bu).view(-1, *k.shape[1:]), (q + self.bv).view(-1, *k.shape[1:]) + + mask = mask.unsqueeze(1).repeat(1, self.n_heads, 1).view(-1, 1, *mask.shape[1:]) + if attn_mask is not None: + mask = mask & attn_mask + # [batch_size * n_heads, seq_len, src_len] + attn = torch.bmm(qu.transpose(0, 1), k.movedim((0, 1), (2, 0))) + attn = attn + torch.matmul(qv.transpose(0, 1).unsqueeze(2), p.transpose(1, 2)).squeeze(2) + attn = torch.softmax(attn / self.scale + torch.where(mask, 0., float('-inf')), -1) + attn = self.dropout(attn) + # [seq_len, batch_size * n_heads, n_embed] + x = torch.bmm(attn, v.transpose(0, 1)).transpose(0, 1) + # [seq_len, batch_size, n_model] + x = F.linear(x.reshape(-1, batch_size, self.n_heads * self.n_embed), self.wo) + + return (x, attn.view(batch_size, self.n_heads, *attn.shape[1:])) if self.attn else x + + +class PositionwiseFeedForward(nn.Module): + + def __init__( + self, + n_model: int = 1024, + n_inner: int = 2048, + activation: str = 'relu', + dropout: float = 0.1 + ) -> PositionwiseFeedForward: + super(PositionwiseFeedForward, self).__init__() + + self.w1 = nn.Linear(n_model, n_inner) + self.activation = nn.ReLU() if activation == 'relu' else nn.GELU() + self.dropout = nn.Dropout(dropout) + self.w2 = nn.Linear(n_inner, n_model) + + self.reset_parameters() + + def reset_parameters(self): + nn.init.xavier_uniform_(self.w1.weight) + nn.init.xavier_uniform_(self.w2.weight) + nn.init.zeros_(self.w1.bias) + nn.init.zeros_(self.w2.bias) + + def forward(self, x): + x = self.w1(x) + x = self.activation(x) + x = self.dropout(x) + x = self.w2(x) + + return x + + +class PositionalEmbedding(nn.Module): + + def __init__( + self, + n_model: int = 1024, + max_len: int = 1024 + ) -> PositionalEmbedding: + super().__init__() + + self.embed = nn.Embedding(max_len, n_model) + + self.reset_parameters() + + @torch.no_grad() + def reset_parameters(self): + w = self.embed.weight + max_len, n_model = w.shape + w = w.new_tensor(range(max_len)).unsqueeze(-1) + w = w / 10000 ** (w.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model) + w[:, 0::2], w[:, 1::2] = w[:, 0::2].sin(), w[:, 1::2].cos() + self.embed.weight.copy_(w) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.embed(x.new_tensor(range(x.shape[1])).long()) + + +class RelativePositionalEmbedding(nn.Module): + + def __init__( + self, + n_model: int = 1024, + max_len: int = 1024 + ) -> RelativePositionalEmbedding: + super().__init__() + + self.embed = nn.Embedding(max_len, n_model) + + self.reset_parameters() + + @torch.no_grad() + def reset_parameters(self): + w = self.embed.weight + max_len, n_model = w.shape + pos = torch.cat((w.new_tensor(range(-max_len//2, 0)), w.new_tensor(range(max_len//2)))) + w = pos.unsqueeze(-1) / 10000 ** (w.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model) + w[:, 0::2], w[:, 1::2] = w[:, 0::2].sin(), w[:, 1::2].cos() + self.embed.weight.copy_(w) + + def forward(self, q: torch.Tensor, k: torch.Tensor) -> torch.Tensor: + offset = sum(divmod(self.embed.weight.shape[0], 2)) + return self.embed((k.new_tensor(range(k.shape[0])) - q.new_tensor(range(q.shape[0])).unsqueeze(-1)).long() + offset) + + +class SinusoidPositionalEmbedding(nn.Module): + + def forward(self, x: torch.Tensor) -> torch.Tensor: + seq_len, n_model = x[0].shape + pos = x.new_tensor(range(seq_len)).unsqueeze(-1) + pos = pos / 10000 ** (x.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model) + pos[:, 0::2], pos[:, 1::2] = pos[:, 0::2].sin(), pos[:, 1::2].cos() + return pos + + +class SinusoidRelativePositionalEmbedding(nn.Module): + + def forward(self, x: torch.Tensor) -> torch.Tensor: + seq_len, n_model = x[0].shape + pos = x.new_tensor(range(seq_len)) + pos = (pos - pos.unsqueeze(-1)).unsqueeze(-1) + pos = pos / 10000 ** (x.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model) + pos[..., 0::2], pos[..., 1::2] = pos[..., 0::2].sin(), pos[..., 1::2].cos() + return pos diff --git a/tania_scripts/supar/parser.py b/tania_scripts/supar/parser.py new file mode 100644 index 0000000..f1c372e --- /dev/null +++ b/tania_scripts/supar/parser.py @@ -0,0 +1,620 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import contextlib +import os +import shutil +import sys +import tempfile +import pickle +from contextlib import contextmanager +from datetime import datetime, timedelta +from typing import Any, Iterable, Union + +import dill +import torch +import torch.distributed as dist +import torch.nn as nn +from torch.cuda.amp import GradScaler +from torch.optim import Adam, Optimizer +from torch.optim.lr_scheduler import ExponentialLR, _LRScheduler + +import supar +from supar.utils import Config, Dataset +from supar.utils.field import Field +from supar.utils.fn import download, get_rng_state, set_rng_state +from supar.utils.logging import get_logger, init_logger, progress_bar +from supar.utils.metric import Metric +from supar.utils.optim import InverseSquareRootLR, LinearLR +from supar.utils.parallel import DistributedDataParallel as DDP +from supar.utils.parallel import gather, is_dist, is_master, reduce +from supar.utils.transform import Batch + +logger = get_logger(__name__) + + +class Parser(object): + + NAME = None + MODEL = None + + def __init__(self, args, model, transform): + self.args = args + self.model = model + self.transform = transform + + @property + def device(self): + return 'cuda' if torch.cuda.is_available() else 'cpu' + + @property + def sync_grad(self): + return self.step % self.args.update_steps == 0 or self.step % self.n_batches == 0 + + @contextmanager + def sync(self): + context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext') + if is_dist() and not self.sync_grad: + context = self.model.no_sync + with context(): + yield + + @contextmanager + def join(self): + context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext') + if not is_dist(): + with context(): + yield + elif self.model.training: + with self.model.join(): + yield + else: + try: + dist_model = self.model + # https://github.com/pytorch/pytorch/issues/54059 + if hasattr(self.model, 'module'): + self.model = self.model.module + yield + finally: + self.model = dist_model + + def train( + self, + train: Union[str, Iterable], + dev: Union[str, Iterable], + test: Union[str, Iterable], + epochs: int, + patience: int, + batch_size: int = 5000, + update_steps: int = 1, + buckets: int = 32, + workers: int = 0, + clip: float = 5.0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ) -> None: + r""" + Args: + train/dev/test (Union[str, Iterable]): + Filenames of the train/dev/test datasets. + epochs (int): + The number of training iterations. + patience (int): + The number of consecutive iterations after which the training process would be early stopped if no improvement. + batch_size (int): + The number of tokens in each batch. Default: 5000. + update_steps (int): + Gradient accumulation steps. Default: 1. + buckets (int): + The number of buckets that sentences are assigned to. Default: 32. + workers (int): + The number of subprocesses used for data loading. 0 means only the main process. Default: 0. + clip (float): + Clips gradient of an iterable of parameters at specified value. Default: 5.0. + amp (bool): + Specifies whether to use automatic mixed precision. Default: ``False``. + cache (bool): + If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``. + verbose (bool): + If ``True``, increases the output verbosity. Default: ``True``. + """ + + args = self.args.update(locals()) + init_logger(logger, verbose=args.verbose) + + self.transform.train() + batch_size = batch_size // update_steps + eval_batch_size = args.get('eval_batch_size', batch_size) + if is_dist(): + batch_size = batch_size // dist.get_world_size() + eval_batch_size = eval_batch_size // dist.get_world_size() + logger.info("Loading the data") + if args.cache: + args.bin = os.path.join(os.path.dirname(args.path), 'bin') + args.even = args.get('even', is_dist()) + + train = Dataset(self.transform, args.train, **args).build(batch_size=batch_size, + n_buckets=buckets, + shuffle=True, + distributed=is_dist(), + even=args.even, + n_workers=workers) + dev = Dataset(self.transform, args.dev, **args).build(batch_size=eval_batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + logger.info(f"{'train:':6} {train}") + if not args.test: + logger.info(f"{'dev:':6} {dev}\n") + else: + test = Dataset(self.transform, args.test, **args).build(batch_size=eval_batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + logger.info(f"{'dev:':6} {dev}") + logger.info(f"{'test:':6} {test}\n") + loader, sampler = train.loader, train.loader.batch_sampler + args.steps = len(loader) * epochs // args.update_steps + args.save(f"{args.path}.yaml") + + self.optimizer = self.init_optimizer() + self.scheduler = self.init_scheduler() + self.scaler = GradScaler(enabled=args.amp) + + if dist.is_initialized(): + self.model = DDP(module=self.model, + device_ids=[args.local_rank], + find_unused_parameters=args.get('find_unused_parameters', True), + static_graph=args.get('static_graph', False)) + if args.amp: + from torch.distributed.algorithms.ddp_comm_hooks.default_hooks import fp16_compress_hook + self.model.register_comm_hook(dist.group.WORLD, fp16_compress_hook) + if args.wandb and is_master(): + import wandb + # start a new wandb run to track this script + wandb.init(config=args.primitive_config, + project=args.get('project', self.NAME), + name=args.get('name', args.path), + resume=self.args.checkpoint) + self.step, self.epoch, self.best_e, self.patience = 1, 1, 1, patience + # uneven batches are excluded + self.n_batches = min(gather(len(loader))) if is_dist() else len(loader) + self.best_metric, self.elapsed = Metric(), timedelta() + if args.checkpoint: + try: + self.optimizer.load_state_dict(self.checkpoint_state_dict.pop('optimizer_state_dict')) + self.scheduler.load_state_dict(self.checkpoint_state_dict.pop('scheduler_state_dict')) + self.scaler.load_state_dict(self.checkpoint_state_dict.pop('scaler_state_dict')) + set_rng_state(self.checkpoint_state_dict.pop('rng_state')) + for k, v in self.checkpoint_state_dict.items(): + setattr(self, k, v) + sampler.set_epoch(self.epoch) + except AttributeError: + logger.warning("No checkpoint found. Try re-launching the training procedure instead") + + for epoch in range(self.epoch, args.epochs + 1): + start = datetime.now() + bar, metric = progress_bar(loader), Metric() + + logger.info(f"Epoch {epoch} / {args.epochs}:") + self.model.train() + with self.join(): + # we should reset `step` as the number of batches in different processes is not necessarily equal + self.step = 1 + for batch in bar: + with self.sync(): + with torch.autocast(self.device, enabled=args.amp): + loss = self.train_step(batch) + self.backward(loss) + if self.sync_grad: + self.clip_grad_norm_(self.model.parameters(), args.clip) + self.scaler.step(self.optimizer) + self.scaler.update() + self.scheduler.step() + self.optimizer.zero_grad(True) + + bar.set_postfix_str(f"lr: {self.scheduler.get_last_lr()[0]:.4e} - loss: {loss:.4f}") + # log metrics to wandb + if args.wandb and is_master(): + wandb.log({'lr': self.scheduler.get_last_lr()[0], 'loss': loss}) + self.step += 1 + logger.info(f"{bar.postfix}") + self.model.eval() + with self.join(), torch.autocast(self.device, enabled=args.amp): + metric = self.reduce(sum([self.eval_step(i) for i in progress_bar(dev.loader)], Metric())) + logger.info(f"{'dev:':5} {metric}") + if args.wandb and is_master(): + wandb.log({'dev': metric.values, 'epochs': epoch}) + if args.test: + test_metric = sum([self.eval_step(i) for i in progress_bar(test.loader)], Metric()) + logger.info(f"{'test:':5} {self.reduce(test_metric)}") + if args.wandb and is_master(): + wandb.log({'test': test_metric.values, 'epochs': epoch}) + + t = datetime.now() - start + self.epoch += 1 + self.patience -= 1 + self.elapsed += t + + if metric > self.best_metric: + self.best_e, self.patience, self.best_metric = epoch, patience, metric + if is_master(): + self.save_checkpoint(args.path) + logger.info(f"{t}s elapsed (saved)\n") + else: + logger.info(f"{t}s elapsed\n") + if self.patience < 1: + break + if is_dist(): + dist.barrier() + + best = self.load(**args) + # only allow the master device to save models + if is_master(): + best.save(args.path) + + logger.info(f"Epoch {self.best_e} saved") + logger.info(f"{'dev:':5} {self.best_metric}") + if args.test: + best.model.eval() + with best.join(): + test_metric = sum([best.eval_step(i) for i in progress_bar(test.loader)], Metric()) + logger.info(f"{'test:':5} {best.reduce(test_metric)}") + logger.info(f"{self.elapsed}s elapsed, {self.elapsed / epoch}s/epoch") + if args.wandb and is_master(): + wandb.finish() + + self.evaluate(data=args.test, batch_size=batch_size) + self.predict(args.test, batch_size=batch_size, buckets=buckets, workers=workers) + + with open(f'{self.args.folder}/status', 'w') as file: + file.write('finished') + + + + def evaluate( + self, + data: Union[str, Iterable], + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + amp: bool = False, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + r""" + Args: + data (Union[str, Iterable]): + The data for evaluation. Both a filename and a list of instances are allowed. + batch_size (int): + The number of tokens in each batch. Default: 5000. + buckets (int): + The number of buckets that sentences are assigned to. Default: 8. + workers (int): + The number of subprocesses used for data loading. 0 means only the main process. Default: 0. + amp (bool): + Specifies whether to use automatic mixed precision. Default: ``False``. + cache (bool): + If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``. + verbose (bool): + If ``True``, increases the output verbosity. Default: ``True``. + + Returns: + The evaluation results. + """ + + args = self.args.update(locals()) + init_logger(logger, verbose=args.verbose) + + self.transform.train() + logger.info("Loading the data") + if args.cache: + args.bin = os.path.join(os.path.dirname(args.path), 'bin') + if is_dist(): + batch_size = batch_size // dist.get_world_size() + data = Dataset(self.transform, **args) + data.build(batch_size=batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + logger.info(f"\n{data}") + + logger.info("Evaluating the data") + start = datetime.now() + self.model.eval() + with self.join(): + bar, metric = progress_bar(data.loader), Metric() + for batch in bar: + metric += self.eval_step(batch) + bar.set_postfix_str(metric) + metric = self.reduce(metric) + elapsed = datetime.now() - start + logger.info(f"{metric}") + logger.info(f"{elapsed}s elapsed, " + f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, " + f"{len(data)/elapsed.total_seconds():.2f} Sents/s") + os.makedirs(os.path.dirname(self.args.folder + '/metrics.pickle'), exist_ok=True) + with open(f'{self.args.folder}/metrics.pickle', 'wb') as file: + pickle.dump(obj=metric, file=file) + + return metric + + def predict( + self, + data: Union[str, Iterable], + pred: str = None, + lang: str = None, + prob: bool = False, + batch_size: int = 5000, + buckets: int = 8, + workers: int = 0, + cache: bool = False, + verbose: bool = True, + **kwargs + ): + r""" + Args: + data (Union[str, Iterable]): + The data for prediction. + - a filename. If ends with `.txt`, the parser will seek to make predictions line by line from plain texts. + - a list of instances. + pred (str): + If specified, the predicted results will be saved to the file. Default: ``None``. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + prob (bool): + If ``True``, outputs the probabilities. Default: ``False``. + batch_size (int): + The number of tokens in each batch. Default: 5000. + buckets (int): + The number of buckets that sentences are assigned to. Default: 8. + workers (int): + The number of subprocesses used for data loading. 0 means only the main process. Default: 0. + amp (bool): + Specifies whether to use automatic mixed precision. Default: ``False``. + cache (bool): + If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``. + verbose (bool): + If ``True``, increases the output verbosity. Default: ``True``. + + Returns: + A :class:`~supar.utils.Dataset` object containing all predictions if ``cache=False``, otherwise ``None``. + """ + + args = self.args.update(locals()) + init_logger(logger, verbose=args.verbose) + + if self.args.use_vq: + self.model.passes_remaining = 0 + self.model.vq.observe_steps_remaining = 0 + + self.transform.eval() + if args.prob: + self.transform.append(Field('probs')) + + #logger.info("Loading the data") + if args.cache: + args.bin = os.path.join(os.path.dirname(args.path), 'bin') + if is_dist(): + batch_size = batch_size // dist.get_world_size() + data = Dataset(self.transform, **args) + data.build(batch_size=batch_size, + n_buckets=buckets, + shuffle=False, + distributed=is_dist(), + even=False, + n_workers=workers) + + #logger.info(f"\n{data}") + + #logger.info("Making predictions on the data") + start = datetime.now() + self.model.eval() + #with tempfile.TemporaryDirectory() as t: + # we have clustered the sentences by length here to speed up prediction, + # so the order of the yielded sentences can't be guaranteed + for batch in progress_bar(data.loader): + #batch, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict = self.pred_step(batch) + *predicted_values, = self.pred_step(batch) + #print('429 supar/parser.py ', batch.sentences) + #print(head_preds, deprel_preds, stack_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text) + #logger.info(f"Saving predicted results to {pred}") + # with open(pred, 'w') as f: + + + elapsed = datetime.now() - start + + #if is_dist(): + # dist.barrier() + #tdirs = gather(t) if is_dist() else (t,) + #if pred is not None and is_master(): + #logger.info(f"Saving predicted results to {pred}") + """with open(pred, 'w') as f: + # merge all predictions into one single file + if is_dist() or args.cache: + sentences = (os.path.join(i, s) for i in tdirs for s in os.listdir(i)) + for i in progress_bar(sorted(sentences, key=lambda x: int(os.path.basename(x)))): + with open(i) as s: + shutil.copyfileobj(s, f) + else: + for s in progress_bar(data): + f.write(str(s) + '\n')""" + # exit util all files have been merged + if is_dist(): + dist.barrier() + #logger.info(f"{elapsed}s elapsed, " + # f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, " + # f"{len(data)/elapsed.total_seconds():.2f} Sents/s") + + if not cache: + #return data, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict + return *predicted_values, + + def backward(self, loss: torch.Tensor, **kwargs): + loss /= self.args.update_steps + if hasattr(self, 'scaler'): + self.scaler.scale(loss).backward(**kwargs) + else: + loss.backward(**kwargs) + + def clip_grad_norm_( + self, + params: Union[Iterable[torch.Tensor], torch.Tensor], + max_norm: float, + norm_type: float = 2 + ) -> torch.Tensor: + self.scaler.unscale_(self.optimizer) + return nn.utils.clip_grad_norm_(params, max_norm, norm_type) + + def clip_grad_value_( + self, + params: Union[Iterable[torch.Tensor], torch.Tensor], + clip_value: float + ) -> None: + self.scaler.unscale_(self.optimizer) + return nn.utils.clip_grad_value_(params, clip_value) + + def reduce(self, obj: Any) -> Any: + if not is_dist(): + return obj + return reduce(obj) + + def train_step(self, batch: Batch) -> torch.Tensor: + ... + + @torch.no_grad() + def eval_step(self, batch: Batch) -> Metric: + ... + + @torch.no_grad() + def pred_step(self, batch: Batch) -> Batch: + ... + + def init_optimizer(self) -> Optimizer: + if self.args.encoder in ('lstm', 'transformer'): + optimizer = Adam(params=self.model.parameters(), + lr=self.args.lr, + betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)), + eps=self.args.get('eps', 1e-8), + weight_decay=self.args.get('weight_decay', 0)) + else: + # we found that Huggingface's AdamW is more robust and empirically better than the native implementation + from transformers import AdamW + optimizer = AdamW(params=[{'params': p, 'lr': self.args.lr * (1 if n.startswith('encoder') else self.args.lr_rate)} + for n, p in self.model.named_parameters()], + lr=self.args.lr, + betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)), + eps=self.args.get('eps', 1e-8), + weight_decay=self.args.get('weight_decay', 0)) + return optimizer + + def init_scheduler(self) -> _LRScheduler: + if self.args.encoder == 'lstm': + scheduler = ExponentialLR(optimizer=self.optimizer, + gamma=self.args.decay**(1/self.args.decay_steps)) + elif self.args.encoder == 'transformer': + scheduler = InverseSquareRootLR(optimizer=self.optimizer, + warmup_steps=self.args.warmup_steps) + else: + scheduler = LinearLR(optimizer=self.optimizer, + warmup_steps=self.args.get('warmup_steps', int(self.args.steps*self.args.get('warmup', 0))), + steps=self.args.steps) + return scheduler + + @classmethod + def build(cls, path, **kwargs): + ... + + @classmethod + def load( + cls, + path: str, + reload: bool = True, + src: str = 'github', + checkpoint: bool = False, + **kwargs + ) -> Parser: + r""" + Loads a parser with data fields and pretrained model parameters. + + Args: + path (str): + - a string with the shortcut name of a pretrained model defined in ``supar.MODEL`` + to load from cache or download, e.g., ``'biaffine-dep-en'``. + - a local path to a pretrained model, e.g., ``./<path>/model``. + reload (bool): + Whether to discard the existing cache and force a fresh download. Default: ``False``. + src (str): + Specifies where to download the model. + ``'github'``: github release page. + ``'hlt'``: hlt homepage, only accessible from 9:00 to 18:00 (UTC+8). + Default: ``'github'``. + checkpoint (bool): + If ``True``, loads all checkpoint states to restore the training process. Default: ``False``. + + Examples: + >>> from supar import Parser + >>> parser = Parser.load('biaffine-dep-en') + >>> parser = Parser.load('./ptb.biaffine.dep.lstm.char') + """ + + args = Config(**locals()) + if not os.path.exists(path): + path = download(supar.MODEL[src].get(path, path), reload=reload) + state = torch.load(path, map_location='cpu', weights_only=False) + #torch.load(path, map_location='cpu') + cls = supar.PARSER[state['name']] if cls.NAME is None else cls + args = state['args'].update(args) + #print('ARGS', args) + model = cls.MODEL(**args) + model.load_pretrained(state['pretrained']) + model.load_state_dict(state['state_dict'], True) + transform = state['transform'] + parser = cls(args, model, transform) + parser.checkpoint_state_dict = state.get('checkpoint_state_dict', None) if checkpoint else None + parser.model.to(parser.device) + return parser + + def save(self, path: str) -> None: + model = self.model + if hasattr(model, 'module'): + model = self.model.module + state_dict = {k: v.cpu() for k, v in model.state_dict().items()} + pretrained = state_dict.pop('pretrained.weight', None) + state = {'name': self.NAME, + 'args': model.args, + 'state_dict': state_dict, + 'pretrained': pretrained, + 'transform': self.transform} + torch.save(state, path, pickle_module=dill) + + def save_checkpoint(self, path: str) -> None: + model = self.model + if hasattr(model, 'module'): + model = self.model.module + checkpoint_state_dict = {k: getattr(self, k) for k in ['epoch', 'best_e', 'patience', 'best_metric', 'elapsed']} + checkpoint_state_dict.update({'optimizer_state_dict': self.optimizer.state_dict(), + 'scheduler_state_dict': self.scheduler.state_dict(), + 'scaler_state_dict': self.scaler.state_dict(), + 'rng_state': get_rng_state()}) + state_dict = {k: v.cpu() for k, v in model.state_dict().items()} + pretrained = state_dict.pop('pretrained.weight', None) + state = {'name': self.NAME, + 'args': model.args, + 'state_dict': state_dict, + 'pretrained': pretrained, + 'checkpoint_state_dict': checkpoint_state_dict, + 'transform': self.transform} + torch.save(state, path, pickle_module=dill) diff --git a/tania_scripts/supar/structs/__init__.py b/tania_scripts/supar/structs/__init__.py new file mode 100644 index 0000000..9afbd79 --- /dev/null +++ b/tania_scripts/supar/structs/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from .chain import LinearChainCRF, SemiMarkovCRF +from .dist import StructuredDistribution +from .tree import (BiLexicalizedConstituencyCRF, ConstituencyCRF, + Dependency2oCRF, DependencyCRF, MatrixTree) +from .vi import (ConstituencyLBP, ConstituencyMFVI, DependencyLBP, + DependencyMFVI, SemanticDependencyLBP, SemanticDependencyMFVI) + +__all__ = ['StructuredDistribution', + 'LinearChainCRF', + 'SemiMarkovCRF', + 'MatrixTree', + 'DependencyCRF', + 'Dependency2oCRF', + 'ConstituencyCRF', + 'BiLexicalizedConstituencyCRF', + 'DependencyMFVI', + 'DependencyLBP', + 'ConstituencyMFVI', + 'ConstituencyLBP', + 'SemanticDependencyMFVI', + 'SemanticDependencyLBP', ] diff --git a/tania_scripts/supar/structs/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef548e93f5fe211cae6a010de99dbcb04c3710ad GIT binary patch literal 703 zcmd1j<>g{vU|<knUzG05%)sy%#6iYP3=9ko3=9m#DGUq@DGVu$ISjdsQH;4vQA~^= zK2r{JE=v>(n9ZESn#&f&mdhT+p34!%k;@synadT$1(svU;m+lW;>qQW;?3oY;>+ca z;?EU`637*d5@cjZXGmdP#26)%!WPV+$^Md&fq_Aj=@y?)W?pJyk#k03W}b79+b!PU z)Z9$p#G>r{GUp&SO~zYd!6ikd$t9&lsVOd*#U(|VNu?#3`FWbGw`80$eNrnjlM{0? zt5Q>(^Ye;JGD}KR^O7q;2JvGExTF@O=B0q-jq*V%co701E|+g&Nl|7+NKtC4Cfh9( z?LJNcw*-*Q^K}dJyoID6q<{}$99UX3I5jshuOu@WAr4X|hA9kEuE|%#!oa{#1d56x zW)O=LL~wuzb`Ze^B3MBLFNoj)5!@gG6tzYCAQm431B0KY@GaJ4P-r5Iy2X+L3OSJZ zw^&MwQd5h-=73EEn+>)FWZx~Ovdki|fncM-mVm7T84b4N7JGbrVopwc{7Qx*QIMq| z;+MUCMt*Lpeo10UW@28VUQ$kCN@i-2esX?pLB4K!L5Xf|eoAVNesO6*Vv&9^I6{l{ p<Kr{)GE3s)^$IF)aoFVMr<CTT+JTZqF~|i1OgxM-j0#LV%mCu)x=#QA literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4517337ef5ef26d1d5c1d3e7001d4ea719d5120 GIT binary patch literal 946 zcmZ3^%ge>Uz`&q%Up2#-nStRkhy%k+P{!vp1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL zb1q913z*HE!<x$$#g@w+#h%L%#gWSy#hJ?$#RZmQ$>GlBiQ>uSjpEJai{i`WkK)f2 zh!V&Zj1pvINM}f4UBnnAl)@IwpvnG{k%56hlj#<pPi9_fVv%!3VrHImklQWZ;MCkq z-^8Nq{4(btH%-P{V!<UvrO73wMX4z+nZ+eVnMtK3nfZB|thZ#GGJR4jGLsW?GOJQk zob&UFOEODJQ}dE5K?d<-2)Lvcq~@i7<c;z{DtHkBATF10Vo6bEMMzO<swUel6zx7v z0k;H@&GU5&^Sp(mAEbZ}VH{XmG&nUkF|Q;u86gf*CWa{tQm)BY#LB?HP{a%(SU?0Q z!iqRSEDjLC4kFk<1Rsdt1ra<Tf*V8#fCzpD1_nP(;ajZ9pwL7Zb&Dkh6mlT*Z?TjV zrKT2v%>kPTHXCdU$i7=lWtl}_1HndvEdg5xGP($4$u0Ky_{5x?`1q9!pF!#7m#=<C zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB zL1K}9F*s(6_2c6+^D;}~<Mj$Ee{tC4=BJeAq}mlpGB7ZJ5=rqJ1_p)?%#4hTAJ`Ze z4KFYlV4@og8W&K}2PQ^F`wtA15-g020gNDHXhgE{a;tq{fDsMsAXp^Mz`y_imp1%4 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/chain.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/chain.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e42d31e38ad624ca095da2a77618bca27d421e88 GIT binary patch literal 9988 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/chain.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/chain.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f42a094bb248a728f5748ec2648f7828e587fdd GIT binary patch literal 17390 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 VZt8-F)<*`g^cM*A0UHI5G5~K|LgfGe literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/dist.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/dist.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fd9588165983a30bc91fedfe71a124d9e274b7a GIT binary patch literal 5710 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/dist.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/dist.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bde8b84641e2db640d4bc8b6077df3a2e1aae03a GIT binary patch literal 7995 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/fn.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/fn.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..128838b69315f5cfbbab3bcd5933e1af0b4e9816 GIT binary patch literal 11869 zcmd1j<>g{vU|<knUzBcT%E0g##6iZK3=9ko3=9m#VvGz7DGVu$ISf%Cnkk1dmnn)V zmpO_#mnDjY5hTW#!y3h!!jQt8!<Ne)#h%L%#Q_#)$>Gf9isAyZS#!8^d7^k28B*9% znNoQr8B*9GbQ((vM+#>POB7!US1M~3e+oN@Ok+vmPT^@`i4sUrNZ|vCr0}P*W(lSU zqzXY*aHI&P2(_?A38yHe2&Xcoh@>*5h=OH#(>PMZQp8(WqeR>pQY2C&TNqL#Q+b-1 zqeR^qQlwI(TNqNL!F(}yh7_3;*%pQrSukJRogqaoMZSe0MIOwTNEOYJjFL(f%aV+e zP8H9RjFL%}$dZhbO<@dX&{TX03Nb%T=35+|C8<S;Nja&vSVKw+KvZa6W`3R~(=BFC zKet=VzMg)XjJKEz5>qr8Z*jPl<|UV8=I7nwC{8UbP0dSAy~S3PT2fk+m&^z<5sH}^ z7#P?X7#Ng6(a^=fz|hE$!kEt3!6MGk$pT`PFm$jqGm0>DGNSO9(iu{i(ivg0OiZ1u zoy_eF?TqbA?ab{g?W}2RDa<J>EgYQ;DXi&?wTvZDwatt!46y>WOdX6hOp**KjM+>@ zP8|$2Of`(nOs)(mY#t1Z424E1Y{3kg?1{0A3=CWf3JMA#iA7n7c?yX+>G?&OB^kL2 zY57G8X_<K`nR)37!6ilcdFeTo3eNd?d8x@IsVNH1`MCx8d8v6N#R?k1&d$Y}3i)XY zi3;gOi3J&YTwo&|i_(j&z$}mjus~AK$jK}&(L_jqBz-cAOF#x>q$Z{)fGkZ;EryyB znVFiCf@F@P0!TkdF;tyGZeljbk);I+i3-8a&Uy-tIXMc&sX1x7Ir;eo#R`c<sS26t zdHF@DDNr+AD-v@Ha#E2@wX?HR$V;s#(I^3jgGRKGj)JL<f`N{Lv5taatfr=dg0g~! zp@OcRf+>hF0uhFq3Yo<Ui3-V;$vLTTk3zK?#)3s&{{R2~zgsdBG&O)IRt5$J5H<#- z2nj||il|{sVU%QGVd!A2VX$H7U;>dKF;)gih7=}q24;{b>jH)vhJ}ob3@OYV%pesd zjG&a`!Vqf|!&J*u%Ur`;!;sBfq*<r{jeC}CrXpvgxMu*xeF+oDd`XZkOp*-EV4e*_ zp+W~UD7_Q~!R5i}2T7i(hCveSLP>^frlO7x)&<N98PXYRS!!5PSR@(1c2}mbb}&Qu zHVic^3m71(K(2;}f>af!fmJcsFqE*=urxEKFlDn8b=9zhF@Or0V1^V12-altD*|Pu zmmngfh?{|d!A+C(7F%LLL26#gEzZ=u(%jUd#FEro%(<C)x0nm^3vMyzq~>X|-eSzW z#Zi)(n_66wT5yXo>lO<rW!+*0$J9!;TkOgC;DmgOIVCOc7IRL1c@%qoUU5lca&{4@ z%)G@4X0K%UWvQQ$pPQ;*l30?Nn3t%Rl#`f}nOdZu3`+jG=>;Xax%nxnIr_z=1&Kxa z#U(|h$tA`5X?c1Dl|>Q^3=AruI5uKnU|?zxVH9BGV&q^HVB%n8V&q{IV3c6wU=(9y zY7k)NV&q}uVdP`v`NzS`!^FkN@`HuFN*t0F^=xwTlM{1_?ew6I28W5CCR33h0|Ub? z)}q9`^i)k|u)B+d85kIfgg}H0h!6)6vLIz_5W{#t?g2TBsewy?kBN^-gh`BvO-cal z9;ODCe?{^j)r`f-pfCreRuJZZrdUu}RxHKHz)-?a!;r$5!j!_?%9O@r!%)MpfN>!M zgfGdkfT;wWPHPwzFsHCAWb9-rVJTtlU|PV2P}9tq!raW%$<V=2tl7a7%uvF<fTM$9 zA!8?q#aY5t!_dsQkZ}Qb3S$RD3gbfNPR0`U1w0*$3wTo)7cwpc=a)`KNO_pXoWh#I z*1}QCSi=a?7sFi30Ll*~d>|e;eKM!8v@%IDK++%+Q!Ps^YYj^Y7bx{*Gt{zmFxIft zut|c_H>liXlVq@AsA1y=$uQI~W5_Vouu3x2vUf0o=nke1h8lK|4v;@I*%O<Ypk=Ca zMyXF`slIDUZhl@$F<RN0m!GFwP?VpQnp~1uma34Fnw$?VYps$qOH!>8a+6c?^AdAX zbW=+bb99Xi3`}+N^79g)1z2!?ZmL3Zeo88+07}X)D#|ZUO;JcI%Fk6uC`rk$N-R+? zR>%aEak;5^ptPHxmk_T9E|6SOi<65o3qUnjF{l*H%ZJDpD<tNnfJ*(`(wxL%h2+FM zg``x4wEWUMP>HNSl(YQuOOOlIkc?C$Pp9Ok7AxfCmnfu{CKe^;m87OBl;kTEBo-B? zDkLftXXd5nr0N#s=a(py6s4v@J&IO`C}`A`<QFAp=!K-_73UXeS}7zXL>H$P#^<Ew z=_o)Mu?YzfuYzh85DrexFG>Y_HZdnhAte=5dZgx+=z_`wg@VM)B3NA$1g^f3ss$9= zP^&CQg%YqE6v{J8G8Bq45(`q1921+6018Wml8jV^qSWHjoDxtKg%;-!za#lpPfsBp zNAw{q&nPJ=D7MnqPtPpLC{5B!&d=3{=+O@Vg=LX$nK3w`!No)oD8u`Ki%yIj4QiEu z%8TL~3=9mQR4mC*%UHwE!BE4P#w5v5%T&YA!6*r88ZxvpbufU%m}{69fbt`#)Mw}b z)lLj4AX%`E8m0xHGJ$a+lLSKz(*mZ24B`y6tTn6)7*d!QGS;${FfU-~U@T!?zzS;F zEM!b$TF6+-UIWfODPVJI*ul0i)G(K@m9T?yXES3B3rMU6<PN4*rW8nd!&<`zR>9WH z*bK27RQfQaFu}^B8nzmiH0EFiO%^|J7=VKS93+|?x7ZSk(sL6lZn2bQrk3AgE-uZz z#R^VWx0sU?OK!12Vzx*QRC<C6Sxt^21qKF&C~k255f4f?#Zm0V@nCKgYjJ!^YQZg* zl+=RaD7Ip-^etA1BCh28ypp0sP?KpTbCDRx5RSb3Jg~-FETE__0vFWaGMWRXI15xt zgA{Wx@i2+7a4~7HaxsZ9i7+WJDKK#{RVgHAl;&iX#-~C`7L*zSY?~&35h!+VainA> zri03nTdZlBIXUq~ilEY+1=P}k6!dH*`Jm=h5vZOjQUgoo=cN`ysuu3dyp+_6c(Be} ztmPT0MX9%#(o1gfp;`|Oog!^eaA|-Db&x@fl~G(^e?kI;y|^?9<X@N|D5pdGt_jit z3V<RL1_lNfkl#V32#AR>aWP3Tu`sbPaxqCTi7*N<@yT&8i!t%Ah%m7+i7;_62{5rR zfpxjvVk-vc@>?vqiN)EsICDW+4rE6%sL}#eVjwKQz`y{i%$z}%I509W)G%Z*#4y(~ z*Rs?yLn<*)vaMxEXQ*W@VXk3Zzyhjn7O*a4Xa+T_>tdK{*}zGb4b(8JVNYQcX8<Ki z7z>nCYdK2TYB-u1YdJxcS`8<tq6Aew3phd9U?F1)GpJcE&QQx$!&E$>gsX<DnK6Yi zo26(%4Mz$SC<&)9gU#VC;jZPW;aI?v0;>FYLAp!07c$p!)Np|seYLzL+{ij?7;3m{ zcqJKXIBIx7CfG1Q-N9GG0e1sm3S$i)oW~EUo)<DLU|Gme%U{D^!;{TY)L+A2!^gx_ z%Tvo)7+b@-K%j;b)O;%xFA=O^tzk)F?PXdZRKu7hyb#oTVoOwEgI0IG!68V+J*fWx zuhh^AK2SO+hLq7E8JWePN-R;Kya?2;D*_jrxN1<$<pwq-7QrmnamK<`pZT=|iet zKvsflxRQ+2JcW$JGEk+HoRONG4XOmesRdm56zhNsPtP=kgaoiCC=J<$6qTkXB*658 z`V)C6si`RnsTH7(3s@agH@L({^rDJWQ?rXf^&F@x1vWV;wYUVMwkuXhs#M4X^*+J% z1gM%S$S*F=Ov*{cq840lq=2-b`WF(S{v{cyMdg{rsbHrdDj!e?KsrMynMJ9|B{`J} zC5hRoc?yZeV3lc^d5Jj+`K2WVr6sTm5v}?K=P;~wa8hDPaz=b{W>qS@8iq5-s*geS zHVA`qGu%d}{QMl`njed;7?y$33fPd6e1*ia{LB<^lLJ&6=a;1xDHJ58fSX+<`Pr#? z&@>6M7lc7tA&DzFKc_S|PoX%qs0^etu~?y?IJGn-U!gp|D5V&jWI^eqSfMy0zceQW z)N)Ela7)Z7PDO5ufYS*`oq|SEetr&GAJ{doxU?u0oLImSjHOYe08W;0bHV9}3T+nb z!3g#hk?j{)dcoeYhLp?-whG`nRu59UYD7mz>lzyBS(+G|=_u$L8tWOFn3?D(DCnB$ znV4HxLc}aA4b5XASrQZ@_;9qYnSq{}rK!1&0*GZ~VFohS#6r)^1R`dvXJKe$O0;Rl z7J7!}CLq&HEcGmnEWxIk>KU0E8|x_Onpo<YnwlFDZJME_p1G-kiH?G<k+Gho0my9% zx|VvDhQ?r@n&}xCSXjiy#%h8i735FQkOU;;qOHIq5r$T=3bqQqo_<)A=)o#_4Feqo zLmdSp&1gfbSUqsntpOUhLeT@x4;aw_PFFe#3ZTLcl|pw`ZgGhQ#A!MTAhQsThR3ae zj)D=`)kZMQ;AR-4Ll16@X)@m8DakKM%mFpt(@QcmMQ*Wzo6)zJlM703v6bc}W#*+6 z@qt<gpuw{ueGm)OM1ZtbK)vc)OsR$7whE-V!-Z(DKpHb_>4~7y@D^ujUU6Y*YHC$# z5iiITc2EO_sU-gvTS{tKW^$^gK#@5}+yX>cf+QK^Z?QxB6Sr6kic(XG!QJXxY&ofU z=_MK9_F$0~NF^&MM}r%FAO@%b2rA-lv4D8D7)w9`prRMj)<HD(m~)Fu7J!-|AVYYR zc^Fxkq!<+#IT#ff1sDYwSr|n?V+D)?j2w(=j2w(yj7$wYj3P`$-XJ>}D~e1(G;3l` zW_lh<69*JtAn$>iJ;fc+zIrob2}2EIGb0mIEpsPB31bNps8=n{0BSv_Gqy9Nf!giN zEgU6GDU3DDphitIlM6#Lqc}q+BdS=eLoEwP1gf9Og(23gmKD^0PGOW_kYuP~h0>tD zHbjIGCYH@C4(d@e*04a;utFO`pq?~n1PQ7aWPdG333Clw4SNkoGc(9^kjXX-g$9M{ z9gLvSCJ?UWtYIqJQ^VZB0PE4$u%<DkGuCp|uz*-8tl7*(+aR_<+>piu<AGQ(v2^BI z?smpB#uT;`_7;vBZjjGwc}kdTcuH6nu%>V<WK7}gWr|^{<&A-i9B?gQgV+FS7(rMd zyNVl17)#he&ADcf8<>g?)o|8ur7;CF)NlqfXmTa0vO=3m&WSn6r8$WupyECwRlz5< zEH$q<qa-ymPa!oWvqU!~v$!NNFF92qDYc|LH8oG6q&y$gy#)_5Lu)Be?F3S+09Tv| zsmSw6bCXhwK+T%uj6`tXqX;CCSfY>zYO|E&D<nZiD~n5$ic2y}N=s5xbQCi4ic^cg zto$N{l+>J5FuNpQp`<7=uQ)BgC|4n&B0(WDuOwd~p%OL_;g(;dkO~=1)j_BP)sad? ziJ5sypr(&faYklds**xcYGG+6xQ5FpN=;P&4b4GYTgmx(#hJz6rcZtv#IG=?W#;EW zMkey}QlW0l%+G`LhM`vI+9@a%gDnHIGC<bCSgA^oMo~ycYH_MUegSB>5Nu>JxSj^L z1Cu}joB}alAs<v;DC8HVq!tzHC?u7ZC?u9B<fJARmnf7VoDCjR28AYkNZBzbC%?Q{ zp|~J5IWw&i6ab*AGdUkJt_=_A%zQ`;7b|F_>ZR-HC@3W=frgTml9V(d)m&0)a$;$5 zszPyoZYp>LQz5eiG{l`+tWcbq2Wr*jD<l>dXQt;Vq!*<omVnwYsd<SxC7Gbal&^qn z6|7nYB^B6cQBi7HW-)xQC@-fZJ0Tw2uuUk>%+5@R#~3(*8G_mttkADi(16XCptWQ` z*1?AR!R?u(RE5O6#GJ}vP;i0jHV_6EU07Q};TfsmSSZO?C<2ejfZL~F^`PObVuhqc zkPq_nz~Z@?d6~JTxwtcto`OqiT4HHV323wkT*-kNW#9@CdwT^ujs_ml)q{@c>Xnvc z<`nCt<$(s(@{2$z0-j^R27x>Ts<3kqIaxzJGp{5y4>ZuGuA`uyT9KMu3gv*k0`62G zYEBJP9ffF6?QNi`qo84^qhJW4jX+hoj)I1<j)F0WZ=$1M0-{ZI6ih+1nT~=Ph&I<z zFbB~VItmsb+EPcsQZrT)G7$qBRsuydB-enPie(H5q(C1`B<18M>8GTYrRL-pKtys= zONug+i}hh8jb1?|*w-L~L8%7Q;M6=lkVHXhN@k*7eo?wUh^Oz82pX?1RdqE|wJ=b% zH1<J+Ry@pXu)*NA0?L3DXaWT^X#yUw0@b4F3^fd~T%aM}bjB2hbjA(_5e9LFiA;q| z!3>&=;E^71m8;2gi%HJ_TzP9U-eSo~%`*av7lB3`ZgJUwhCe`~`F8(6l`+T~8HOr( zq<BP(t{~Jx8Zb-{TR<b_C~gH+y(|n24B!bK8}O804MVJC3{x#*EmI9+3PUz)kw^^_ zga!?_Niu+@Uh)`0m2?eL8dDk*Xey+T2|PauvBgi5u?XaUP39s$P$LCA#xKIazyO+& z%t<Xn@)M^`dTL&3MM06BI3oi?F~}uM4OR?Qa@aiuQw;VD$h7R#N=*)MtLhdDD0Cp> zVEmx=1_z`B%`dvem06OSo1R)yl3E0AQr+SxN-aw*Do#z&<SX(4xe(MqDe?vB0tLDu zI0lM9E(W)qZZRg_VoU-JP(f<CTU_8w0nXpIxF9`LP(gi*AI^>km8Qi-paCMVZ#9{U z{6Q84f(USIawGZhHYhp`7#J9Yl=K*dScMpMm_)#{9ZWxXI9V9E7(sI`d`uvk<*yK{ z6lnJ42M?zJV^KT<14A-sv<Ml4W`)2r>3Iwc45<uJj42FJOeu^}%&9D?tXXVX>{%SC ztXZ5XOudXLyeS|tt`yc(?i99E)-0|xwiNahjuuu>b1RAmu7fv)6C|6$mI|61=StxM zjrzdm%)x5;Q@DZ|H2H3E`sAk<m*%Ec6jWURXOQ5;wA3PngoGTJctQfGs!c8}N>wNY zO>LzX7bg}~D)=S(DU>DVl!EGpjKmU!#3InZ0Jwn5%u7>9EJ`m02RWpc3{Fi2wI-5F zi;F>F532e=B?anWb3rAz8>bJWGmDE$Q;YRYEX|EfAjX7%S{MrX1tpoenN_JNkP&ic zZEbz$(v(Dn)Cy210c1Wz^-9KD+{uZ>CGnYgppge~)&i%XTg)k$xkaD_4k!&=P<jSo z@E9Iw+_Hvo0YeRFD4Ds2sfHn*v4&v*Qw?Jc^Fk&@h8kwjBxNweN=83TmRp?g;3@(| z@GZgO#In@*wEUv@q{QUx^2DN)Tdc`B`FW|DEVr1GODe$5fGA~y42*yi9)tj=IQF#s zB9J~cP)-AlEOIfkG4e2SFjfh|qf8H~<`!eRAId~9sF}{jz`y|ZNg4wK1E@^PVpzmj z!;r-|kueA~GRXuQo2+46z*NJskg<jtLNkF%642-*GkA281?+p)8pax?8fFOw&}gLy zLoHhg+XD6))*7Y-94Sl-8Ee=UGN&+r8lx+jA-%A4So+rFyu}L&iIjLy%;XmpgS}kj z2+CJ>pbX5JT2YXgmlB^?e2W=Wuz*6n2;BeT%1bSW>e6H{$^hxe1`*&AAQQv_1#}Up zUv-Nmy(lpS5_X^h98v&tz(QUR6oR10mS7eG_kbiAtAr3?2vfF_u?RE|tSNAdBR)Pa zF*h|n{uWn!d~SY9X%2|Z6CYn#nwSHXVULeb$xn`tzr|Awn&nE)O)bgDPXYHIZ?Pno zrX=2CPRuR1#g$xIT#}y~pH`l7i#07LA2bI58E3l1oS9cr1R9TrD@rO)DFUUxq9Ty@ zz&=3`phQuWz`(#D2l5VNxS55CiA{h}fsu&~)RhCvf&v8=`d}KAbil<+4pQ-w%ACrQ z1uk4tS+Y1%7<(C0m{M7?I8#94oGC0Ib{ZRa?vn*vTyVj4aHp_?WK&pDc|bG>Lkk!1 zG99pLUU1>U4K7>~Q&K<?n+Wm}IPSouHz+zV@*b!b0;gCd2GB(C0??!@(?Zbl14zDO zs$pKpjL3OKDWFP<1rp|<3<$Lfl-`R#Nl=pol5P;zg3}FJn1Z6f3KXWG48z0B2g_m* z(_mSw2$c9x@)#&!L0Z5r21N{X#2=Qg7(qFxmbHedhDCw_H1=P^3}Z2Y$NE8&R^VL3 z3d=>1iL4sd8t_EcLdF{Qh0L|=pw22NcNKwRP?N1F7ZjAB+*6bfV!^XaQ2{7CI3Ruo zITupMfWsT?aZp}~Vgu!s_zEapiI!`?NzV}!8ldSt9%e2^DMk_SfB`tmK*I!<W&AYx zib_CkC<PH^Aff_9fSptcVpV~NY7kKaB5FYdD8P&AK`i`<y@7#&!2;wI(7*!+0}~TC zsk3r0YA_ao<S>#ttS0>ovH@0;!V@ki*+P;!4?LNJYEqUg&NMb~2OUz2a>I4-q;P<e zcM5ANFPP?pCUmY8?iNV4;7b8@zj<#71cR6Tq`*s+B5-;Kl_!u$0J#;j!T~ksKp32a zK*<tZ&4AZD)G&fa02s5FYM4OzGnhe>3Di;p8KlV!DMrBwJrxw`%#cV2Cv=bs^jHN2 zh#x2@K?#-(yeOnf0^Q9hNgcI50p(0kodR~K7Xt%$iAD}XE@LgICS=HBs$s}tW@3tA zgw`o6pgLs%DD5+Y1~gKb7c!-=^fE4BU&ye4Erq#;Wg*i-Mo68Z$qK16G#PIR`sby3 z<d--nmZYZV7iA_V=0Hkh##?MT`RSP@#hM&Z!r&%?9;i)Ul$iwX_7oSjfD#ipTYx<e zs$Om}=a%N&V$aPlOHIkly~S1xjv!4|NI-#e2Ur)*AOn@bp|Bw1VHRN2W2}<I2r^hs zC@Ka;13wwLp$_DBQ2Y>+C7Kx+7<@pELeCOvj71<hkoUo*K8%26iJ~Tu`*?4027_k+ zauX|vOQ9hB@Q7c-zyMn9#}Lm@!?=JElr9&7#;%xaS-{N)P?R!Bfac{H7ciHwq%eVs zF;D{{g-M*DnQ0+o7F!B)IwNR?9@MY`t=N%Z5Mfxv7{t)Wuz)=U)YxFEWvgMUVHROn zz){1xkZ}Pg#FkpN8rB6|HB2>ZDNGU!3z=%zq#0`2OSl*C)G*etOE9FcEM%(Xs9{*Z zTf<hv0dAgg1T$!|`h|e|d*EaQ>4ortv(7D+;{2kLTWratxy7Zq;DQs}7rDh!oLQAx z1gd{-ae{}Z3i69ni$LA2BJfBts3wI}IIPJziMa(upggF_2}xD(v=qewGCnmWz5?8* zxW!m?i!u8ab4g<9Eye<Dc{3gqr=X4(8?yi-AEO<k7$ay=7Y`!~W0fF0%J5`RP`(CL zNZ<?_MySEZya3$1OJQ8dRLcq)iL7B>zy_+WYCvl$*lSo)m=-eCFiA5=Fx0RvWCpFY zfM!-`1206A15yov65K6r&`5o13V1rd2wX9ND*$jajwvq{9CDg$kT3%0ya}K*KM6#D z^cNL^SfJt$5;WkJ4k-KOfI<c2D+y*HMio%KEQAOPs^>gVK@6_`Ag(}jPbUKd187NW zF-p$k2DiIFa+-{8nsP;<pf)XANo7H1UV0Iz$6o|C6<p7O!sM0^Wbg+v=#!kEo132p z?tDXL8TgQ8)AEWyIqw!9q{K@sEy)K}-9?}PDFT-opapeB;3^d~cX5jgF^PGL1vCu^ z9?=JPI>AjtaHR<@CW=5VzQvkYP>@qu1gb!a8bJ;hgcOn~@$k;fEzV+id4UKJFbfn* zw>WGd&0{;zNJTNoha5~Ij2uj$RewB;Qp{o&N-;9l0?q<b0wMx}Y!YltY)o8C0P4zy AzW@LL literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/fn.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/fn.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52542e3188bfcde5e56f78ad516e4e75e2da4552 GIT binary patch literal 21496 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 SskAOI2txS{oDH1d>;eGpwdP^~ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/semiring.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/semiring.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eebbfcd87f3a9e230655a6f65e90217253551767 GIT binary patch literal 17503 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/semiring.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/semiring.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9cfb3a935ad9c1fee1faac17b0a0e4317f6aa3d GIT binary patch literal 33629 zcmZ3^%ge>Uz`&q%Up2$ngn{8Phy%l{P{wB;Mh1rI3@HpLj5!QZAet$MF_$Tdi4nwR z&SB1FiDCh>8FN^pSW_5MSaR5M*`wHVIifhg;;cEGxm;0Pj0{W+?hGkxEet8_socw$ z85mYGL+xOQ;sMKXv@oP_rt+Z4@q*>JS{PEeQ+d(k_)>UU7^3*WDtKEMQur`*3xMVL zTNqLVFmwxo<pf(8QiL$%gursbEet6l7;?g3Infq|6fq1r5wM(i3qy(ohMZ^$V=#lJ z<V%pZ{Z=yGVk=5bDNRn*WW2@US&~|mn3R*M$#hGwI5D>%Cp9HLCqKQoG&i-P;1*|b zL1IyHYHnhMCgUw;Ur)bekP$Epjzk6qhR=R1pr}e^h+<4(h+;}%jABk<iegD&j$%z^ zOJPZ6&*Fe-Nnu6du_5!)*izVASe7v`Fsz0tXNck?(F6_*6Sz{@Qe@Fw!IjFLf^Ii= z3oDx4JVff`!O+P|q)uK8oqR;<<ipU(k3}bHXk+@CBZVKs9072M3nIsiBs@OQLX9Ow z03*DG!1|Hn95tj_QUo#d2ouyJgrP?SLyvGOdzL87sc0@`OA)~^L5xHbL@`VdC(#5k z3=<?sG(jB01W61N(8F5-Lyr_eJ(3uDqzUSg!q6i_P>(c*9@!L`U<OUOTO7fuxtT?o zdFhEMj0_B13JMAePKm{-3dK-ih2)&X;$j7><jj&(tAzCY{FL0pJY7ReOG{mtk_0_2 zus%nGrp#i6l+?7$ywnthq)LTEg_6>OoKyv?+{BU$s{|Ww9fg?uf}GM~5M7d)n+jrp z<dV{=4Qh21VxVlpTDt^2u+dPR-U$ks#R`cE#i=C<`DqGei8-aI#n#9wAm)OVCFken zmX;)zWR|7sC?pma=O<@^ISPq+DGC{h#R`de3YjUXc_o=8l?tgjsky0nB?<`!325el z-3K-h$qXIb1{fxQEl9~ME-A`PDlJJZR>&_)EmBC(hWe$5iGhLPB_jg^!!5>&Ta1;U zdZMJXC@&daUotQ-fYgBapLrNSg?<fV4O0~Z14A&wN=Cnx3@e#$F(>B~7l9;;co`TN zia}}>6cm2>>SyHVrs{*dotT%Xmz0y3l9^hhpPZjtkgr>kT2Z2#T9%ljUy_)YnHXQ3 zT$EW*QmkKGT98<zUtCgDnhfGWV_vVI@)mPqN=g+EEQ#nPrlf!hsn6UD3=9nn5BLQp z7<QI+@O%c91_YhY3UYpt00RR<ksyc=LUMPJ2q-w1b4zoOY|Aapkp(Ff0}<k&K>Ppy z|NmReDVez_mVx{Z!k=}ZVYL9{9t>Q=w2YB~VKpe=!E(V2V8^Uvyv1Bxn!A#@NEl=f zI7p?@omM2rz`%gywBpiSMNpLt@&h;^`b)b?Cj@s^^;BKpkSqc@mWoc)WW2>vP?Voi zB#+@PC6K##;SmH<r3zAna9CMa*@WcI>YnNg98%PF7^snxT$)>4nv2D0Aa_*p!<`0E zr->SB6<rlGm^*8GYA<leP}^~ujJMd6OLIX%g2i<jpnwxVb{$BeE^63Sc2&+0?yT#n zyTBm}aUKge=|BiJ1_lOjx(kD(I|dx-j$r{j%|SFmNKl?$#>Bv|8kE<;LN&~&d}s>Q zWCAC@B2d=TWI;-%pqyU>POBhifr@TuK1#_iK}xJC`6Y%Re}U2pD6tClmv@y<D4t$E zseDG^0>z27Q)(9^U*y-i!mo9KLkr?hWEX=BX9vZb76SuAJHvE_5+vCUhBU?$#uknm zMs&ApGWjLLy~e=605S%Y#XcJ_FfdGIoX*h6ge$->4TEM?NEk5RV$8h7m<0|AXvx<A z_W3Uko1Dblq?AOvDg}7df(vjxo1FaQ#GGO~J(vn}P>_J!^P_=bf$?(lMdm9ES0pa9 zU1Hn701ks9P~5I$0^0&EX^TO=Nl*aWbc+>iY!x4>HKrg#L50?j28O5nq8G#r;An&5 zMShbj{3aJTOu)vYgbm0l5dLfiNlJ{kLM96y^w<kCrdzCOnK?P}w^*uDi}H)W@eXpf z0?gSU;dmrxgZY-A*aa1{pyVL{Ngh)wF7hi};a9l8p+HOb7J-877IS`HDyCyu^7B&T zs}Q9dh--_@spS{><*)F|U*M1jJM|VzZenpZN&yT?eBc1Kz#qU&H4I2WjFLOyx$zb^ z$oSNhcu+_efnp4$@~{J?0gzn^ut4Vo2Qo-gl@L6=z{MOv>Lp+`YJY84?TnBG#!D<N z^6OmT*SWx<1NIZ`e8U5B7}PiMVDA)xorK~AF1T~!tAsKA5buiWiMp=387T{#mv~&{ z*S*58dx1ljww@?*0M*^rAOh3v9H4Xq@?@1D+~qJKPgHlq0^j^1zxEY=?F$^*G<LTO z$jLa|%?Wd4JW{fOi}|9u92Vm4XvqeY`N5S7v;+pl>SrhXnSc?I1!@?w;3l9K@Zd68 zllc}$UTS%KT4_$sE!N_U#DY{v8p0@gz)7e$J|{Cf6)g!t1Oq`Hl7i=hs;;UTigVPl z<OH~bXy&CNZ&0-OfCzBhVE6?TH4s;$Mh!$P6qirXlNGX0Km|KEazM?B=?pcD(DDY- zSjKPxdvbnWS!z*96;c}pA`%HIAwl&uxG?YFfTUmwtl})qgIR_szTjf9pil||5ujGD z-%7?JP#l7Kmhtg<iMgrq@wd3*<8$*<N^?MLp7{8}(!?C7410WhN`7)YwAcZK^(}62 zhch>|BqKlN7Hdg<QF6vDwvg1k;{2i_(69rz32=)!Gp_{FDgw1?ia>46B2bgA2-HR? z0*!7K8G+mcs^yDpK%EONr~LdJs5zkYUj!<$irhhpK!rdNC_feXgSeoCSQG+cf%_>S zZ-MLlBG5=2m;iMWiVavmouCE=2>igr&dTwD0YnHf@bEUc+~DGFaDKol@PUbuRdj;u z6rT?ajI5#yLYKsV85>f!<bW9n;v+Kyn_x>cSi=W41~x%3i+rt8Afu&V`lS{WgZUd= zw}71jkp&AOSu6#&SQ;cHJt1@o*uBy#n8ExFp<5t)Fb_;1>6V7;mIX=4PAHvH17@sH z22&eKw?Oz{9+*JVEeqEz2a=MT!8(Tr%vfOzrgpIIf$+gRFoC374z61pB&7}Ww>B)u zwReEMpnV|p2-ph{Wni^P#%RNhF`ZDcfOQGa6>(jV8q*D`TXet-1c9W@6s}EiLh2N7 z%qlJ@T>|#4B1i{>K+>TI*P#FlWQ7H(OTbzcKsq1<k`4v94&525bHI+#U6Fc4&km$o z_kigU8!!VwAnDbG>(!fKItQ#!Z$;@9eS45<y#uaCz-dAc%mWihdiCIXb!LdpkpW5T ztO&iLYYS!_P(1>63KD^&R|l?_5;yC@+^oC8bq(01;5dO0NVXw-sRIikofW2Qz}_X~ zK0#P=6I>y>2JA^ekpCbAk{yC@9|^+j5QNzQQ4H3GqJx2v6(R*Li@`+*$`C(n;Qn(P zcs2%kh(DDjiZz8PiY=8rg*lZYixXCtr?8;#Sdn>YY$<FQ1Abg2nt(Y;z@5sT!jI+( z&QzWhbi27Q2D^EQ)QLGcz(=G`%*g?MB6VU;4hW?11v6+0+~W4hPlq)at31J@j6V74 zy2S;F$w=d)(4k427|@_)QEoMSTBlY=L0d;bHzqSLt)x;%!2mXv2_F9gcPPO_cSU>* z3=Al(dr&I?gvlGv(qz2FnUkNMn39rOQBVXL2ZDByAw58F9a_bY<TcQ!UKXgu0#XZZ zGxS$?RnIU)8TSCW2bT0eO$iVmV{8)KAcVA6KxU!Z3mUyZwKumkCl6H1f;yg%i~(vn zfCn_FA0CjYHY@`{;E_F)@Bj^Gfx-hcCW#0SW7Iw-6<t^a8Zf}(GEmE=N&q>gKtohz zpdeEK5uk<%6`i5Uc#9_|KOHho2TD7bqm7_uR+SL4iy*2&L(|2G-~#nUk}vWrUEx={ zz@Y?=S}MA;NCo71Ovizme^tV0jst~Q9Z0<zhyaC{UlFKzt|?dq8nr752MI@j2vD=R z2viV5x-X!%Xi*eMA{s=*fCzZ=vk2Vi1*M!KP$VHWKhau@2_S7CA_<hBrZJ+n7@0sV zMi9Zlz{8K)Vw9TzZ86HhnlEy&79*r_1gd1@kSZBO^M``QCZx#$vswYtVpM>&7$LGC zixrS8Mzl&GElOBpMhenml!CPwA+jLdQb@WH?M-kCQ5n`^RED$|m0>MLh%89AGLmj( zcwG!>Z^Ei@SxAdf7S>{f$bxjsBI!mF1*g#>P()#`mrsB@%&7Hp3R5a;7O1lZE*Ddn zQFtuKyfn5HR*d?XJ(VSe8_f*%RE`vMog5goDJPLSIWcr{rEmo^X!6|R_D!sS*KD@n zn$0({0x^AuUZ>?IR^Y77Kz$*aRAiuuncTz*oK+Z-A3#-D2PlVuvLB?#2F=F=c2@LM zbnrtWmq6V@Xj~9=xHW|lRGon%9yBM%<OiwLb3xf1vt$Al6jl7l?kz6O?E$$LRP`a; z3!Xokp-8LQ5VqvfTu^{wIuKH>BRddMu1^5@2fgIv##(Y>D=HDCB*+3t!vItSLweKM zAj3gKGbkjkf(L#eedz{<4@{t9kpV<-Ks&+`uwqF9Rw7EkN<;}z&V~?3*;@jwaDeHT zg%oSDuwo6V7(mjE=!`<-VFi;cq+pVT6-*FWkOS}*Eg*j;gNAq@X@-FTG(-VzM1h7W zK$9w<g+;K*loX~Cm^uaq2Gm7SwTz&lAx-A06mY)H*3HG2bF<-DHyYj&g)?GO@=J<i zbrhlvklLvbL0DrIdvUmn5i)}VD-cteQy5cOvOs<UyE}ymg~yD{OJf83lBI<QZ5<FB z8K$sen8KdQoWh6Z8c?x{%?%tayl8IVBu;k<mZFtNotT{?ZVZ2;x|Jn`8>8~zA*2T! z#yl9I!<)hz%%I8tOUWBKv%}}ckVWzJP*@ol7(i2JpRYit@@jBQSfwzcmYX<cLUBw4 zrl8H(qnQQjhk%nCGJ&pV0VtCpD*&@QnN!f_D^r+JN^}-K@G$1ffB*mg2bb-dEVnpI z^NI^gQ&X!_i$MLBTkL5$i6teedAC?f@(Z$8qR-6UV$3cEO*<(lC_rW>Azd#u<UmGD zOQMJ-rliaP6^fwY$R7<14}?XgTTil{Q8dwhiv4wAwM)Wk3ksK4FRI>Pw6K0j{Y7E( zE5hd2h3zj1+aF-MDC~Si*!jA!$0cEp6M`q4E(-f!5%#|j5O_s6=mJj=xH3d(jf30> zj?672MrI9>(FW=rV2^l=$if<>gd(e`oPmKslewr8RH1+@E2;*uYCs_f@*E-pKv7&p zOa$bX=745ki$P<=pa>8Vo$fu!djZo#|0(_p5|?K$%HE)~Fn>w@MG@2M!giO0?RFGh z6n45I>~vk&{gSZz3C0sf7lr+<2>YEVydoTUfhQ0g>_ynyARsq_BcO{w1k^C0r&>A$ z>n--&{Ib-P%-kY)(4s6t0IfeLs>KXzaHEHqur4mmT>{c>#lXM-3Tt7J>6Vi$X9O=$ zx+tuAMOgK^u<j*c-4#g}g$=I=8(tSSyCiJ3p>T)NMPb`3!nQjSuLwI_;Bf#4FiN@x z4V8g|brzOo3y2x65>R0VE)*CTN<h;lP<9q5TEOfY#sx@fz(QaGeL)ep%w=rhK%FN; zEwpNwP-TM|XtGQK)Kgu_j8ue!0s=Z711*d|t1zmpQHmX`^?)9vDTpYkU<)W#f##V& zDf&kP!-dd@>!C51LSrt(#$8BAycn8vB{T`Tj$$QS5vU7&i?z5UF**AdOHO8S$t}*z zlGLJ-{QR8aTU?3B$)&laIf*5yx7bSak}~s<7CI$B=g`4j>?%#7ox1|$ID1HndMYe2 z#d>bZQqL<Y7CQv@OYD+3puAIdkL(4HBsjXLl6*xa`J#Nv75S74X_*&=v#tndUEs+Y zO;(6id!WTpMJ=GL3aV4#wHi1f*$@{qpy3$Il(Y_1T(^P<aPOcE#DaHH;3)t+zN1CF zJ!?S5fO=VwI7F^mKv^4<BR)?9_v>pIQy5biQkYtq(wIP11UPr&T+M|jI#9DVBLmnR zrW6Ju&4IfJ)0|)iO=ds6BG5X^mCWEJGDYA4DbQjQjCC^L`OPYIB0>hVcwhr40zvcJ z4Ga%>csr6O7)@}TVAPS`<8_@!<`R$0jNm!p7kN~#@TgwkQN00HVK~7EO+~~-9<?hx zY8QCaZU~EXcwmMwXsQ$(!k~-@TI_|qW(*O6HH-`3p#TYW2#MZqtYN_3j$>k|VMG+v z=^!4ws9wa_$&|uW#l^rdkuiv&j{!B5(=h5%aF|1?Xi&IoLW?ct<irw4(*iV?e2Wvb z*daBypro=0v_3!+dD$qq7DUM#psD04qS7p6?tU96a-gj~P_bn>BXNHAtn3v^GxO)< zuP9z$xvFx9^bWy2(ibd44<sH*zhD`9qVPg+$jQ<RmZ1=IQ9ta8e%J-s@C%XA7lmW4 z2*+IDi2+BDA7tc{55516t?LfT21uiv;Ql)(1A^095y)GbjF4I%)TxD3DYtl#lVDLP z0|Nu7>Mdqv0$1#?zWoDEkq=CaoWYFH(K^mxM(B(iXE5Uq)jc{N7(lYP$dAknT%tYF z5F<XYF>r~3m_cyUg5ahF!A%Qd1eu17L^3Ui5pJ3zSiK|MOh-oWfFh?OBXmTO6Q%-W zE-D+zL`Q^)*<cg18KD!IoY{;kl0ka28F!fO0nJZx!c;&+kxa?PVv6e=&@3p(6wstT zXEx&w*F8`Xh<*r(%@k%%QOGPVGpFbZ)ipXF7??Rl5d>TdNR$g2y0MHipf<)bt_WQN znm*@@1^Wma2{(cfO%XU17EJ-Q))~Qrt(r{WGz1nxUR?<m025O|8Nv%vkAL8jV+Gkq zn4DVukpZOY3z+->AsrYQcqA^ch=W~$eOzM=mg!ftAzE^Vc}W>4#+<n2NM%XkM{@;7 zDksK3F}5)Y;&fsglORqf=7cRzDhrxhQ3teHQg|>%Gk6K=;l<Fy2c4u9cC9E#O$P0E z$j^fhY3~9LjUmZk8QRW=Y(UY541XDbhQSPV6bxeR5@4HMax!&OGmG<5i*$_)3@mli zGK-2!V0&ExiV~AcGLsW?6dVf*ax#+>OEUBGimhN<Ts$-iG!<+WVsi4+6`~Y$6=Kqg z5|gV9YpbJbV~R_2<Ev8?Vlwj-Txt~xG*UDbiZoI*VY@@{jHiRDN>KGe+QciUFHj|p z6d15z0*#s<0X339qtK9C0Wuv@12Zsy`a&T7XV54x>Y{Jt3LJST9MnMt)f^Bbs#qDo zO(KLy4O0qI0}CpTB!a0Q)aOiNO2JqdzmmmoC6gX_WClcoDr|7ot;q!LY!tPF{Dor@ z8f#eOmgayad5S@6!9Z)bMS7}dIL=6$<GF%yh1wd<i!z2A3^#;rvD{I3Kx|LtMPrW> zh9|<#SY8N^xDXkCB|PDxcfv*EgbUJ%7m`yi@~2(lPrJa81`brPyNW>FWR&hHC}=^L zyjgx+bH?CaH&zc8m*$=U1q$}5V^C)q>>5yw4H}Nd-d-Dio#i6X>;tY|jSjY4gR4J$ z3Do6;^@jsPt_Mb33XHfA8Fe8h_F`b%mB2V?f4B%o{|3~?s*=KO;{}lUur4jXNKf@# zlck(j6ihY*Zjaa$u_Jk7?3UOIE^%;lQ6c_{Li|PPge%es7n0BtB}!5pxsi{rORI|` zDzNuquYvN`d=Npf4=atwV9<bi5oqWUTy)T6k4TXT$d%{|ii<$Kn<`0cP6IFfzX8$& znk2>JFi^q<tz1T~5<q@|R0qf;$}S6(U3uVMG*Xp-Q$MIO1RIIkuLJ21W?0GWR|G1_ zie`hH4XVI!^qM8Gc^K49z5{A_g2JSM;Q<F{hguJ3KYthh4CXoP7daHJaDcYO+&~fM zxX7V+g+uWIhvE%>0qCl0Xpf5@y~hP!YeG`D3*-_=-wQOw4UPlIEGlROqX<Oo1v&U6 z+6ogE&<Ya}!2_K|rC@PLIwNcbHJuSQ1)I(Yn}baUbq82sB+^7`I;i^sS<4Jr0s=FI z)CI{fvtcu_>5P!6*mOqNTr5n*2L?vgbVlrMfT@9YK3UTtT|3rvSl15j2YjZGy2zKA zRS>c+hM83mvdEViv?3Hnz?}*c_`tx-DhP>XP~2kgtz4o_Z$$vD{SKNvMQy{grC?u_ zLX1xAy%b_}V(+D(_N`FeiGAjjPW=;teHuQDJ`H~ge=vil;4OaFypp2)f=XCJJ&_r< zH6JRWkc#N^;P2YN=la1N90N!PM+e+JD$htQN`-Y;VEg7l8^ytU)=M%{6>{>^bs>A~ z!CTrvLPe!{d6{|X3h?dinfZB%ISQ!|2g6MBh%Sgt09yh*Hvn5#N++W{5!ACX(1o0c zqLZDOtD9Pqn4@cCU}&jZnpa#}kXlrhS)7_eMBfOs5DVOZ1ug5F&QOD6__hS323&10 zAnj}dZN*JPn`}m(Y71s4Dqvt>Sji08b^@Bxz}3qD_qc?iaRrM+P;cuMs0jyJz6e_L z1Kx%^wRB4L0>=e~3(PKxYh4l7TH$z+U+)UP-USXlNcIOcC^0(^paE=<Pd;ma%K*^8 zGoqJ;qsm0{UoA7Lt{P_SlZoiFT%ZBfT9z6X>;t!`>nX4g+SV{4_X2BJKqjJA;tN3j zgT@kqLU&0mO9`mo2UUPridVy2!-B2PSTqwf^2A=03ThL8CW~(|r&bhz_Y<MT=}K0_ zu3vEA-(oDd#aL7f8e0Z!vxY9E26whF;<>mq_Z_G%t^luS0*$e!^>|+Ak-x+vzkvB7 zkIEGul@3PGz<OGb=M2XA+_ShBIA4^|xFVr(kw*h8)9>2l+Uefo-tXPzJwtGY*&N9Q zfiq<<@@QP)(YVf|bBRZ1Mes!)!z(<79gKHDJ%JgHGYV&zEik&suXcrB?E;4yIPHwK z@xg~p;OpRNpl4ECoxAU#G&3JW;A`H4yKrLI&HM_|49c3LaYNjcq9&Gb#NPM%4GLO< zkpr5(s1nCv=ueOlh}eO5E}%y|fXmv!)4eHL3aN=ed*_jst7GreiK2TM+@JdkDxyHW z3iSRBQa=Wze}mNTf%k7{(?10*1i{f=6G8V2sH+BQ9TkDj1%Tu%<hVm?6<{CKs$r~Q zz+Rixpe<j+I%&uRSt_Q<j5P8Hn!>~M0%+O{OA3Tc{joDLFcgCd5X9(X@%-9ZwJQQI z%IjZ|*S{cbutDh}zv&fz(+eD?m|g{W8=Oo*qn_x!aPTq{NM{(_f5b>BpzW?zlIWoe z-{i{;avW%68q{zRm>||ud4WR$>;^~|cclQ)U0k$9!Ju3T9(#cFZb3nWb?@zRPzD7N zpkoY+UlZ!*>ce`O`mnC5KCGvz59-)K2zbAXkyRhMT9}1Z{R0CFt2#tK3#&S4wJ-~- z`Udc}S(q$X30yZw6xP9p^)Cm$mkR20g14fA`kdgcs3^Tlxa&cpT+rbG(zl|T!8+1r z&`DfYGf?<K2)G@LtY*;gWn`6vZJU&YZJU$?>3|SOIv@gIDR4?F0>%DlPdJS&W#sgP zMVyQBi;K~Ur9@C^1nymeWfh>(WORx#d&jiuASZ+Tfu)<QQwZ%S=cg%v`qw4p`6zvB z_{n?NdeDQYTU@jfR6c{M9_T7VXcr0G6_x<U6EvET`@`al3=Bn}b%c-%j=ir7ufxmW zeO;m#Yhms4V(KQf?~A-x9DB=w$bK*jqSs!-lERAM(V|a`y?>vA7Dj1IDHv;1SF-u( zL8dW5gX*9OS8!B;2G>_2^{0!#OYT6PK<ZCV0ws*Kpw=d~-ZS>3QCylU4Qg@BgLk2m zCm2s~nqb_K(c^ucNAVJm;sRyJ5;Sm!xdTahhT?qfS=tMdFG^`$k<z-zqXkis*5ldl z+vVHo-{TMMiwiC=Um~?4aRb|$%!`WV7kMnN@K|2wvAx7&yCeA`kJA+%CrIzQa)#oJ z!1>X$qE`sbjGq&KK~i@`(M5ivEBr<mIE=svceJBTu%oSuwFtn~+g1UU3j{lKpvH2Q zG#-PMK*k_Cb)eQUbg+nFbjlNUW+-IsUJ-Z|uO6<z#NO`)4L%kTj3!VEze)z5$!e(a z1nSAa;t4bm2#UAQebip5i?rVdltf?_B50JOuQ28)gBez`zzW6vpdxN7h`{JqfqK|g zQdm6??uKhIGBA90h7@xgoE^#?#S@r1iaRuVxUX|aUgD6Pp*%<9B8T!74&@6R%Ag5H z^&YP491@o}BxVTD5yvv+NcS$eBv#LX`sD_oXvN+y2aVezMJuWOauoF-bHK3%8qdb8 z+fhfBQF+)#iNVndav!+DTgd|H)q`s>$T?Er#lPTV%y9JZain!fH{S#l;UI$`-F#5x z5<EX*R>acOD{7!^Ey6pJb`<VN+9AHB>Y|#{6*Z@evd&jzoi9kb97wvz?|Fsa^8$w_ zq}D;sCm=Q`AU=bdV3@uCl}vs`;8cpI_b-PvBH=>-79fWsh5*D7C*4AZ0E%{kG62|o z@DM5JIEbR%ATbaj0Mh-DhP`%UP?y{o)@wJ0^xBO#Kzr>FS+Ej#50iz}_`^u;wR^#q zHnV!cmP@mGfoJexBs`cHK@zaj$fRI>cPUuk9Wtj6>ZPL|>%hRs3XuY*Rd7NW?Yobx zzPq=NOJ-SWQF>}#aw@FXmna6C%J%kANP$Za>b^UwOQC0Dc>6>bD8v*b7A5B7q~<7$ zh;BT#2n9`RyMQWsqPy`OBdi-=!-70q09w$D+6bY1vYY&lebGKp1$_WS;O?ShjrQWw zTn|te9W*El+et>_F8U6|9d3IxFDg1;<Z->i<9eOP^AeBe3FV7Ceph(>M*HgEHZUqt z!+_%?b-b&db+JY`uD*I8DDxBS1VZ}icntOj83XEwf!hnCBP!q#6@1H+^>76y_P%;3 zD0~S<6Qr+>&*Wf`If!@y^*dl`ZV>m?i;jVcIDB1ntbPV}(ZfMLJ`U0k>etY}e~r~; zp#F6%$YDdSe_eD66qKhy1jc9yX!f^C2CIjmCr~GX{CpOq86z@4NfA#Mxad4c7r1|l zVJ~?0TMnze@cwTq$Y#(U3~&L3r_XyCWDkh21?jj5;(^>+1QNpD1!4lXh+u~)fi8B# zSUgJ3wnHAW7xEIL6Z=A5Vsv7ezD(f`X3*rl#UBj08xPi7sOkkz^MOS{t4@odR};b3 znG$p8Dr~W9W^xAj@~Aw8)QZI95{0z<qVmL|6y3DUoRU<~1z0)?Nr}nXU@`E5RFH*< z1qDU<iOCs|Td0uE)4({i6+TNv<MpR_C)$L;A(ff}3qMffya1F62{q2)MK|a;OVqu7 zptZ5+XO@5udevks0(lzC!KILOk?3wIF3kmv+ZBUGs6c~X3JU}mIA7$~xWcb-fkOkF zt46DRaJ7$j#UgsJ;%b*wf#RKDg%56*iD5Uh0%QWBst1*=u&RD^`UKnbi6)kC#NHaK z0|hO?$N{&;#Bmr}12O_0JCOQFlZT>ZSm4SLTvveyZ|{SuE)W6Q?pv&iHh9Yn+FAr6 zU~7lSUUJ3AstFoD)PxM)GO}ud25%WzH6eqyFj=q?q)|yt_=2Lru;dE7;|S!$bVhJV zRs;$+I@b0aDVQ}cC&m#0nA>)^Qdx-7iCNoo6R8ukw&#J?_JYB%Yj0uoRn<aBeGe1I zvbP0#%6c(ONiD`H>tG|G`%ZEbi%K%{is9Qz%s{8NL$2D@$xY2GPR@W!S?Hz|=p^SC z6{Th-!UT;BbW_vPGLth?^FTZQK}-J!eH%a&BUC}HfOb%6fvpt)YBj@3b<hG0P$~a; z5qPo{R9nNOFh>$<nQCxdY=^d@1p5jZ^tH7$OxSmeq%hVnu0dOo0$LpdKCb5_$oZN~ zMc@;pKwIoJS&BgC79cit++xYgFUr+~o`nWd0#=N=N(tOx!4h!ArMcapK`zjJF%1k) zc|<29&Je!HBYTBMwuA8ozX15wNAM}b{WV=RGn^qerY$gBZnns5h2sX}1!fnO&95k% zU*tExz+qklDq2UII0TzGT9_#qS0iT<C|MJ%N5PF830$U50GR==NJrxb96$I*p0u%s zB=&|5=*W8_mxxH>G<FI~3_+VZyu>zjZt)a@j)zHxTq%Y1P%E^C&vQ`22ShZ2GCz$P zK0=@~t}Q+=FtJ*6l=jqs84Hxb)QZwI5I&d(CO{1zp_Ukk9@vrCgR<cR3O7x$qE67A zTbya7dCA~Y9*aOd%v)?Fl?9o3>5%)mKszXJ34re&)`Q+Xte2Jt=~IHr@LNI<xzdu% zoMJuDZO-|5;0qdVvE?Uar6!kv@6iFDBUJ=CUK@N~6nHB<c%?Xa${9T90&a^Hf!tMu z8qvQvY#{fN*%f_bU|;~9WL7N4#K7=@nUN8+Yn@T>0)qeq-C&TpfQoJ~NMArj4;XkF z!0-lx<ppf$27}TCRP=!@n2}NN0|R!lqwFJC<_nmFs>)%KW0d{CfJscy_y`jH0wN&t zPK^8@rI^G7?T-xnjIv)q#0M~;qRJ@ofdNhgFe-zbg-OiN_{gBlDEI|Ld;k+Zj9QG6 z9~dx+3E3Y(qF+D+L_Ug9i%|;1L?>oggOo~vltQIQQYyj-$_dy>kSjnkUl>5-2MDPr X3f6(0oWcE(0VMMUOn$&1!PPhbRFa}C literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/tree.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/tree.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cfa02dffd8263f04ff8556087083f71ef8bccee GIT binary patch literal 26754 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 D%w81) literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/tree.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/tree.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b42efb7cbe328a1db42ec469766abe4c93796ba5 GIT binary patch literal 52834 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 DPbNQ0 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/vi.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/vi.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dc6ac96670b2c3dda14334e09a50e31c53a3ff5 GIT binary patch literal 13833 zcmd1j<>g{vU|<knUzDC6%)sy%#6iX^3=9ko3=E9L=NK3mQW#Pga~N_NqZk=MY^EHh zT;?d|T$U)7T-GR7uo!a=TNGOgLke>adoD*52ULtRmxGCcks+5WiW@A#lEahB8^sG| zv*z&S@<;JAGPpCOu%)oKFr=`ja%2fKGe-%!Go)~&aJDd{a6(0d+!<21Qn*_fQn;Za z!tM+yJSn^_3@N-&5fOKW6uuPx7KRjlsEDXLLyAC(U<*TvAXG#wg*li(Q|Kkgr<#nn zxD)g8@=Fp+GV}9_HJNX*_+%EB+~V*r00|`K++qzWEyzjr(`3BG>ylcKnwOHAmt5%_ z<fh4Zi`m!HFBxPCGG>Kv7(aV4FfgPtL@}l?L@}i>Mlq*|rHHpPq%ng1$s5H2@m&;a zD%%3~g$$frDH17?DMBg2Ev(IqQ5-2EDWWY5QJn1zEDTXx!3>&GxA+kD`?`gBR<&~} zC@3iSrY7boxMim1q$q?X7G;9{k(i_4nU|JYl$w{Es*sjnq>xxpP?TShnVVRWnp3He zoS2hbnv+<PnU}7Rn^=^dnU|PT3^pu3O(6yDNrjT4)YM`HtK`g*RI7yY#JqIfl2TnG z10w_7;?(5)yp#kzu%?&H3=9mnIC2v!;xkK9i*7Mz=9S!HD@rXXEy_z~f&>Sc1hGMw znSp`vvj_tNLkUAO!ve;I42%plj5Q4LOeqY(3@aJ^Rx;mWEiNrcExN@KAD@|*SrQ*# z#Ld9Ku#)K(OL1yW8id1mi!(kxIVZ8WI6i(Q!!JwyjQreGeNaRu<|XPS<s_zLrWWZZ z=jRsW>!uf!=;r39q~_=smlh-z=@*w2l_r-I>z8Hf6;u`pF)%O)GcYiG2Bmi{MlPl* zanzvJgE=Fa5$q8N0b+x6ID@<+#=yW(!;r<0#W<TGg|UVqi)l7P3e#McV1|{<epOr= zu+Xvn#i+TGxd@~j<h#7Y+*FwF7>ht*QY6m6zyKj6z~LGnUzA!<6dw=beFg=e7$X+< zLDcx&Vk=J0FG?-`B?L;w(Ixps$r*Yfsd>fuMX|S7aubWQe+fVYo$~W@AQHFON)n6G zQ%inH!4f@GpHF^XIz&nAFGX-RfJ#6Fbrc{bL3pvrps;|13<Co@0|NsnCxFAo4H`D- z3^k047;Bg&G6pg9G1Riuuq<FqVO+>q%UZ*n!c@voBwE87%uvF#fVqaHhDnm4h8aXI zWU6JWVXI+HV*-U`;$mh725_<iC4R@E^kOSG4<rKdzJf*_vfFeNP`H|?T0q*szEj9g zQz*$ON=;QL0f$(zLPBwTVo`E}LSkMDh+UkS1WofGJunPYq>+#ios?LToDpA~S(U1z zP@GyApOcygXT&BXXewmn=cE)XKwX)irjVGEqfn4vT%4JdlM2s!CAt}@i75&NiJ3*k zkUR#n3q&Ur$AcWAK*&C97MEnCB3Ta0>k#{NL5={G2_;3D1v#l`HiOa*JXjHlN7G6H zySHN#umn{|MydkXpptxr#IpR%6otg}^rF;saH*w`pQlien34i^LVk8?9-0dvsTA%8 zMCv5X4UP(s1PhAo^!%I@-QtqOyp+VE6zsvT;F6k_SejD;@~2;ZUMk32@DvvWF67XX zAWB+8OL|yRUPh`yT4qski9%+v0w{V)iV`#PKw*%RUtFw^Se9Cpn4X%VkW>kl%`44K zN-YApy#yRYItt|(naLRn<@tH)B??KY3PoTirKTukrYR&OK*G!x=5SE*LB^o?fRyDR z+Y_Pb9$aO>D+Z8V#TkhOsW>7UIhi36>&yTD|Nr;XWVywXn^u;2i@i8Mtt2<G;ufRZ zE#Bm!{Nm#H)Vz|S{DR7r?2uwl2~_N<fCx2EvB#E^pPpG#e2WwAj$16C0D+W@;4%_a zAl_n6%P%TVEJ~3EmESxJ3=AR?T#Ot{EQ}(I986VWXyrImF-lPds#!P~7#KiBRk0o; z149jS7DEhEElVwH3F88$62=A0HOvcGYFKMn7cwnmT*$b9HH8t(V_v|P!nBYvg-H^m zo~@R>hIs*d3UdwH0uHb^^FroYkX}wuAy>n^fHQ?<A)^Ds0<IL+6y_8rxGeKRMzAa^ zNVb-vhNFgU0a(uhZjf0eJT<J%j9{C=q7DpTHSBOT><c)ss$oR3iLr(W$^*HXrG`U< zp_ZwJv6i!hr-mVmx0%s}Ay&AStA=v{AIR;soHdL!oC`QpKyG6aVOYSQ!n%-AoS~Mp zu%?C+Y7)~z=3s`E?0!YsplAbChcCgzzyJULzXa7(MWE)Trob&$aQeB$3NDjxu@;vk zCTHJbEzd|TO1;IAms%d5pO;#Ei=`|xwfq)Kaeh(BEw0SGl+=p&w9K5GTU;O&kP`V8 zXK7w>VQFe=Rq8GFg4Cki(vs9$OnIrdSc?+#(o?|=gCbo}`e80E&DG=vC#_qo;8Gk! z6=x<DfzsG5E<{0niyc}}-(t!szQt5je2WcKL>cAZVl2GH7>}0VigXwl7;G3A7>Z>W z7#O%14H!ij<(Nd6R2Wql`ItnQSXlU&xEQ6F_?W7M(GnjhBdlbEgb548sh|W~#0v^N zP7uKlYUFSffwO`#NC4#4B2^FzlqrhTK`gLx4UkIiA~}#(x#Ht<^HWN5Qsd)q@x;d$ zmL}#vniaR$<Kt8EljGyTEu10+kZx;`4(`;v#H5_m`1GR0lp+(5FvwT8c%kj7<kXy; zcw~=@f|P)=TM@{aAP0OFU|?Y2U|?YsVC7(CV`gII`y-$Lmc`j1E&^pTO)2DNw2xCj zRR_2*^~ujKs8n!D&B;tnQwS)^FGz&e2~=vm7UyP`Way@57U!iF=^7arSm?s)zT`@1 zJq3;!v}nQEd@bSw1qmp=ia;Sz1ZqAOfrANNG=T#>7Nks)fq?<JDDrU%Al#xXk^*T3 z6>CMZAeKCc02>Y_z_9^}(Ik+#B32uqZ9)R+36zvj3Pj|#TahNncr8$BW4XnglT-lC zT}65zQGF0$03yIH0ux|ofl^c|NZb_UEKx)@0C^l+5e!OEpws~_f(u4S5xju6hJ&A> zgl{1eq#&+gTEGvgR%%#lSQfI>a)AqG0dT>rS<79+xj+zFFoTL^)`g5UToMemJSB_^ zglc#e2!rHmcxsr$85S}v5J_Q9VO_`s)xlN6Si=P>@E3@}3-NZ;LcGX~fq_9&tjG!! zYoH>c2vo!s*@C!sAi^F*IDiO85a9$OoI!*Oh;RiFpjQ4Z9#GMlngTAk<BLEk=@uub z_^wJV$}a|Iu3OwW`RVbn<^X3-etKd`N@_*HEfBM~G#AV)DN4*MF32xVEpi7rj2B#v z7kPlJ@dOdzauL+QF7gI(eL#dSi0}gu{-83BH5b%ME(!p#8FSG~@fZdMhBi<s4k~NW zOK~YC78U^}P&v-Wq{1WuD$4~?6EP?w1cF?KQI1D}8~`pCf<T!DQbZSpfJ8$<L>Pzw zbvO~laZxx(43ue#K+Y<P0CB;&2~2=X6>z=+nGIGO2~q*#5iD#4ob&UFOEODJL8BJn zQG*O{c}uNP15o2I8E!=hWXJ&03ZzMSx(4KPaCs_;?lbBYsT)C-fQwXYmQbNo{R~RU zpwR+sJ>rE7;QlaUDMOJ6w*K$}mW2$+ePT_f#CbIC6PM>hdj{YhadAOn9=uBo>Z3v{ zP~?sUsE-O(MyQiYxKj+W4y`8$vMHfB9&9%iy1|ehkZyiaN@|e;RXV@e`$QmTgD|Mq z1u7>MsL%^0q9=~uF{9mKP?SJ0C}JRqf!f_+zm=@up2IEn;>`5i{LB<^6Y7>iQf6La zQDr<zk2t<Ovm_%P+W%!u%gIkHDZ<sv+5)P>K)nbN2@Y_#R|3@SmB1()v9-ETI=)=6 zRu?m<<6FxH>-v^3E?}u)PGOW}0ChmYonIzUD`g?5^UJu95hN4CRLfq=0q*=VrZ6vL z0(W{jKwU>rmp6r_hBXD$qT#IJtYL?AjTdm$urJ_7>a>D8%nl5-AT=CtH5@q9FfL$E zf!GA<*7ByXfZ97Lj0;(6IHBEINb89Y+<FqKWvk&@z`u~87TgkAzya!p*MK^;0w6bv zGt_bwX4h~n;7wspVN78GcWT-Eia=diNYB<1R3Dgw2ylN^5L+|p7AL3=8=sSzomvEM zEZt(y%`Zz$$;>SRwUt0);svRRB}L%o61WKkYBLpqn^2(0D9Qxc0dDa?d#-H7@u1@G z78|6n1NU8v5bYjN<E98p;|IO91M1yf1*H^FpMr<ch>?d$4BTVof%aHAAU#%5jC2F) zvld}*>7;=i3vcNZ1%tTY1`C)#v|2#wmV-uTKpiD;myrdj%LtMs*oxstb{DAAm;i3X zP}*svcjM&?D2Tv~7nBSN>J<^3U?8?T_!DFYxb1?)4k|QVia{-GTum3yI2UL%4BUWW zE@dbZC#nI%lDL7k4Vbk2(jw#*OlnGcYJv`IL?6sZ&M$zsY0`^eQ(KT~0YZ*8X(00% zG#}U>ZPE;h5q@ypxROb)2vjrrX|h5(ub{zKaNDK`G&}?vv(HP%*?Rc{s*@nC7d}Mm zMI5cP*TdF$0Sy^}1|z{kMrA{&@d9mF@zyXdWUOIKV_L|#fG>p+JR<;VB!L<<d@0N+ zEGev@1`T*<hzm3{l)?;Zc7X?nSZhH|Cx$G@;E)-(c_RoaduzFBxE64L26<|@p@TzA zH9QN1Kyn~^Yj{A-wHlrj7D)!sP!ZU6uq>DbF@w8?v4(qrFsMnjkO|bFS|9>45!_6w zso`3{2XQONb-@fpIiOJxQEV-uqFhi_1aAu!<$<`Mc2H41h=tk+y2S+^A%e7@zzw1} zkRouaC?3R01QFn|PH_7OIwDj65-kJ~Xd^<nT1HW9x!`VNQ3^;CxTOLnz~d{R(HB`p z28LqLxGHipNr6d#iG@W7IwWMqD8nScR3(g_OmPni6@x58G?l<(qhM>n1fr<~QuiLD zwg^Okcm$h9V!^4oiFqZN$%p|e@G#FLa0`iA!#rTa^3xQGp_aj?N|P%gLp~_0L{du< zb99Xi3@uUDiO^&~$cd4Gp$OcjlE)qr)EgFZ2U!JfTH&^e3N5UnbWoOJdU%k9rVAaY z)g}VBr3enf5FX}%&Bs92A`Gsz4+;tjpvEG&jYw!f3wg8!w%h|Wt&dppf$CG;<otrf zqSQRl*eRA}7f`D~O;Un^OtRJKMTvPS_-qG{Qo+{JP~0v94X=Prq{6rt5vxCtg99=o z4GK&c9v%0Bg@l3vC}L<d?p2fls>*N;UwMIQTW|wV3TgOC4o682YX`EyR+%v{Fn~0} zrw(I4?LgKnh8X5rwpw<yK`d5K+Xrb7i@k<@A#)5<Ek`Y94eJ6naGQ&9A#*Kj4eJ7S z@DLG*W(Kdx-~vscEno*tvMu1K;aI>~!d1f#U6TP8bpQ=6fmTm|c?&o|YbUU)S-`!J zVF3@QMFv{+h-5FQ<p*&ExaC*F1s=)*4YR>pgJ3b{8WyN7ggTZQ##-(YF8E3gm0GqM z?ge}c8EPS|If#FlL>Owg7x04zxtKshXrOf`A`IdnQFf4vYFI$L1+ZZ;?!u-TZm3<1 zpkXmcYY*%A7gB2v+<XH!^w8RP94VQJ>G^q}MYW)X9gszxkU=j*%Z>*;*9RK$0@W-< zpy@u)%8lgw0uYs6lmZz912^zMlYh6EGKz08<rWu#1}2I?Q-9b-zj8qd4brUB0I$;k zuh#&xMBrm!cA%L)X&i|U&q!D~D2XGQcQ{AFK<aE585poFo=_?R$r5btiDJ4AG#=Ik zZlF;*9tJjKP`2_Wftp_6RvwnJfvV$Y(?K?Y8+kZwqCy+57&L}U*(e&y6d+4c1t<-I z*I|_~FfjNPMT7XbirrbD+yE*$MWi78Zt!9`S*&Rb-up%_bwSIQ;l1xmObiS);L>#g z1E_?oWvgM$VvJ!1O$yYqgO>A_FfCvyVOqdi!<xbjpGaU!VX5J$;Q*JxoV8rwQkOM_ zDFw7@4patnfXu34h4g0~KqVPy5d?VfegP+F`9cYI4F|Lg28%+~fO^0z3mF%1)^IK0 z!mefk&q4;!aQ{L^M(}du5~c-wNd0m46y_AR6xI}`g)Ft8QkfmZPGL)7UdU3*1fJ#q zxf8+%mBz^OppuxUhAE3bg*BbAhC7RK5oED5Zw)hs7+(zwh8RE0EwutA+%>R1{>EDN z8XibU)bL6$)Cz(^wMKA(AZP*u!UlzGjUZ_B72dN4%Yu9MLLhauypV+=DWIhxkkI9m zV5k)W>lZ>YO9*V15ZEkcaR#sn=w|VO-NUqyv4&rQp;j1dhA@&D!eBFm!Dg`FFoVB_ zr$#`6p;n|sq(%g+QUs(+f?)w9M41;d*RVA+Wr-sAwW1)KQkZH)B^YW%K`yHmtr1-y zR>HJEd?7=Y#6rdek_#DXL?jp%K>RFF!&t*x!za#A!!ORTKsbdpg>4~I4Yvrx0)`Ye z(2B+y0da;}p2GDtJPX(%u?~voU<OTgKTRe*$Se?OgbTs~=P>Ym5O^v`3cNmrz~~3A z`mm@Hlt-&TL>Y)cjCg<tJHW#p;Cd01^NNf>3t3o`a}sk4Zn36i=B4G|Vooh6zQvrA zpROqet~86PLB@b;%%U0)s}@9n21ahN<fP^mgV(}97R=OvWa>c#qSge}JyEQ=@yYoG zAS%5m1vFR!+5-~BS_WE61ERo^W$|FivUsp0TN0Q?uXRC#DSJWX3}_`0A0rPVa=i;0 zP!RwRs)#UyAQv+q6CaZqqZpGJBZ%f;(qR;0lw;HY4YWvNFPCr+w={x0hNzEm4!3~R z^?=Iz29O32PgDFBSA2Y0X-R1jXj=voD9qVPDho36(u+X5T#7(@9Ew028;U@yq;7G5 zSG4No<=tY+%Zn0*@$}M4^OB+ahqw@I@VMwLUhozaJ?IvcB2eVs5`u`8mSpA>>m}#s z=H}-?7EiJHf>(BeS5_8*R{Ru!Cd`UJLqp&OLlMZ;NI?%CPy!8R-Quu;EDE&)&0`jW dC;pg3m^c`D7=;*lKqRw}mr#I^hmfyW004{qbw>aI literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/__pycache__/vi.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/vi.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b5a62221a93d1af40f302d54c6da4bfff1818d4 GIT binary patch literal 28892 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 WJ2}H?j^{@PklYtA`2m9j$2|Z;=Cxe_ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/structs/chain.py b/tania_scripts/supar/structs/chain.py new file mode 100644 index 0000000..828caab --- /dev/null +++ b/tania_scripts/supar/structs/chain.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import List, Optional + +import torch +from supar.structs.dist import StructuredDistribution +from supar.structs.semiring import LogSemiring, Semiring +from torch.distributions.utils import lazy_property + + +class LinearChainCRF(StructuredDistribution): + r""" + Linear-chain CRFs :cite:`lafferty-etal-2001-crf`. + + Args: + scores (~torch.Tensor): ``[batch_size, seq_len, n_tags]``. + Log potentials. + trans (~torch.Tensor): ``[n_tags+1, n_tags+1]``. + Transition scores. + ``trans[-1, :-1]``/``trans[:-1, -1]`` represent oracle for start/end positions respectively. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking. Default: ``None``. + + Examples: + >>> from supar import LinearChainCRF + >>> batch_size, seq_len, n_tags = 2, 5, 4 + >>> lens = torch.tensor([3, 4]) + >>> value = torch.randint(n_tags, (batch_size, seq_len)) + >>> s1 = LinearChainCRF(torch.randn(batch_size, seq_len, n_tags), + torch.randn(n_tags+1, n_tags+1), + lens) + >>> s2 = LinearChainCRF(torch.randn(batch_size, seq_len, n_tags), + torch.randn(n_tags+1, n_tags+1), + lens) + >>> s1.max + tensor([4.4120, 8.9672], grad_fn=<MaxBackward0>) + >>> s1.argmax + tensor([[2, 0, 3, 0, 0], + [3, 3, 3, 2, 0]]) + >>> s1.log_partition + tensor([ 6.3486, 10.9106], grad_fn=<LogsumexpBackward>) + >>> s1.log_prob(value) + tensor([ -8.1515, -10.5572], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([3.4150, 3.6549], grad_fn=<SelectBackward>) + >>> s1.kl(s2) + tensor([4.0333, 4.3807], grad_fn=<SelectBackward>) + """ + + def __init__( + self, + scores: torch.Tensor, + trans: Optional[torch.Tensor] = None, + lens: Optional[torch.LongTensor] = None + ) -> LinearChainCRF: + super().__init__(scores, lens=lens) + + batch_size, seq_len, self.n_tags = scores.shape[:3] + self.lens = scores.new_full((batch_size,), seq_len).long() if lens is None else lens + self.mask = self.lens.unsqueeze(-1).gt(self.lens.new_tensor(range(seq_len))) + + self.trans = self.scores.new_full((self.n_tags+1, self.n_tags+1), LogSemiring.one) if trans is None else trans + + def __repr__(self): + return f"{self.__class__.__name__}(n_tags={self.n_tags})" + + def __add__(self, other): + return LinearChainCRF(torch.stack((self.scores, other.scores), -1), + torch.stack((self.trans, other.trans), -1), + self.lens) + + @lazy_property + def argmax(self): + return self.lens.new_zeros(self.mask.shape).masked_scatter_(self.mask, torch.where(self.backward(self.max.sum()))[2]) + + def topk(self, k: int) -> torch.LongTensor: + preds = torch.stack([torch.where(self.backward(i))[2] for i in self.kmax(k).sum(0)], -1) + return self.lens.new_zeros(*self.mask.shape, k).masked_scatter_(self.mask.unsqueeze(-1), preds) + + def score(self, value: torch.LongTensor) -> torch.Tensor: + scores, mask, value = self.scores.transpose(0, 1), self.mask.t(), value.t() + prev, succ = torch.cat((torch.full_like(value[:1], -1), value[:-1]), 0), value + # [seq_len, batch_size] + alpha = scores.gather(-1, value.unsqueeze(-1)).squeeze(-1) + # [batch_size] + alpha = LogSemiring.prod(LogSemiring.one_mask(LogSemiring.mul(alpha, self.trans[prev, succ]), ~mask), 0) + alpha = alpha + self.trans[value.gather(0, self.lens.unsqueeze(0) - 1).squeeze(0), torch.full_like(value[0], -1)] + return alpha + + def forward(self, semiring: Semiring) -> torch.Tensor: + # [seq_len, batch_size, n_tags, ...] + scores = semiring.convert(self.scores.transpose(0, 1)) + trans = semiring.convert(self.trans) + mask = self.mask.t() + + # [batch_size, n_tags] + alpha = semiring.mul(trans[-1, :-1], scores[0]) + for i in range(1, len(mask)): + alpha[mask[i]] = semiring.mul(semiring.dot(alpha.unsqueeze(2), trans[:-1, :-1], 1), scores[i])[mask[i]] + alpha = semiring.dot(alpha, trans[:-1, -1], 1) + return semiring.unconvert(alpha) + + +class SemiMarkovCRF(StructuredDistribution): + r""" + Semi-markov CRFs :cite:`sarawagi-cohen-2004-semicrf`. + + Args: + scores (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_tags]``. + Log potentials. + trans (~torch.Tensor): ``[n_tags, n_tags]``. + Transition scores. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking. Default: ``None``. + + Examples: + >>> from supar import SemiMarkovCRF + >>> batch_size, seq_len, n_tags = 2, 5, 4 + >>> lens = torch.tensor([3, 4]) + >>> value = torch.tensor([[[ 0, -1, -1, -1, -1], + [-1, -1, 2, -1, -1], + [-1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1]], + [[-1, 1, -1, -1, -1], + [-1, -1, 3, -1, -1], + [-1, -1, -1, 0, -1], + [-1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1]]]) + >>> s1 = SemiMarkovCRF(torch.randn(batch_size, seq_len, seq_len, n_tags), + torch.randn(n_tags, n_tags), + lens) + >>> s2 = SemiMarkovCRF(torch.randn(batch_size, seq_len, seq_len, n_tags), + torch.randn(n_tags, n_tags), + lens) + >>> s1.max + tensor([4.1971, 5.5746], grad_fn=<MaxBackward0>) + >>> s1.argmax + [[[0, 0, 1], [1, 1, 0], [2, 2, 1]], [[0, 0, 1], [1, 1, 3], [2, 2, 0], [3, 3, 1]]] + >>> s1.log_partition + tensor([6.3641, 8.4384], grad_fn=<LogsumexpBackward0>) + >>> s1.log_prob(value) + tensor([-5.7982, -7.4534], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([3.7520, 5.1609], grad_fn=<SelectBackward0>) + >>> s1.kl(s2) + tensor([3.5348, 2.2826], grad_fn=<SelectBackward0>) + """ + + def __init__( + self, + scores: torch.Tensor, + trans: Optional[torch.Tensor] = None, + lens: Optional[torch.LongTensor] = None + ) -> SemiMarkovCRF: + super().__init__(scores, lens=lens) + + batch_size, seq_len, _, self.n_tags = scores.shape[:4] + self.lens = scores.new_full((batch_size,), seq_len).long() if lens is None else lens + self.mask = self.lens.unsqueeze(-1).gt(self.lens.new_tensor(range(seq_len))) + self.mask = self.mask.unsqueeze(1) & self.mask.unsqueeze(2) + + self.trans = self.scores.new_full((self.n_tags, self.n_tags), LogSemiring.one) if trans is None else trans + + def __repr__(self): + return f"{self.__class__.__name__}(n_tags={self.n_tags})" + + def __add__(self, other): + return SemiMarkovCRF(torch.stack((self.scores, other.scores), -1), + torch.stack((self.trans, other.trans), -1), + self.lens) + + @lazy_property + def argmax(self) -> List: + return [torch.nonzero(i).tolist() for i in self.backward(self.max.sum())] + + def topk(self, k: int) -> List: + return list(zip(*[[torch.nonzero(j).tolist() for j in self.backward(i)] for i in self.kmax(k).sum(0)])) + + def score(self, value: torch.LongTensor) -> torch.Tensor: + mask = self.mask & value.ge(0) + lens = mask.sum((1, 2)) + indices = torch.where(mask) + batch_size, seq_len = lens.shape[0], lens.max() + span_mask = lens.unsqueeze(-1).gt(lens.new_tensor(range(seq_len))) + scores = self.scores.new_full((batch_size, seq_len), LogSemiring.one) + scores = scores.masked_scatter_(span_mask, self.scores[(*indices, value[indices])]) + scores = LogSemiring.prod(LogSemiring.one_mask(scores, ~span_mask), -1) + value = value.new_zeros(batch_size, seq_len).masked_scatter_(span_mask, value[indices]) + trans = LogSemiring.prod(LogSemiring.one_mask(self.trans[value[:, :-1], value[:, 1:]], ~span_mask[:, 1:]), -1) + return LogSemiring.mul(scores, trans) + + def forward(self, semiring: Semiring) -> torch.Tensor: + # [seq_len, seq_len, batch_size, n_tags, ...] + scores = semiring.convert(self.scores.movedim((1, 2), (0, 1))) + trans = semiring.convert(self.trans) + # [seq_len, batch_size, n_tags, ...] + alpha = semiring.zeros_like(scores[0]) + + alpha[0] = scores[0, 0] + # [batch_size, n_tags] + for t in range(1, len(scores)): + # [batch_size, n_tags, ...] + s = semiring.dot(semiring.dot(alpha[:t].unsqueeze(3), trans, 2), scores[1:t+1, t], 0) + alpha[t] = semiring.sum(torch.stack((s, scores[0, t])), 0) + return semiring.unconvert(semiring.sum(alpha[self.lens - 1, range(len(self.lens))], 1)) diff --git a/tania_scripts/supar/structs/dist.py b/tania_scripts/supar/structs/dist.py new file mode 100644 index 0000000..6ab594d --- /dev/null +++ b/tania_scripts/supar/structs/dist.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import Iterable, Union + +import torch +import torch.autograd as autograd +from supar.structs.semiring import (CrossEntropySemiring, EntropySemiring, + KLDivergenceSemiring, KMaxSemiring, + LogSemiring, MaxSemiring, SampledSemiring, + Semiring) +from torch.distributions.distribution import Distribution +from torch.distributions.utils import lazy_property + + +class StructuredDistribution(Distribution): + r""" + Base class for structured distribution :math:`p(y)` :cite:`eisner-2016-inside,goodman-1999-semiring,li-eisner-2009-first`. + + Args: + scores (torch.Tensor): + Log potentials, also for high-order cases. + + """ + + def __init__(self, scores: torch.Tensor, **kwargs) -> StructuredDistribution: + self.scores = scores.requires_grad_() if isinstance(scores, torch.Tensor) else [s.requires_grad_() for s in scores] + self.kwargs = kwargs + + def __repr__(self): + return f"{self.__class__.__name__}()" + + def __add__(self, other: 'StructuredDistribution') -> StructuredDistribution: + return self.__class__(torch.stack((self.scores, other.scores), -1), lens=self.lens) + + @lazy_property + def log_partition(self): + r""" + Computes the log partition function of the distribution :math:`p(y)`. + """ + + return self.forward(LogSemiring) + + @lazy_property + def marginals(self): + r""" + Computes marginal probabilities of the distribution :math:`p(y)`. + """ + + return self.backward(self.log_partition.sum()) + + @lazy_property + def max(self): + r""" + Computes the max score of the distribution :math:`p(y)`. + """ + + return self.forward(MaxSemiring) + + @lazy_property + def argmax(self): + r""" + Computes :math:`\arg\max_y p(y)` of the distribution :math:`p(y)`. + """ + + return self.backward(self.max.sum()) + + @lazy_property + def mode(self): + return self.argmax + + def kmax(self, k: int) -> torch.Tensor: + r""" + Computes the k-max of the distribution :math:`p(y)`. + """ + + return self.forward(KMaxSemiring(k)) + + def topk(self, k: int) -> Union[torch.Tensor, Iterable]: + r""" + Computes the k-argmax of the distribution :math:`p(y)`. + """ + raise NotImplementedError + + def sample(self): + r""" + Obtains a structured sample from the distribution :math:`y \sim p(y)`. + TODO: multi-sampling. + """ + + return self.backward(self.forward(SampledSemiring).sum()).detach() + + @lazy_property + def entropy(self): + r""" + Computes entropy :math:`H[p]` of the distribution :math:`p(y)`. + """ + + return self.forward(EntropySemiring) + + def cross_entropy(self, other: 'StructuredDistribution') -> torch.Tensor: + r""" + Computes cross-entropy :math:`H[p,q]` of self and another distribution. + + Args: + other (~supar.structs.dist.StructuredDistribution): Comparison distribution. + """ + + return (self + other).forward(CrossEntropySemiring) + + def kl(self, other: 'StructuredDistribution') -> torch.Tensor: + r""" + Computes KL-divergence :math:`KL[p \parallel q]=H[p,q]-H[p]` of self and another distribution. + + Args: + other (~supar.structs.dist.StructuredDistribution): Comparison distribution. + """ + + return (self + other).forward(KLDivergenceSemiring) + + def log_prob(self, value: torch.LongTensor, *args, **kwargs) -> torch.Tensor: + """ + Computes log probability over values :math:`p(y)`. + """ + + return self.score(value, *args, **kwargs) - self.log_partition + + def score(self, value: torch.LongTensor, *args, **kwargs) -> torch.Tensor: + raise NotImplementedError + + @torch.enable_grad() + def forward(self, semiring: Semiring) -> torch.Tensor: + raise NotImplementedError + + def backward(self, log_partition: torch.Tensor) -> Union[torch.Tensor, Iterable[torch.Tensor]]: + grads = autograd.grad(log_partition, self.scores, create_graph=True) + return grads[0] if isinstance(self.scores, torch.Tensor) else grads diff --git a/tania_scripts/supar/structs/fn.py b/tania_scripts/supar/structs/fn.py new file mode 100644 index 0000000..1a0af2a --- /dev/null +++ b/tania_scripts/supar/structs/fn.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- + +import operator +from typing import Iterable, Tuple, Union + +import torch +from supar.utils.common import INF, MIN +from supar.utils.fn import pad +from torch.autograd import Function + + +def tarjan(sequence: Iterable[int]) -> Iterable[int]: + r""" + Tarjan algorithm for finding Strongly Connected Components (SCCs) of a graph. + + Args: + sequence (list): + List of head indices. + + Yields: + A list of indices making up a SCC. All self-loops are ignored. + + Examples: + >>> next(tarjan([2, 5, 0, 3, 1])) # (1 -> 5 -> 2 -> 1) is a cycle + [2, 5, 1] + """ + + sequence = [-1] + sequence + # record the search order, i.e., the timestep + dfn = [-1] * len(sequence) + # record the the smallest timestep in a SCC + low = [-1] * len(sequence) + # push the visited into the stack + stack, onstack = [], [False] * len(sequence) + + def connect(i, timestep): + dfn[i] = low[i] = timestep[0] + timestep[0] += 1 + stack.append(i) + onstack[i] = True + + for j, head in enumerate(sequence): + if head != i: + continue + if dfn[j] == -1: + yield from connect(j, timestep) + low[i] = min(low[i], low[j]) + elif onstack[j]: + low[i] = min(low[i], dfn[j]) + + # a SCC is completed + if low[i] == dfn[i]: + cycle = [stack.pop()] + while cycle[-1] != i: + onstack[cycle[-1]] = False + cycle.append(stack.pop()) + onstack[i] = False + # ignore the self-loop + if len(cycle) > 1: + yield cycle + + timestep = [0] + for i in range(len(sequence)): + if dfn[i] == -1: + yield from connect(i, timestep) + + +def chuliu_edmonds(s: torch.Tensor) -> torch.Tensor: + r""" + ChuLiu/Edmonds algorithm for non-projective decoding :cite:`mcdonald-etal-2005-non`. + + Some code is borrowed from `tdozat's implementation`_. + Descriptions of notations and formulas can be found in :cite:`mcdonald-etal-2005-non`. + + Notes: + The algorithm does not guarantee to parse a single-root tree. + + Args: + s (~torch.Tensor): ``[seq_len, seq_len]``. + Scores of all dependent-head pairs. + + Returns: + ~torch.Tensor: + A tensor with shape ``[seq_len]`` for the resulting non-projective parse tree. + + .. _tdozat's implementation: + https://github.com/tdozat/Parser-v3 + """ + + s[0, 1:] = MIN + # prevent self-loops + s.diagonal()[1:].fill_(MIN) + # select heads with highest scores + tree = s.argmax(-1) + # return the cycle finded by tarjan algorithm lazily + cycle = next(tarjan(tree.tolist()[1:]), None) + # if the tree has no cycles, then it is a MST + if not cycle: + return tree + # indices of cycle in the original tree + cycle = torch.tensor(cycle) + # indices of noncycle in the original tree + noncycle = torch.ones(len(s)).index_fill_(0, cycle, 0) + noncycle = torch.where(noncycle.gt(0))[0] + + def contract(s): + # heads of cycle in original tree + cycle_heads = tree[cycle] + # scores of cycle in original tree + s_cycle = s[cycle, cycle_heads] + + # calculate the scores of cycle's potential dependents + # s(c->x) = max(s(x'->x)), x in noncycle and x' in cycle + s_dep = s[noncycle][:, cycle] + # find the best cycle head for each noncycle dependent + deps = s_dep.argmax(1) + # calculate the scores of cycle's potential heads + # s(x->c) = max(s(x'->x) - s(a(x')->x') + s(cycle)), x in noncycle and x' in cycle + # a(v) is the predecessor of v in cycle + # s(cycle) = sum(s(a(v)->v)) + s_head = s[cycle][:, noncycle] - s_cycle.view(-1, 1) + s_cycle.sum() + # find the best noncycle head for each cycle dependent + heads = s_head.argmax(0) + + contracted = torch.cat((noncycle, torch.tensor([-1]))) + # calculate the scores of contracted graph + s = s[contracted][:, contracted] + # set the contracted graph scores of cycle's potential dependents + s[:-1, -1] = s_dep[range(len(deps)), deps] + # set the contracted graph scores of cycle's potential heads + s[-1, :-1] = s_head[heads, range(len(heads))] + + return s, heads, deps + + # keep track of the endpoints of the edges into and out of cycle for reconstruction later + s, heads, deps = contract(s) + + # y is the contracted tree + y = chuliu_edmonds(s) + # exclude head of cycle from y + y, cycle_head = y[:-1], y[-1] + + # fix the subtree with no heads coming from the cycle + # len(y) denotes heads coming from the cycle + subtree = y < len(y) + # add the nodes to the new tree + tree[noncycle[subtree]] = noncycle[y[subtree]] + # fix the subtree with heads coming from the cycle + subtree = ~subtree + # add the nodes to the tree + tree[noncycle[subtree]] = cycle[deps[subtree]] + # fix the root of the cycle + cycle_root = heads[cycle_head] + # break the cycle and add the root of the cycle to the tree + tree[cycle[cycle_root]] = noncycle[cycle_head] + + return tree + + +def mst(scores: torch.Tensor, mask: torch.BoolTensor, multiroot: bool = False) -> torch.Tensor: + r""" + MST algorithm for decoding non-projective trees. + This is a wrapper for ChuLiu/Edmonds algorithm. + + The algorithm first runs ChuLiu/Edmonds to parse a tree and then have a check of multi-roots, + If ``multiroot=True`` and there indeed exist multi-roots, the algorithm seeks to find + best single-root trees by iterating all possible single-root trees parsed by ChuLiu/Edmonds. + Otherwise the resulting trees are directly taken as the final outputs. + + Args: + scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all dependent-head pairs. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask to avoid parsing over padding tokens. + The first column serving as pseudo words for roots should be ``False``. + multiroot (bool): + Ensures to parse a single-root tree If ``False``. + + Returns: + ~torch.Tensor: + A tensor with shape ``[batch_size, seq_len]`` for the resulting non-projective parse trees. + + Examples: + >>> scores = torch.tensor([[[-11.9436, -13.1464, -6.4789, -13.8917], + [-60.6957, -60.2866, -48.6457, -63.8125], + [-38.1747, -49.9296, -45.2733, -49.5571], + [-19.7504, -23.9066, -9.9139, -16.2088]]]) + >>> scores[:, 0, 1:] = MIN + >>> scores.diagonal(0, 1, 2)[1:].fill_(MIN) + >>> mask = torch.tensor([[False, True, True, True]]) + >>> mst(scores, mask) + tensor([[0, 2, 0, 2]]) + """ + + _, seq_len, _ = scores.shape + scores = scores.cpu().unbind() + + preds = [] + for i, length in enumerate(mask.sum(1).tolist()): + s = scores[i][:length+1, :length+1] + tree = chuliu_edmonds(s) + roots = torch.where(tree[1:].eq(0))[0] + 1 + if not multiroot and len(roots) > 1: + s_root = s[:, 0] + s_best = MIN + s = s.index_fill(1, torch.tensor(0), MIN) + for root in roots: + s[:, 0] = MIN + s[root, 0] = s_root[root] + t = chuliu_edmonds(s) + s_tree = s[1:].gather(1, t[1:].unsqueeze(-1)).sum() + if s_tree > s_best: + s_best, tree = s_tree, t + preds.append(tree) + + return pad(preds, total_length=seq_len).to(mask.device) + + +def levenshtein(x: Iterable, y: Iterable, align: bool = False) -> int: + """ + Calculates the Levenshtein edit-distance between two sequences. + The edit distance is the number of characters that need to be + substituted, inserted, or deleted, to transform `x` into `y`. + + For example, transforming "rain" to "shine" requires three steps, + consisting of two substitutions and one insertion: + "rain" -> "sain" -> "shin" -> "shine". + These operations could have been done in other orders, but at least three steps are needed. + + Allows specifying the cost of substitution edits (e.g., "a" -> "b"), + because sometimes it makes sense to assign greater penalties to substitutions. + + The code is revised from `nltk`_ and `wiki`_'s implementations. + + Args: + x/y (Iterable): + The sequences to be analysed. + align (bool): + Whether to return the alignments based on the minimum Levenshtein edit-distance. Default: ``False``. + + Examples: + >>> from supar.structs.utils.fn import levenshtein + >>> levenshtein('intention', 'execution', align=True) + (5, [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]) + + .. _nltk: + https://github.com/nltk/nltk/blob/develop/nltk/metrics/distance.py + .. _wiki: + https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance + """ + + # set up a 2-D array + len1, len2 = len(x), len(y) + lev = [list(range(len2 + 1))] + [[i] + [0] * len2 for i in range(1, len1 + 1)] + + # iterate over the array + # i and j start from 1 and not 0 to stay close to the wikipedia pseudo-code + # see https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance + for i in range(1, len1 + 1): + for j in range(1, len2 + 1): + # substitution + s = lev[i - 1][j - 1] + (x[i - 1] != y[j - 1]) + # deletion + a = lev[i - 1][j] + 1 + # insertion + b = lev[i][j - 1] + 1 + + lev[i][j] = min(s, a, b) + distance = lev[-1][-1] + if align: + i, j = len1, len2 + alignments = [(i, j)] + while (i, j) != (0, 0): + directions = [ + (i - 1, j - 1), # substitution + (i - 1, j), # deletion + (i, j - 1), # insertion + ] + direction_costs = ((lev[i][j] if (i >= 0 and j >= 0) else INF, (i, j)) for i, j in directions) + _, (i, j) = min(direction_costs, key=operator.itemgetter(0)) + alignments.append((i, j)) + alignments = list(reversed(alignments)) + return (distance, alignments) if align else distance + + +class Logsumexp(Function): + + r""" + Safer ``logsumexp`` to cure unnecessary NaN values that arise from inf arguments. + See discussions at http://github.com/pytorch/pytorch/issues/49724. + To be optimized with C++/Cuda extensions. + """ + + @staticmethod + @torch.cuda.amp.custom_fwd(cast_inputs=torch.float) + def forward(ctx, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + output = x.logsumexp(dim) + ctx.dim = dim + ctx.save_for_backward(x, output) + return output.clone() + + @staticmethod + @torch.cuda.amp.custom_bwd + def backward(ctx, g: torch.Tensor) -> Union[torch.Tensor, None]: + x, output, dim = *ctx.saved_tensors, ctx.dim + g, output = g.unsqueeze(dim), output.unsqueeze(dim) + mask = g.eq(0).expand_as(x) + grad = g * (x - output).exp() + return torch.where(mask, x.new_tensor(0.), grad), None + + +class Logaddexp(Function): + + @staticmethod + @torch.cuda.amp.custom_fwd(cast_inputs=torch.float) + def forward(ctx, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + output = torch.logaddexp(x, y) + ctx.save_for_backward(x, y, output) + return output.clone() + + @staticmethod + @torch.cuda.amp.custom_bwd + def backward(ctx, g: torch.Tensor) -> Union[torch.Tensor, torch.Tensor]: + x, y, output = ctx.saved_tensors + mask = g.eq(0) + grad_x, grad_y = (x - output).exp(), (y - output).exp() + grad_x = torch.where(mask, x.new_tensor(0.), grad_x) + grad_y = torch.where(mask, y.new_tensor(0.), grad_y) + return grad_x, grad_y + + +class SampledLogsumexp(Function): + + @staticmethod + @torch.cuda.amp.custom_fwd(cast_inputs=torch.float) + def forward(ctx, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + ctx.dim = dim + ctx.save_for_backward(x) + return x.logsumexp(dim=dim) + + @staticmethod + @torch.cuda.amp.custom_bwd + def backward(ctx, g: torch.Tensor) -> Union[torch.Tensor, None]: + from torch.distributions import OneHotCategorical + (x, ), dim = ctx.saved_tensors, ctx.dim + return g.unsqueeze(dim).mul(OneHotCategorical(logits=x.movedim(dim, -1)).sample().movedim(-1, dim)), None + + +class Sparsemax(Function): + + @staticmethod + @torch.cuda.amp.custom_fwd(cast_inputs=torch.float) + def forward(ctx, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + ctx.dim = dim + sorted_x, _ = x.sort(dim, True) + z = sorted_x.cumsum(dim) - 1 + k = x.new_tensor(range(1, sorted_x.size(dim) + 1)).view(-1, *[1] * (x.dim() - 1)).transpose(0, dim) + k = (k * sorted_x).gt(z).sum(dim, True) + tau = z.gather(dim, k - 1) / k + p = torch.clamp(x - tau, 0) + ctx.save_for_backward(k, p) + return p + + @staticmethod + @torch.cuda.amp.custom_bwd + def backward(ctx, g: torch.Tensor) -> Tuple[torch.Tensor, None]: + k, p, dim = *ctx.saved_tensors, ctx.dim + grad = g.masked_fill(p.eq(0), 0) + grad = torch.where(p.ne(0), grad - grad.sum(dim, True) / k, grad) + return grad, None + + +logsumexp = Logsumexp.apply + +logaddexp = Logaddexp.apply + +sampled_logsumexp = SampledLogsumexp.apply + +sparsemax = Sparsemax.apply diff --git a/tania_scripts/supar/structs/semiring.py b/tania_scripts/supar/structs/semiring.py new file mode 100644 index 0000000..9b66bee --- /dev/null +++ b/tania_scripts/supar/structs/semiring.py @@ -0,0 +1,406 @@ +# -*- coding: utf-8 -*- + +import itertools +from functools import reduce +from typing import Iterable + +import torch +from supar.structs.fn import sampled_logsumexp, sparsemax +from supar.utils.common import MIN + + +class Semiring(object): + r""" + Base semiring class :cite:`goodman-1999-semiring`. + + A semiring is defined by a tuple :math:`<K, \oplus, \otimes, \mathbf{0}, \mathbf{1}>`. + :math:`K` is a set of values; + :math:`\oplus` is commutative, associative and has an identity element `0`; + :math:`\otimes` is associative, has an identity element `1` and distributes over `+`. + """ + + zero = 0 + one = 1 + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x + y + + @classmethod + def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x * y + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.sum(dim) + + @classmethod + def prod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.prod(dim) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.cumsum(dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.cumprod(dim) + + @classmethod + def dot(cls, x: torch.Tensor, y: torch.Tensor, dim: int = -1) -> torch.Tensor: + return cls.sum(cls.mul(x, y), dim) + + @classmethod + def times(cls, *x: Iterable[torch.Tensor]) -> torch.Tensor: + return reduce(lambda i, j: cls.mul(i, j), x) + + @classmethod + def zero_(cls, x: torch.Tensor) -> torch.Tensor: + return x.fill_(cls.zero) + + @classmethod + def one_(cls, x: torch.Tensor) -> torch.Tensor: + return x.fill_(cls.one) + + @classmethod + def zero_mask(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + return x.masked_fill(mask, cls.zero) + + @classmethod + def zero_mask_(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + return x.masked_fill_(mask, cls.zero) + + @classmethod + def one_mask(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + return x.masked_fill(mask, cls.one) + + @classmethod + def one_mask_(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor: + return x.masked_fill_(mask, cls.one) + + @classmethod + def zeros_like(cls, x: torch.Tensor) -> torch.Tensor: + return x.new_full(x.shape, cls.zero) + + @classmethod + def ones_like(cls, x: torch.Tensor) -> torch.Tensor: + return x.new_full(x.shape, cls.one) + + @classmethod + def convert(cls, x: torch.Tensor) -> torch.Tensor: + return x + + @classmethod + def unconvert(cls, x: torch.Tensor) -> torch.Tensor: + return x + + +class LogSemiring(Semiring): + r""" + Log-space semiring :math:`<\mathrm{logsumexp}, +, -\infty, 0>`. + """ + + zero = MIN + one = 0 + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x.logaddexp(y) + + @classmethod + def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x + y + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.logsumexp(dim) + + @classmethod + def prod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.sum(dim) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.logcumsumexp(dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.cumsum(dim) + + +class MaxSemiring(LogSemiring): + r""" + Max semiring :math:`<\mathrm{max}, +, -\infty, 0>`. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x.max(y) + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.max(dim)[0] + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.cummax(dim) + + +def KMaxSemiring(k): + r""" + k-max semiring :math:`<\mathrm{kmax}, +, [-\infty, -\infty, \dots], [0, -\infty, \dots]>`. + """ + + class KMaxSemiring(LogSemiring): + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x.unsqueeze(-1).max(y.unsqueeze(-2)).flatten(-2).topk(k, -1)[0] + + @classmethod + def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return (x.unsqueeze(-1) + y.unsqueeze(-2)).flatten(-2).topk(k, -1)[0] + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.movedim(dim, -1).flatten(-2).topk(k, -1)[0] + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) + + @classmethod + def one_(cls, x: torch.Tensor) -> torch.Tensor: + x[..., :1].fill_(cls.one) + x[..., 1:].fill_(cls.zero) + return x + + @classmethod + def convert(cls, x: torch.Tensor) -> torch.Tensor: + return torch.cat((x.unsqueeze(-1), cls.zero_(x.new_empty(*x.shape, k - 1))), -1) + + return KMaxSemiring + + +class ExpectationSemiring(Semiring): + r""" + Expectation semiring :math:`<\oplus, +, [0, 0], [1, 0]>` :cite:`li-eisner-2009-first`. + + Practical Applications: :math:`H(p) = \log Z - \frac{1}{Z}\sum_{d \in D} p(d) r(d)`. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return x + y + + @classmethod + def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return torch.stack((x[..., 0] * y[..., 0], x[..., 0] * y[..., 1] + x[..., 1] * y[..., 0]), -1) + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return x.sum(dim) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) + + @classmethod + def zero_(cls, x: torch.Tensor) -> torch.Tensor: + return x.fill_(cls.zero) + + @classmethod + def one_(cls, x: torch.Tensor) -> torch.Tensor: + x[..., 0].fill_(cls.one) + x[..., 1].fill_(cls.zero) + return x + + +class EntropySemiring(LogSemiring): + r""" + Entropy expectation semiring :math:`<\oplus, +, [-\infty, 0], [0, 0]>`, + where :math:`\oplus` computes the log-values and the running distributional entropy :math:`H[p]` + :cite:`li-eisner-2009-first,hwa-2000-sample,kim-etal-2019-unsupervised`. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return cls.sum(torch.stack((x, y)), 0) + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + p = x[..., 0].logsumexp(dim) + r = x[..., 0] - p.unsqueeze(dim) + r = r.exp().mul((x[..., 1] - r)).sum(dim) + return torch.stack((p, r), -1) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) + + @classmethod + def zero_(cls, x: torch.Tensor) -> torch.Tensor: + x[..., 0].fill_(cls.zero) + x[..., 1].fill_(cls.one) + return x + + @classmethod + def one_(cls, x: torch.Tensor) -> torch.Tensor: + return x.fill_(cls.one) + + @classmethod + def convert(cls, x: torch.Tensor) -> torch.Tensor: + return torch.stack((x, cls.ones_like(x)), -1) + + @classmethod + def unconvert(cls, x: torch.Tensor) -> torch.Tensor: + return x[..., 1] + + +class CrossEntropySemiring(LogSemiring): + r""" + Cross Entropy expectation semiring :math:`<\oplus, +, [-\infty, -\infty, 0], [0, 0, 0]>`, + where :math:`\oplus` computes the log-values and the running distributional cross entropy :math:`H[p,q]` + of the two distributions :cite:`li-eisner-2009-first`. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return cls.sum(torch.stack((x, y)), 0) + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + p = x[..., :-1].logsumexp(dim) + r = x[..., :-1] - p.unsqueeze(dim) + r = r[..., 0].exp().mul((x[..., -1] - r[..., 1])).sum(dim) + return torch.cat((p, r.unsqueeze(-1)), -1) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) + + @classmethod + def zero_(cls, x: torch.Tensor) -> torch.Tensor: + x[..., :-1].fill_(cls.zero) + x[..., -1].fill_(cls.one) + return x + + @classmethod + def one_(cls, x: torch.Tensor) -> torch.Tensor: + return x.fill_(cls.one) + + @classmethod + def convert(cls, x: torch.Tensor) -> torch.Tensor: + return torch.cat((x, cls.one_(torch.empty_like(x[..., :1]))), -1) + + @classmethod + def unconvert(cls, x: torch.Tensor) -> torch.Tensor: + return x[..., -1] + + +class KLDivergenceSemiring(LogSemiring): + r""" + KL divergence expectation semiring :math:`<\oplus, +, [-\infty, -\infty, 0], [0, 0, 0]>`, + where :math:`\oplus` computes the log-values and the running distributional KL divergence :math:`KL[p \parallel q]` + of the two distributions :cite:`li-eisner-2009-first`. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return cls.sum(torch.stack((x, y)), 0) + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + p = x[..., :-1].logsumexp(dim) + r = x[..., :-1] - p.unsqueeze(dim) + r = r[..., 0].exp().mul((x[..., -1] - r[..., 1] + r[..., 0])).sum(dim) + return torch.cat((p, r.unsqueeze(-1)), -1) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) + + @classmethod + def zero_(cls, x: torch.Tensor) -> torch.Tensor: + x[..., :-1].fill_(cls.zero) + x[..., -1].fill_(cls.one) + return x + + @classmethod + def one_(cls, x: torch.Tensor) -> torch.Tensor: + return x.fill_(cls.one) + + @classmethod + def convert(cls, x: torch.Tensor) -> torch.Tensor: + return torch.cat((x, cls.one_(torch.empty_like(x[..., :1]))), -1) + + @classmethod + def unconvert(cls, x: torch.Tensor) -> torch.Tensor: + return x[..., -1] + + +class SampledSemiring(LogSemiring): + r""" + Sampling semiring :math:`<\mathrm{logsumexp}, +, -\infty, 0>`, + which is an exact forward-filtering, backward-sampling approach. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return cls.sum(torch.stack((x, y)), 0) + + @classmethod + def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return sampled_logsumexp(x, dim) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) + + +class SparsemaxSemiring(LogSemiring): + r""" + Sparsemax semiring :math:`<\mathrm{sparsemax}, +, -\infty, 0>` + :cite:`martins-etal-2016-sparsemax,mensch-etal-2018-dp,correia-etal-2020-efficient`. + """ + + @classmethod + def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + return cls.sum(torch.stack((x, y)), 0) + + @staticmethod + def sum(x: torch.Tensor, dim: int = -1) -> torch.Tensor: + p = sparsemax(x, dim) + return x.mul(p).sum(dim) - p.norm(p=2, dim=dim) + + @classmethod + def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim) + + @classmethod + def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor: + return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim) diff --git a/tania_scripts/supar/structs/tree.py b/tania_scripts/supar/structs/tree.py new file mode 100644 index 0000000..e1cc555 --- /dev/null +++ b/tania_scripts/supar/structs/tree.py @@ -0,0 +1,635 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import List, Optional, Tuple, Union + +import torch +import torch.nn as nn +from supar.structs.dist import StructuredDistribution +from supar.structs.fn import mst +from supar.structs.semiring import LogSemiring, Semiring +from supar.utils.fn import diagonal_stripe, expanded_stripe, stripe +from torch.distributions.utils import lazy_property + + +class MatrixTree(StructuredDistribution): + r""" + MatrixTree for calculating partitions and marginals of non-projective dependency trees in :math:`O(n^3)` + by an adaptation of Kirchhoff's MatrixTree Theorem :cite:`koo-etal-2007-structured`. + + Args: + scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible dependent-head pairs. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking, regardless of root positions. Default: ``None``. + multiroot (bool): + If ``False``, requires the tree to contain only a single root. Default: ``True``. + + Examples: + >>> from supar import MatrixTree + >>> batch_size, seq_len = 2, 5 + >>> lens = torch.tensor([3, 4]) + >>> arcs = torch.tensor([[0, 2, 0, 4, 2], [0, 3, 1, 0, 3]]) + >>> s1 = MatrixTree(torch.randn(batch_size, seq_len, seq_len), lens) + >>> s2 = MatrixTree(torch.randn(batch_size, seq_len, seq_len), lens) + >>> s1.max + tensor([0.7174, 3.7910], grad_fn=<SumBackward1>) + >>> s1.argmax + tensor([[0, 0, 1, 1, 0], + [0, 4, 1, 0, 3]]) + >>> s1.log_partition + tensor([2.0229, 6.0558], grad_fn=<CopyBackwards>) + >>> s1.log_prob(arcs) + tensor([-3.2209, -2.5756], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([1.9711, 3.4497], grad_fn=<SubBackward0>) + >>> s1.kl(s2) + tensor([1.3354, 2.6914], grad_fn=<AddBackward0>) + """ + + def __init__( + self, + scores: torch.Tensor, + lens: Optional[torch.LongTensor] = None, + multiroot: bool = False + ) -> MatrixTree: + super().__init__(scores) + + batch_size, seq_len, *_ = scores.shape + self.lens = scores.new_full((batch_size,), seq_len-1).long() if lens is None else lens + self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len))) + self.mask = self.mask.index_fill(1, self.lens.new_tensor(0), 0) + + self.multiroot = multiroot + + def __repr__(self): + return f"{self.__class__.__name__}(multiroot={self.multiroot})" + + def __add__(self, other): + return MatrixTree(torch.stack((self.scores, other.scores)), self.lens, self.multiroot) + + @lazy_property + def max(self): + arcs = self.argmax + return LogSemiring.prod(LogSemiring.one_mask(self.scores.gather(-1, arcs.unsqueeze(-1)).squeeze(-1), ~self.mask), -1) + + @lazy_property + def argmax(self): + with torch.no_grad(): + return mst(self.scores, self.mask, self.multiroot) + + def kmax(self, k: int) -> torch.Tensor: + # TODO: Camerini algorithm + raise NotImplementedError + + def sample(self): + raise NotImplementedError + + @lazy_property + def entropy(self): + return self.log_partition - (self.marginals * self.scores).sum((-1, -2)) + + def cross_entropy(self, other: MatrixTree) -> torch.Tensor: + return other.log_partition - (self.marginals * other.scores).sum((-1, -2)) + + def kl(self, other: MatrixTree) -> torch.Tensor: + return other.log_partition - self.log_partition + (self.marginals * (self.scores - other.scores)).sum((-1, -2)) + + def score(self, value: torch.LongTensor, partial: bool = False) -> torch.Tensor: + arcs = value + if partial: + mask, lens = self.mask, self.lens + mask = mask.index_fill(1, self.lens.new_tensor(0), 1) + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + arcs = arcs.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1) + arcs = arcs.eq(lens.new_tensor(range(mask.shape[1]))) | arcs.lt(0) + scores = LogSemiring.zero_mask(self.scores, ~(arcs & mask)) + return self.__class__(scores, lens, **self.kwargs).log_partition + return LogSemiring.prod(LogSemiring.one_mask(self.scores.gather(-1, arcs.unsqueeze(-1)).squeeze(-1), ~self.mask), -1) + + @torch.enable_grad() + def forward(self, semiring: Semiring) -> torch.Tensor: + s_arc = self.scores + batch_size, *_ = s_arc.shape + mask, lens = self.mask.index_fill(1, self.lens.new_tensor(0), 1), self.lens + # double precision to prevent overflows + s_arc = semiring.zero_mask(s_arc, ~(mask.unsqueeze(-1) & mask.unsqueeze(-2))).double() + + # A(i, j) = exp(s(i, j)) + m = s_arc.view(batch_size, -1).max(-1)[0] + A = torch.exp(s_arc - m.view(-1, 1, 1)) + + # Weighted degree matrix + # D(i, j) = sum_j(A(i, j)), if h == m + # 0, otherwise + D = torch.zeros_like(A) + D.diagonal(0, 1, 2).copy_(A.sum(-1)) + # Laplacian matrix + # L(i, j) = D(i, j) - A(i, j) + L = D - A + if not self.multiroot: + L.diagonal(0, 1, 2).add_(-A[..., 0]) + L[..., 1] = A[..., 0] + L = nn.init.eye_(torch.empty_like(A[0])).repeat(batch_size, 1, 1).masked_scatter_(mask.unsqueeze(-1), L[mask]) + L = L + nn.init.eye_(torch.empty_like(A[0])) * torch.finfo().tiny + # Z = L^(0, 0), the minor of L w.r.t row 0 and column 0 + return (L[:, 1:, 1:].logdet() + m * lens).float() + + +class DependencyCRF(StructuredDistribution): + r""" + First-order TreeCRF for projective dependency trees :cite:`eisner-2000-bilexical,zhang-etal-2020-efficient`. + + Args: + scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all possible dependent-head pairs. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking, regardless of root positions. Default: ``None``. + multiroot (bool): + If ``False``, requires the tree to contain only a single root. Default: ``True``. + + Examples: + >>> from supar import DependencyCRF + >>> batch_size, seq_len = 2, 5 + >>> lens = torch.tensor([3, 4]) + >>> arcs = torch.tensor([[0, 2, 0, 4, 2], [0, 3, 1, 0, 3]]) + >>> s1 = DependencyCRF(torch.randn(batch_size, seq_len, seq_len), lens) + >>> s2 = DependencyCRF(torch.randn(batch_size, seq_len, seq_len), lens) + >>> s1.max + tensor([3.6346, 1.7194], grad_fn=<IndexBackward>) + >>> s1.argmax + tensor([[0, 2, 3, 0, 0], + [0, 0, 3, 1, 1]]) + >>> s1.log_partition + tensor([4.1007, 3.3383], grad_fn=<IndexBackward>) + >>> s1.log_prob(arcs) + tensor([-1.3866, -5.5352], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([0.9979, 2.6056], grad_fn=<IndexBackward>) + >>> s1.kl(s2) + tensor([1.6631, 2.6558], grad_fn=<IndexBackward>) + """ + + def __init__( + self, + scores: torch.Tensor, + lens: Optional[torch.LongTensor] = None, + multiroot: bool = False + ) -> DependencyCRF: + super().__init__(scores) + + batch_size, seq_len, *_ = scores.shape + self.lens = scores.new_full((batch_size,), seq_len-1).long() if lens is None else lens + self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len))) + self.mask = self.mask.index_fill(1, self.lens.new_tensor(0), 0) + + self.multiroot = multiroot + + def __repr__(self): + return f"{self.__class__.__name__}(multiroot={self.multiroot})" + + def __add__(self, other): + return DependencyCRF(torch.stack((self.scores, other.scores), -1), self.lens, self.multiroot) + + @lazy_property + def argmax(self): + return self.lens.new_zeros(self.mask.shape).masked_scatter_(self.mask, torch.where(self.backward(self.max.sum()))[2]) + + def topk(self, k: int) -> torch.LongTensor: + preds = torch.stack([torch.where(self.backward(i))[2] for i in self.kmax(k).sum(0)], -1) + return self.lens.new_zeros(*self.mask.shape, k).masked_scatter_(self.mask.unsqueeze(-1), preds) + + def score(self, value: torch.Tensor, partial: bool = False) -> torch.Tensor: + arcs = value + if partial: + mask, lens = self.mask, self.lens + mask = mask.index_fill(1, self.lens.new_tensor(0), 1) + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + arcs = arcs.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1) + arcs = arcs.eq(lens.new_tensor(range(mask.shape[1]))) | arcs.lt(0) + scores = LogSemiring.zero_mask(self.scores, ~(arcs & mask)) + return self.__class__(scores, lens, **self.kwargs).log_partition + return LogSemiring.prod(LogSemiring.one_mask(self.scores.gather(-1, arcs.unsqueeze(-1)).squeeze(-1), ~self.mask), -1) + + def forward(self, semiring: Semiring) -> torch.Tensor: + s_arc = self.scores + batch_size, seq_len = s_arc.shape[:2] + # [seq_len, seq_len, batch_size, ...], (h->m) + s_arc = semiring.convert(s_arc.movedim((1, 2), (1, 0))) + s_i = semiring.zeros_like(s_arc) + s_c = semiring.zeros_like(s_arc) + semiring.one_(s_c.diagonal().movedim(-1, 1)) + + for w in range(1, seq_len): + n = seq_len - w + + # [n, batch_size, ...] + il = ir = semiring.dot(stripe(s_c, n, w), stripe(s_c, n, w, (w, 1)), 1) + # INCOMPLETE-L: I(j->i) = <C(i->r), C(j->r+1)> * s(j->i), i <= r < j + # fill the w-th diagonal of the lower triangular part of s_i with I(j->i) of n spans + s_i.diagonal(-w).copy_(semiring.mul(il, s_arc.diagonal(-w).movedim(-1, 0)).movedim(0, -1)) + # INCOMPLETE-R: I(i->j) = <C(i->r), C(j->r+1)> * s(i->j), i <= r < j + # fill the w-th diagonal of the upper triangular part of s_i with I(i->j) of n spans + s_i.diagonal(w).copy_(semiring.mul(ir, s_arc.diagonal(w).movedim(-1, 0)).movedim(0, -1)) + + # [n, batch_size, ...] + # COMPLETE-L: C(j->i) = <C(r->i), I(j->r)>, i <= r < j + cl = semiring.dot(stripe(s_c, n, w, (0, 0), 0), stripe(s_i, n, w, (w, 0)), 1) + s_c.diagonal(-w).copy_(cl.movedim(0, -1)) + # COMPLETE-R: C(i->j) = <I(i->r), C(r->j)>, i < r <= j + cr = semiring.dot(stripe(s_i, n, w, (0, 1)), stripe(s_c, n, w, (1, w), 0), 1) + s_c.diagonal(w).copy_(cr.movedim(0, -1)) + if not self.multiroot: + s_c[0, w][self.lens.ne(w)] = semiring.zero + return semiring.unconvert(s_c)[0][self.lens, range(batch_size)] + + +class Dependency2oCRF(StructuredDistribution): + r""" + Second-order TreeCRF for projective dependency trees :cite:`mcdonald-pereira-2006-online,zhang-etal-2020-efficient`. + + Args: + scores (tuple(~torch.Tensor, ~torch.Tensor)): + Scores of all possible dependent-head pairs (``[batch_size, seq_len, seq_len]``) and + dependent-head-sibling triples ``[batch_size, seq_len, seq_len, seq_len]``. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking, regardless of root positions. Default: ``None``. + multiroot (bool): + If ``False``, requires the tree to contain only a single root. Default: ``True``. + + Examples: + >>> from supar import Dependency2oCRF + >>> batch_size, seq_len = 2, 5 + >>> lens = torch.tensor([3, 4]) + >>> arcs = torch.tensor([[0, 2, 0, 4, 2], [0, 3, 1, 0, 3]]) + >>> sibs = torch.tensor([CoNLL.get_sibs(i) for i in arcs[:, 1:].tolist()]) + >>> s1 = Dependency2oCRF((torch.randn(batch_size, seq_len, seq_len), + torch.randn(batch_size, seq_len, seq_len, seq_len)), + lens) + >>> s2 = Dependency2oCRF((torch.randn(batch_size, seq_len, seq_len), + torch.randn(batch_size, seq_len, seq_len, seq_len)), + lens) + >>> s1.max + tensor([0.7574, 3.3634], grad_fn=<IndexBackward>) + >>> s1.argmax + tensor([[0, 3, 3, 0, 0], + [0, 4, 4, 4, 0]]) + >>> s1.log_partition + tensor([1.9906, 4.3599], grad_fn=<IndexBackward>) + >>> s1.log_prob((arcs, sibs)) + tensor([-0.6975, -6.2845], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([1.6436, 2.1717], grad_fn=<IndexBackward>) + >>> s1.kl(s2) + tensor([0.4929, 2.0759], grad_fn=<IndexBackward>) + """ + + def __init__( + self, + scores: Tuple[torch.Tensor, torch.Tensor], + lens: Optional[torch.LongTensor] = None, + multiroot: bool = False + ) -> Dependency2oCRF: + super().__init__(scores) + + batch_size, seq_len, *_ = scores[0].shape + self.lens = scores[0].new_full((batch_size,), seq_len-1).long() if lens is None else lens + self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len))) + self.mask = self.mask.index_fill(1, self.lens.new_tensor(0), 0) + + self.multiroot = multiroot + + def __repr__(self): + return f"{self.__class__.__name__}(multiroot={self.multiroot})" + + def __add__(self, other): + return Dependency2oCRF([torch.stack((i, j), -1) for i, j in zip(self.scores, other.scores)], self.lens, self.multiroot) + + @lazy_property + def argmax(self): + return self.lens.new_zeros(self.mask.shape).masked_scatter_(self.mask, + torch.where(self.backward(self.max.sum())[0])[2]) + + def topk(self, k: int) -> torch.LongTensor: + preds = torch.stack([torch.where(self.backward(i)[0])[2] for i in self.kmax(k).sum(0)], -1) + return self.lens.new_zeros(*self.mask.shape, k).masked_scatter_(self.mask.unsqueeze(-1), preds) + + def score(self, value: Tuple[torch.LongTensor, torch.LongTensor], partial: bool = False) -> torch.Tensor: + arcs, sibs = value + if partial: + mask, lens = self.mask, self.lens + mask = mask.index_fill(1, self.lens.new_tensor(0), 1) + mask = mask.unsqueeze(1) & mask.unsqueeze(2) + arcs = arcs.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1) + arcs = arcs.eq(lens.new_tensor(range(mask.shape[1]))) | arcs.lt(0) + s_arc, s_sib = LogSemiring.zero_mask(self.scores[0], ~(arcs & mask)), self.scores[1] + return self.__class__((s_arc, s_sib), lens, **self.kwargs).log_partition + s_arc = self.scores[0].gather(-1, arcs.unsqueeze(-1)).squeeze(-1) + s_arc = LogSemiring.prod(LogSemiring.one_mask(s_arc, ~self.mask), -1) + s_sib = self.scores[1].gather(-1, sibs.unsqueeze(-1)).squeeze(-1) + s_sib = LogSemiring.prod(LogSemiring.one_mask(s_sib, ~sibs.gt(0)), (-1, -2)) + return LogSemiring.mul(s_arc, s_sib) + + @torch.enable_grad() + def forward(self, semiring: Semiring) -> torch.Tensor: + s_arc, s_sib = self.scores + batch_size, seq_len = s_arc.shape[:2] + # [seq_len, seq_len, batch_size, ...], (h->m) + s_arc = semiring.convert(s_arc.movedim((1, 2), (1, 0))) + # [seq_len, seq_len, seq_len, batch_size, ...], (h->m->s) + s_sib = semiring.convert(s_sib.movedim((0, 2), (3, 0))) + s_i = semiring.zeros_like(s_arc) + s_s = semiring.zeros_like(s_arc) + s_c = semiring.zeros_like(s_arc) + semiring.one_(s_c.diagonal().movedim(-1, 1)) + + for w in range(1, seq_len): + n = seq_len - w + + # INCOMPLETE-L: I(j->i) = <I(j->r), S(j->r, i)> * s(j->i), i < r < j + # <C(j->j), C(i->j-1)> * s(j->i), otherwise + # [n, w, batch_size, ...] + il = semiring.times(stripe(s_i, n, w, (w, 1)), + stripe(s_s, n, w, (1, 0), 0), + stripe(s_sib[range(w, n+w), range(n), :], n, w, (0, 1))) + il[:, -1] = semiring.mul(stripe(s_c, n, 1, (w, w)), stripe(s_c, n, 1, (0, w - 1))).squeeze(1) + il = semiring.sum(il, 1) + s_i.diagonal(-w).copy_(semiring.mul(il, s_arc.diagonal(-w).movedim(-1, 0)).movedim(0, -1)) + # INCOMPLETE-R: I(i->j) = <I(i->r), S(i->r, j)> * s(i->j), i < r < j + # <C(i->i), C(j->i+1)> * s(i->j), otherwise + # [n, w, batch_size, ...] + ir = semiring.times(stripe(s_i, n, w), + stripe(s_s, n, w, (0, w), 0), + stripe(s_sib[range(n), range(w, n+w), :], n, w)) + if not self.multiroot: + semiring.zero_(ir[0]) + ir[:, 0] = semiring.mul(stripe(s_c, n, 1), stripe(s_c, n, 1, (w, 1))).squeeze(1) + ir = semiring.sum(ir, 1) + s_i.diagonal(w).copy_(semiring.mul(ir, s_arc.diagonal(w).movedim(-1, 0)).movedim(0, -1)) + + # [batch_size, ..., n] + sl = sr = semiring.dot(stripe(s_c, n, w), stripe(s_c, n, w, (w, 1)), 1).movedim(0, -1) + # SIB: S(j, i) = <C(i->r), C(j->r+1)>, i <= r < j + s_s.diagonal(-w).copy_(sl) + # SIB: S(i, j) = <C(i->r), C(j->r+1)>, i <= r < j + s_s.diagonal(w).copy_(sr) + + # [n, batch_size, ...] + # COMPLETE-L: C(j->i) = <C(r->i), I(j->r)>, i <= r < j + cl = semiring.dot(stripe(s_c, n, w, (0, 0), 0), stripe(s_i, n, w, (w, 0)), 1) + s_c.diagonal(-w).copy_(cl.movedim(0, -1)) + # COMPLETE-R: C(i->j) = <I(i->r), C(r->j)>, i < r <= j + cr = semiring.dot(stripe(s_i, n, w, (0, 1)), stripe(s_c, n, w, (1, w), 0), 1) + s_c.diagonal(w).copy_(cr.movedim(0, -1)) + return semiring.unconvert(s_c)[0][self.lens, range(batch_size)] + + +class ConstituencyCRF(StructuredDistribution): + r""" + Constituency TreeCRF :cite:`zhang-etal-2020-fast,stern-etal-2017-minimal`. + + Args: + scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``. + Scores of all constituents. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking. + + Examples: + >>> from supar import ConstituencyCRF + >>> batch_size, seq_len, n_labels = 2, 5, 4 + >>> lens = torch.tensor([3, 4]) + >>> charts = torch.tensor([[[-1, 0, -1, 0, -1], + [-1, -1, 0, 0, -1], + [-1, -1, -1, 0, -1], + [-1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1]], + [[-1, 0, 0, -1, 0], + [-1, -1, 0, -1, -1], + [-1, -1, -1, 0, 0], + [-1, -1, -1, -1, 0], + [-1, -1, -1, -1, -1]]]) + >>> s1 = ConstituencyCRF(torch.randn(batch_size, seq_len, seq_len, n_labels), lens, True) + >>> s2 = ConstituencyCRF(torch.randn(batch_size, seq_len, seq_len, n_labels), lens, True) + >>> s1.max + tensor([3.7036, 7.2569], grad_fn=<IndexBackward0>) + >>> s1.argmax + [[[0, 1, 2], [0, 3, 0], [1, 2, 1], [1, 3, 0], [2, 3, 3]], + [[0, 1, 1], [0, 4, 2], [1, 2, 3], [1, 4, 1], [2, 3, 2], [2, 4, 3], [3, 4, 3]]] + >>> s1.log_partition + tensor([ 8.5394, 12.9940], grad_fn=<IndexBackward0>) + >>> s1.log_prob(charts) + tensor([ -8.5209, -14.1160], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([6.8868, 9.3996], grad_fn=<IndexBackward0>) + >>> s1.kl(s2) + tensor([4.0039, 4.1037], grad_fn=<IndexBackward0>) + """ + + def __init__( + self, + scores: torch.Tensor, + lens: Optional[torch.LongTensor] = None, + label: bool = False + ) -> ConstituencyCRF: + super().__init__(scores) + + batch_size, seq_len, *_ = scores.shape + self.lens = scores.new_full((batch_size,), seq_len-1).long() if lens is None else lens + self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len))) + self.mask = self.mask.unsqueeze(1) & scores.new_ones(scores.shape[:3]).bool().triu_(1) + self.label = label + + def __repr__(self): + return f"{self.__class__.__name__}(label={self.label})" + + def __add__(self, other): + return ConstituencyCRF(torch.stack((self.scores, other.scores), -1), self.lens, self.label) + + @lazy_property + def argmax(self): + return [torch.nonzero(i).tolist() for i in self.backward(self.max.sum())] + + def topk(self, k: int) -> List[List[Tuple]]: + return list(zip(*[[torch.nonzero(j).tolist() for j in self.backward(i)] for i in self.kmax(k).sum(0)])) + + def score(self, value: torch.LongTensor) -> torch.Tensor: + mask = self.mask & value.ge(0) + if self.label: + scores = self.scores[mask].gather(-1, value[mask].unsqueeze(-1)).squeeze(-1) + scores = torch.full_like(mask, LogSemiring.one, dtype=scores.dtype).masked_scatter_(mask, scores) + else: + scores = LogSemiring.one_mask(self.scores, ~mask) + return LogSemiring.prod(LogSemiring.prod(scores, -1), -1) + + @torch.enable_grad() + def forward(self, semiring: Semiring) -> torch.Tensor: + batch_size, seq_len = self.scores.shape[:2] + # [seq_len, seq_len, batch_size, ...], (l->r) + scores = semiring.convert(self.scores.movedim((1, 2), (0, 1))) + scores = semiring.sum(scores, 3) if self.label else scores + s = semiring.zeros_like(scores) + s.diagonal(1).copy_(scores.diagonal(1)) + + for w in range(2, seq_len): + n = seq_len - w + # [n, batch_size, ...] + s_s = semiring.dot(stripe(s, n, w-1, (0, 1)), stripe(s, n, w-1, (1, w), False), 1) + s.diagonal(w).copy_(semiring.mul(s_s, scores.diagonal(w).movedim(-1, 0)).movedim(0, -1)) + return semiring.unconvert(s)[0][self.lens, range(batch_size)] + + +class BiLexicalizedConstituencyCRF(StructuredDistribution): + r""" + Grammarless Eisner-Satta Algorithm :cite:`eisner-satta-1999-efficient,yang-etal-2021-neural`. + + Code is revised from `Songlin Yang's implementation <https://github.com/sustcsonglin/span-based-dependency-parsing>`_. + + Args: + scores (~torch.Tensor): ``[2, batch_size, seq_len, seq_len]``. + Scores of dependencies and constituents. + lens (~torch.LongTensor): ``[batch_size]``. + Sentence lengths for masking. + + Examples: + >>> from supar import BiLexicalizedConstituencyCRF + >>> batch_size, seq_len = 2, 5 + >>> lens = torch.tensor([3, 4]) + >>> deps = torch.tensor([[0, 0, 1, 1, 0], [0, 3, 1, 0, 3]]) + >>> cons = torch.tensor([[[0, 1, 1, 1, 0], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0]], + [[0, 1, 1, 1, 1], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 1], + [0, 0, 0, 0, 0]]]).bool() + >>> heads = torch.tensor([[[0, 1, 1, 1, 0], + [0, 0, 2, 0, 0], + [0, 0, 0, 3, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0]], + [[0, 1, 1, 3, 3], + [0, 0, 2, 0, 0], + [0, 0, 0, 3, 0], + [0, 0, 0, 0, 4], + [0, 0, 0, 0, 0]]]) + >>> s1 = BiLexicalizedConstituencyCRF((torch.randn(batch_size, seq_len, seq_len), + torch.randn(batch_size, seq_len, seq_len), + torch.randn(batch_size, seq_len, seq_len, seq_len)), + lens) + >>> s2 = BiLexicalizedConstituencyCRF((torch.randn(batch_size, seq_len, seq_len), + torch.randn(batch_size, seq_len, seq_len), + torch.randn(batch_size, seq_len, seq_len, seq_len)), + lens) + >>> s1.max + tensor([0.5792, 2.1737], grad_fn=<MaxBackward0>) + >>> s1.argmax[0] + tensor([[0, 3, 1, 0, 0], + [0, 4, 1, 1, 0]]) + >>> s1.argmax[1] + [[[0, 3], [0, 2], [0, 1], [1, 2], [2, 3]], [[0, 4], [0, 3], [0, 2], [0, 1], [1, 2], [2, 3], [3, 4]]] + >>> s1.log_partition + tensor([1.1923, 3.2343], grad_fn=<LogsumexpBackward>) + >>> s1.log_prob((deps, cons, heads)) + tensor([-1.9123, -3.6127], grad_fn=<SubBackward0>) + >>> s1.entropy + tensor([1.3376, 2.2996], grad_fn=<SelectBackward>) + >>> s1.kl(s2) + tensor([1.0617, 2.7839], grad_fn=<SelectBackward>) + """ + + def __init__( + self, + scores: List[torch.Tensor], + lens: Optional[torch.LongTensor] = None + ) -> BiLexicalizedConstituencyCRF: + super().__init__(scores) + + batch_size, seq_len, *_ = scores[1].shape + self.lens = scores[1].new_full((batch_size,), seq_len-1).long() if lens is None else lens + self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len))) + self.mask = self.mask.unsqueeze(1) & scores[1].new_ones(scores[1].shape[:3]).bool().triu_(1) + + def __add__(self, other): + return BiLexicalizedConstituencyCRF([torch.stack((i, j), -1) for i, j in zip(self.scores, other.scores)], self.lens) + + @lazy_property + def argmax(self): + marginals = self.backward(self.max.sum()) + dep_mask = self.mask[:, 0] + dep = self.lens.new_zeros(dep_mask.shape).masked_scatter_(dep_mask, torch.where(marginals[0])[2]) + con = [torch.nonzero(i).tolist() for i in marginals[1]] + return dep, con + + def topk(self, k: int) -> Tuple[torch.LongTensor, List[List[Tuple]]]: + dep_mask = self.mask[:, 0] + marginals = [self.backward(i) for i in self.kmax(k).sum(0)] + dep_preds = torch.stack([torch.where(i)[2] for i in marginals[0]], -1) + dep_preds = self.lens.new_zeros(*dep_mask.shape, k).masked_scatter_(dep_mask.unsqueeze(-1), dep_preds) + con_preds = list(zip(*[[torch.nonzero(j).tolist() for j in i] for i in marginals[1]])) + return dep_preds, con_preds + + def score(self, value: List[Union[torch.LongTensor, torch.BoolTensor]], partial: bool = False) -> torch.Tensor: + deps, cons, heads = value + s_dep, s_con, s_head = self.scores + mask, lens = self.mask, self.lens + dep_mask, con_mask = mask[:, 0], mask + if partial: + if deps is not None: + dep_mask = dep_mask.index_fill(1, self.lens.new_tensor(0), 1) + dep_mask = dep_mask.unsqueeze(1) & dep_mask.unsqueeze(2) + deps = deps.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1) + deps = deps.eq(lens.new_tensor(range(mask.shape[1]))) | deps.lt(0) + s_dep = LogSemiring.zero_mask(s_dep, ~(deps & dep_mask)) + if cons is not None: + s_con = LogSemiring.zero_mask(s_con, ~(cons & con_mask)) + if heads is not None: + head_mask = heads.unsqueeze(-1).eq(lens.new_tensor(range(mask.shape[1]))) + head_mask = head_mask & con_mask.unsqueeze(-1) + s_head = LogSemiring.zero_mask(s_head, ~head_mask) + return self.__class__((s_dep, s_con, s_head), lens, **self.kwargs).log_partition + s_dep = LogSemiring.prod(LogSemiring.one_mask(s_dep.gather(-1, deps.unsqueeze(-1)).squeeze(-1), ~dep_mask), -1) + s_head = LogSemiring.mul(s_con, s_head.gather(-1, heads.unsqueeze(-1)).squeeze(-1)) + s_head = LogSemiring.prod(LogSemiring.prod(LogSemiring.one_mask(s_head, ~(con_mask & cons)), -1), -1) + return LogSemiring.mul(s_dep, s_head) + + def forward(self, semiring: Semiring) -> torch.Tensor: + s_dep, s_con, s_head = self.scores + batch_size, seq_len, *_ = s_con.shape + # [seq_len, seq_len, batch_size, ...], (m<-h) + s_dep = semiring.convert(s_dep.movedim(0, 2)) + s_root, s_dep = s_dep[1:, 0], s_dep[1:, 1:] + # [seq_len, seq_len, batch_size, ...], (i, j) + s_con = semiring.convert(s_con.movedim(0, 2)) + # [seq_len, seq_len, seq_len-1, batch_size, ...], (i, j, h) + s_head = semiring.mul(s_con.unsqueeze(2), semiring.convert(s_head.movedim(0, -1)[:, :, 1:])) + # [seq_len, seq_len, seq_len-1, batch_size, ...], (i, j, h) + s_span = semiring.zeros_like(s_head) + # [seq_len, seq_len, seq_len-1, batch_size, ...], (i, j<-h) + s_hook = semiring.zeros_like(s_head) + diagonal_stripe(s_span, 1).copy_(diagonal_stripe(s_head, 1)) + s_hook.diagonal(1).copy_(semiring.mul(s_dep, diagonal_stripe(s_head, 1)).movedim(0, -1)) + + for w in range(2, seq_len): + n = seq_len - w + # COMPLETE-L: s_span_l(i, j, h) = <s_span(i, k, h), s_hook(h->k, j)>, i < k < j + # [n, w, batch_size, ...] + s_l = stripe(semiring.dot(stripe(s_span, n, w-1, (0, 1)), stripe(s_hook, n, w-1, (1, w), False), 1), n, w) + # COMPLETE-R: s_span_r(i, j, h) = <s_hook(i, k<-h), s_span(k, j, h)>, i < k < j + # [n, w, batch_size, ...] + s_r = stripe(semiring.dot(stripe(s_hook, n, w-1, (0, 1)), stripe(s_span, n, w-1, (1, w), False), 1), n, w) + # COMPLETE: s_span(i, j, h) = (s_span_l(i, j, h) + s_span_r(i, j, h)) * s(i, j, h) + # [n, w, batch_size, ...] + s = semiring.mul(semiring.sum(torch.stack((s_l, s_r)), 0), diagonal_stripe(s_head, w)) + diagonal_stripe(s_span, w).copy_(s) + + if w == seq_len - 1: + continue + # ATTACH: s_hook(h->i, j) = <s(h->m), s_span(i, j, m)>, i <= m < j + # [n, seq_len, batch_size, ...] + s = semiring.dot(expanded_stripe(s_dep, n, w), diagonal_stripe(s_span, w).unsqueeze(2), 1) + s_hook.diagonal(w).copy_(s.movedim(0, -1)) + return semiring.unconvert(semiring.dot(s_span[0][self.lens, :, range(batch_size)].transpose(0, 1), s_root, 0)) diff --git a/tania_scripts/supar/structs/vi.py b/tania_scripts/supar/structs/vi.py new file mode 100644 index 0000000..b848825 --- /dev/null +++ b/tania_scripts/supar/structs/vi.py @@ -0,0 +1,499 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import List, Optional, Tuple +import torch +import torch.nn as nn +import torch.nn.functional as F +from supar.structs import DependencyCRF +from supar.utils.common import MIN + + +class DependencyMFVI(nn.Module): + r""" + Mean Field Variational Inference for approximately calculating marginals + of dependency trees :cite:`wang-tu-2020-second`. + """ + + def __init__(self, max_iter: int = 3) -> DependencyMFVI: + super().__init__() + + self.max_iter = max_iter + + def __repr__(self): + return f"{self.__class__.__name__}(max_iter={self.max_iter})" + + @torch.enable_grad() + def forward( + self, + scores: List[torch.Tensor], + mask: torch.BoolTensor, + target: Optional[torch.LongTensor] = None + ) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + Args: + scores (~torch.Tensor, ~torch.Tensor): + Tuple of three tensors `s_arc` and `s_sib`. + `s_arc` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs. + `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask to avoid aggregation on padding tokens. + target (~torch.LongTensor): ``[batch_size, seq_len]``. + A Tensor of gold-standard dependent-head pairs. Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``. + The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + logits = self.mfvi(*scores, mask) + marginals = logits.softmax(-1) + + if target is None: + return marginals + loss = F.cross_entropy(logits[mask], target[mask]) + + return loss, marginals + + def mfvi(self, s_arc, s_sib, mask): + batch_size, seq_len = mask.shape + ls, rs = torch.stack(torch.where(mask.new_ones(seq_len, seq_len))).view(-1, seq_len, seq_len).sort(0)[0] + mask = mask.index_fill(1, ls.new_tensor(0), 1) + # [seq_len, seq_len, batch_size], (h->m) + mask = (mask.unsqueeze(-1) & mask.unsqueeze(-2)).permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + mask2o = mask.unsqueeze(1) & mask.unsqueeze(2) + mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1) + # [seq_len, seq_len, batch_size], (h->m) + s_arc = s_arc.permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + s_sib = s_sib.permute(2, 1, 3, 0) * mask2o + + # posterior distributions + # [seq_len, seq_len, batch_size], (h->m) + q = s_arc + + for _ in range(self.max_iter): + q = q.softmax(0) + # q(ij) = s(ij) + sum(q(ik)s^sib(ij,ik)), k != i,j + q = s_arc + (q.unsqueeze(1) * s_sib).sum(2) + + return q.permute(2, 1, 0) + + +class DependencyLBP(nn.Module): + r""" + Loopy Belief Propagation for approximately calculating marginals + of dependency trees :cite:`smith-eisner-2008-dependency`. + """ + + def __init__(self, max_iter: int = 3) -> DependencyLBP: + super().__init__() + + self.max_iter = max_iter + + def __repr__(self): + return f"{self.__class__.__name__}(max_iter={self.max_iter})" + + @torch.enable_grad() + def forward( + self, + scores: List[torch.Tensor], + mask: torch.BoolTensor, + target: Optional[torch.LongTensor] = None + ) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + Args: + scores (~torch.Tensor, ~torch.Tensor): + Tuple of three tensors `s_arc` and `s_sib`. + `s_arc` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs. + `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples. + mask (~torch.BoolTensor): ``[batch_size, seq_len]``. + The mask to avoid aggregation on padding tokens. + target (~torch.LongTensor): ``[batch_size, seq_len]``. + A Tensor of gold-standard dependent-head pairs. Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``. + The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + logits = self.lbp(*scores, mask) + marginals = logits.softmax(-1) + + if target is None: + return marginals + loss = F.cross_entropy(logits[mask], target[mask]) + + return loss, marginals + + def lbp(self, s_arc, s_sib, mask): + batch_size, seq_len = mask.shape + ls, rs = torch.stack(torch.where(mask.new_ones(seq_len, seq_len))).view(-1, seq_len, seq_len).sort(0)[0] + mask = mask.index_fill(1, ls.new_tensor(0), 1) + # [seq_len, seq_len, batch_size], (h->m) + mask = (mask.unsqueeze(-1) & mask.unsqueeze(-2)).permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + mask2o = mask.unsqueeze(1) & mask.unsqueeze(2) + mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1) + # [seq_len, seq_len, batch_size], (h->m) + s_arc = s_arc.permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + s_sib = s_sib.permute(2, 1, 3, 0).masked_fill_(~mask2o, MIN) + + # log beliefs + # [seq_len, seq_len, batch_size], (h->m) + q = s_arc + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + m_sib = s_sib.new_zeros(seq_len, seq_len, seq_len, batch_size) + + for _ in range(self.max_iter): + q = q.log_softmax(0) + # m(ik->ij) = logsumexp(q(ik) - m(ij->ik) + s(ij->ik)) + m = q.unsqueeze(2) - m_sib + # TODO: better solution for OOM + m_sib = torch.logaddexp(m.logsumexp(0), m + s_sib).transpose(1, 2).log_softmax(0) + # q(ij) = s(ij) + sum(m(ik->ij)), k != i,j + q = s_arc + (m_sib * mask2o).sum(2) + + return q.permute(2, 1, 0) + + +class ConstituencyMFVI(nn.Module): + r""" + Mean Field Variational Inference for approximately calculating marginals of constituent trees. + """ + + def __init__(self, max_iter: int = 3) -> ConstituencyMFVI: + super().__init__() + + self.max_iter = max_iter + + def __repr__(self): + return f"{self.__class__.__name__}(max_iter={self.max_iter})" + + @torch.enable_grad() + def forward( + self, + scores: List[torch.Tensor], + mask: torch.BoolTensor, + target: Optional[torch.LongTensor] = None + ) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + Args: + scores (~torch.Tensor, ~torch.Tensor): + Tuple of two tensors `s_span` and `s_pair`. + `s_span` (``[batch_size, seq_len, seq_len]``) holds scores of all possible spans. + `s_pair` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of second-order triples. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask to avoid aggregation on padding tokens. + target (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + A Tensor of gold-standard dependent-head pairs. Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``. + The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + logits = self.mfvi(*scores, mask) + marginals = logits.sigmoid() + + if target is None: + return marginals + loss = F.binary_cross_entropy_with_logits(logits[mask], target[mask].float()) + + return loss, marginals + + def mfvi(self, s_span, s_pair, mask): + batch_size, seq_len, _ = mask.shape + ls, rs = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len).sort(0)[0] + # [seq_len, seq_len, batch_size], (l->r) + mask = mask.movedim(0, 2) + # [seq_len, seq_len, seq_len, batch_size], (l->r->b) + mask2o = mask.unsqueeze(2).repeat(1, 1, seq_len, 1) + mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1) + # [seq_len, seq_len, batch_size], (l->r) + s_span = s_span.movedim(0, 2) + # [seq_len, seq_len, seq_len, batch_size], (l->r->b) + s_pair = s_pair.permute(1, 2, 3, 0) * mask2o + + # posterior distributions + # [seq_len, seq_len, batch_size], (l->r) + q = s_span + + for _ in range(self.max_iter): + q = q.sigmoid() + # q(ij) = s(ij) + sum(q(jk)*s^pair(ij,jk), k != i,j + q = s_span + (q.unsqueeze(1) * s_pair).sum(2) + + return q.permute(2, 0, 1) + + +class ConstituencyLBP(nn.Module): + r""" + Loopy Belief Propagation for approximately calculating marginals of constituent trees. + """ + + def __init__(self, max_iter: int = 3) -> ConstituencyLBP: + super().__init__() + + self.max_iter = max_iter + + def __repr__(self): + return f"{self.__class__.__name__}(max_iter={self.max_iter})" + + @torch.enable_grad() + def forward( + self, + scores: List[torch.Tensor], + mask: torch.BoolTensor, + target: Optional[torch.LongTensor] = None + ) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + Args: + scores (~torch.Tensor, ~torch.Tensor): + Tuple of four tensors `s_edge`, `s_sib`, `s_cop` and `s_grd`. + `s_span` (``[batch_size, seq_len, seq_len]``) holds scores of all possible spans. + `s_pair` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of second-order triples. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask to avoid aggregation on padding tokens. + target (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + A Tensor of gold-standard dependent-head pairs. Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``. + The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + logits = self.lbp(*scores, mask) + marginals = logits.softmax(-1)[..., 1] + + if target is None: + return marginals + loss = F.cross_entropy(logits[mask], target[mask].long()) + + return loss, marginals + + def lbp(self, s_span, s_pair, mask): + batch_size, seq_len, _ = mask.shape + ls, rs = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len).sort(0)[0] + # [seq_len, seq_len, batch_size], (l->r) + mask = mask.movedim(0, 2) + # [seq_len, seq_len, seq_len, batch_size], (l->r->b) + mask2o = mask.unsqueeze(2).repeat(1, 1, seq_len, 1) + mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1) + # [2, seq_len, seq_len, batch_size], (l->r) + s_span = torch.stack((torch.zeros_like(s_span), s_span)).permute(0, 3, 2, 1) + # [seq_len, seq_len, seq_len, batch_size], (l->r->p) + s_pair = s_pair.permute(2, 1, 3, 0) + + # log beliefs + # [2, seq_len, seq_len, batch_size], (h->m) + q = s_span + # [2, seq_len, seq_len, seq_len, batch_size], (h->m->s) + m_pair = s_pair.new_zeros(2, seq_len, seq_len, seq_len, batch_size) + + for _ in range(self.max_iter): + q = q.log_softmax(0) + # m(ik->ij) = logsumexp(q(ik) - m(ij->ik) + s(ij->ik)) + m = q.unsqueeze(3) - m_pair + m_pair = torch.stack((m.logsumexp(0), torch.stack((m[0], m[1] + s_pair)).logsumexp(0))).log_softmax(0) + # q(ij) = s(ij) + sum(m(ik->ij)), k != i,j + q = s_span + (m_pair.transpose(2, 3) * mask2o).sum(3) + + return q.permute(3, 2, 1, 0) + + +class SemanticDependencyMFVI(nn.Module): + r""" + Mean Field Variational Inference for approximately calculating marginals + of semantic dependency trees :cite:`wang-etal-2019-second`. + """ + + def __init__(self, max_iter: int = 3) -> SemanticDependencyMFVI: + super().__init__() + + self.max_iter = max_iter + + def __repr__(self): + return f"{self.__class__.__name__}(max_iter={self.max_iter})" + + @torch.enable_grad() + def forward( + self, + scores: List[torch.Tensor], + mask: torch.BoolTensor, + target: Optional[torch.LongTensor] = None + ) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + Args: + scores (~torch.Tensor, ~torch.Tensor): + Tuple of four tensors `s_edge`, `s_sib`, `s_cop` and `s_grd`. + `s_edge` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs. + `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples. + `s_cop` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-coparent triples. + `s_grd` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-grandparent triples. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask to avoid aggregation on padding tokens. + target (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + A Tensor of gold-standard dependent-head pairs. Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``. + The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + logits = self.mfvi(*scores, mask) + marginals = logits.sigmoid() + + if target is None: + return marginals + loss = F.binary_cross_entropy_with_logits(logits[mask], target[mask].float()) + + return loss, marginals + + def mfvi(self, s_edge, s_sib, s_cop, s_grd, mask): + _, seq_len, _ = mask.shape + hs, ms = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len) + # [seq_len, seq_len, batch_size], (h->m) + mask = mask.permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + mask2o = mask.unsqueeze(1) & mask.unsqueeze(2) + mask2o = mask2o & hs.unsqueeze(-1).ne(hs.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o = mask2o & ms.unsqueeze(-1).ne(ms.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o.diagonal().fill_(0) + # [seq_len, seq_len, batch_size], (h->m) + s_edge = s_edge.permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + s_sib = s_sib.permute(2, 1, 3, 0) * mask2o + # [seq_len, seq_len, seq_len, batch_size], (h->m->c) + s_cop = s_cop.permute(2, 1, 3, 0) * mask2o + # [seq_len, seq_len, seq_len, batch_size], (h->m->g) + s_grd = s_grd.permute(2, 1, 3, 0) * mask2o + + # posterior distributions + # [seq_len, seq_len, batch_size], (h->m) + q = s_edge + + for _ in range(self.max_iter): + q = q.sigmoid() + # q(ij) = s(ij) + sum(q(ik)s^sib(ij,ik) + q(kj)s^cop(ij,kj) + q(jk)s^grd(ij,jk)), k != i,j + q = s_edge + (q.unsqueeze(1) * s_sib + q.transpose(0, 1).unsqueeze(0) * s_cop + q.unsqueeze(0) * s_grd).sum(2) + + return q.permute(2, 1, 0) + + +class SemanticDependencyLBP(nn.Module): + r""" + Loopy Belief Propagation for approximately calculating marginals + of semantic dependency trees :cite:`wang-etal-2019-second`. + """ + + def __init__(self, max_iter: int = 3) -> SemanticDependencyLBP: + super().__init__() + + self.max_iter = max_iter + + def __repr__(self): + return f"{self.__class__.__name__}(max_iter={self.max_iter})" + + @torch.enable_grad() + def forward( + self, + scores: List[torch.Tensor], + mask: torch.BoolTensor, + target: Optional[torch.LongTensor] = None + ) -> Tuple[torch.Tensor, torch.Tensor]: + r""" + Args: + scores (~torch.Tensor, ~torch.Tensor): + Tuple of four tensors `s_edge`, `s_sib`, `s_cop` and `s_grd`. + `s_edge` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs. + `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples. + `s_cop` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-coparent triples. + `s_grd` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-grandparent triples. + mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``. + The mask to avoid aggregation on padding tokens. + target (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``. + A Tensor of gold-standard dependent-head pairs. Default: ``None``. + + Returns: + ~torch.Tensor, ~torch.Tensor: + The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``. + The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``. + """ + + logits = self.lbp(*scores, mask) + marginals = logits.softmax(-1)[..., 1] + + if target is None: + return marginals + loss = F.cross_entropy(logits[mask], target[mask]) + + return loss, marginals + + def lbp(self, s_edge, s_sib, s_cop, s_grd, mask): + lens = mask[..., 0].sum(1) + _, seq_len, _ = mask.shape + hs, ms = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len) + # [seq_len, seq_len, batch_size], (h->m) + mask = mask.permute(2, 1, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + mask2o = mask.unsqueeze(1) & mask.unsqueeze(2) + mask2o = mask2o & hs.unsqueeze(-1).ne(hs.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o = mask2o & ms.unsqueeze(-1).ne(ms.new_tensor(range(seq_len))).unsqueeze(-1) + mask2o.diagonal().fill_(0) + # [2, seq_len, seq_len, batch_size], (h->m) + s_edge = torch.stack((torch.zeros_like(s_edge), s_edge)).permute(0, 3, 2, 1) + # [seq_len, seq_len, seq_len, batch_size], (h->m->s) + s_sib = s_sib.permute(2, 1, 3, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->c) + s_cop = s_cop.permute(2, 1, 3, 0) + # [seq_len, seq_len, seq_len, batch_size], (h->m->g) + s_grd = s_grd.permute(2, 1, 3, 0) + + # log beliefs + # [2, seq_len, seq_len, batch_size], (h->m) + q = s_edge + # sibling factor + # [2, seq_len, seq_len, seq_len, batch_size], (h->m->s) + m_sib = s_sib.new_zeros(2, *mask2o.shape) + # coparent factor + # [2, seq_len, seq_len, seq_len, batch_size], (h->m->c) + m_cop = s_cop.new_zeros(2, *mask2o.shape) + # grandparent factor + # [2, seq_len, seq_len, seq_len, batch_size], (h->m->g) + m_grd = s_grd.new_zeros(2, *mask2o.shape) + # tree factor + # [2, seq_len, seq_len, batch_size], (h->m) + m_tree = torch.zeros_like(s_edge) + + for _ in range(self.max_iter): + # sibling factor + v_sib = q.unsqueeze(2) - m_sib + m_sib = torch.stack((v_sib.logsumexp(0), torch.stack((v_sib[0], v_sib[1] + s_sib)).logsumexp(0))).log_softmax(0) + # coparent factor + v_cop = q.transpose(1, 2).unsqueeze(1) - m_cop + m_cop = torch.stack((v_cop.logsumexp(0), torch.stack((v_cop[0], v_cop[1] + s_cop)).logsumexp(0))).log_softmax(0) + # grandparent factor + v_grd = q.unsqueeze(1) - m_grd + m_grd = torch.stack((v_grd.logsumexp(0), torch.stack((v_grd[0], v_grd[1] + s_grd)).logsumexp(0))).log_softmax(0) + # tree factor + v_tree = q - m_tree + b_tree = DependencyCRF((v_tree[1] - v_tree[0]).permute(2, 1, 0), lens).marginals.permute(2, 1, 0) + b_tree = torch.stack((1 - b_tree, b_tree)) + m_tree = (b_tree.clamp(torch.finfo().eps).log() - v_tree).log_softmax(0) + # q(ij) = s(ij) + sum(m(ik->ij)), k != i,j + q = s_edge + ((m_sib + m_cop + m_grd).transpose(2, 3) * mask2o).sum(3) + m_tree + + return q.permute(3, 2, 1, 0) diff --git a/tania_scripts/supar/utils/__init__.py b/tania_scripts/supar/utils/__init__.py new file mode 100644 index 0000000..279bb3f --- /dev/null +++ b/tania_scripts/supar/utils/__init__.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +from . import field, fn, metric, transform +from .config import Config +from .data import Dataset +from .embed import Embedding +from .field import ChartField, Field, RawField, SubwordField +from .transform import Transform +from .vocab import Vocab + +__all__ = ['Config', + 'Dataset', + 'Embedding', + 'RawField', 'Field', 'SubwordField', 'ChartField', + 'Transform', + 'Vocab', + 'field', 'fn', 'metric', 'transform'] diff --git a/tania_scripts/supar/utils/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7085981158edde053f2e613913ae5104f375bc5 GIT binary patch literal 590 zcmd1j<>g{vU|<knUzGlak%8ech=Yuo7#J8F7#J9eD;O9UQW#Pga~N_NqZo6UqL^}- zqnLA9qF5L~;!HWLxolBvU^a6OdoD*52bj&0!<ow!#RX=w<}l`RM{(!!MDgVEM)BtI zMe%{f*>YHN`J?#3Z1x<1T)`+oMuv2T6plrVQ9>!4!3>&QFBusa7&KXKv8H9F=A_(W zO3S;&mYZ5ql$m^sv!p07uQ)BgC|8s57MpW^URq|lCgUx3m&B69;?xpN##@}Oxk;%h zDVcfcnk=`toHG)OO5DK4utF$~pu}<rizm1=sXV_Z1<V8K3_&uRH7q|lF-eoRh>d}P zp@<zsaDWJI5CICsA|4Qn6GZTW2tE)23cw;}5Q_ywure?(_-P8?Vkp8Qaf>Y(?0m2d zw^&jVOA^8M++s}y`Jf1F9oT%ZbzqCZc7m*nVl4x?uLxx8E%x~M#GIV?_>~MrA|Pu) z#4lU@jQreG{gT9z%*4Dzy`-GPl+4s3{p9@If_&Zdf)d@_{FKxj{o>Ms#3KFDlFXc9 s{rLFIyv&mLc)fzkTO2mI`6;D2sdk{aC>CH~V31(qVFW=5Fv-IN0MJ{BYybcN literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea9d342a076da2ffb2ad39c0137168c37c8ba0a9 GIT binary patch literal 781 zcmZ3^%ge>Uz`&q%Up3<mBLl-@5C?{tpp4H|3=9m@8B!Qh7;_kM8KW3;nWC6-nWLC< zS)y1NLE=m~thsDaY+yEX4tp*~6bG2ilEazH6~zT+v*s}7az}CJ@<j3E@<#FI@<s81 z#o2OLa`~h9!EE*%fn32TK}Lpjh7^uPj8Q@<oWTs5TrU|J7#K8JZn36irskyFVoJ-q z#g>~|Qk0o|i?gICF|Rl+zbIFe@fMqNeqLH;x+dc-c9+DG#NyNvO~zZCuDMC6DJhwG z>6$FJxSTT*i%Q(U#;`&tj-bSH2#Y7UG^sqlC<V*|=?p<Kn>8#yIWb9-w}_pAfuV>4 zL~w!#9uUC|B6vXrC^U=sKrDU`!3-i;Km;p@U}Iol@Y58&#ZZJr;uc#n*!f@^Zn2~! zmL!7hxy70a@<9>UI<Wa*>%bO+?F3nOi?s~oz9NvVx7g$36LWIn<5x0#21Vg7Z~ct? z+*JLN#FEU!yhOdEoWzvO)FS=l{M>?k-ICOb65Z6Y#2o#S#JtSJ_~PWE%z~0){o>Ms z#3KFDlFXc9{rLFIyv&mLc)fzkUmP~M`6;D2sdhz@3=9mQm?_@Jz`*c<nURt40~-UQ z_5}tl{OAUQ)CE*@gF*5FD!RcSa{(3IV6eGB2;E>%xPXdoFi2cLMITt$xD7urz=#HR L5G)dBU|;|M)oIM# literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/common.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/common.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d3aa81c201d0bcf97afeb8657a7fbfda08ae766 GIT binary patch literal 358 zcmd1j<>g{vU|<knUzEOsfq~&Mh=Yuo85kHG7#J9eEf^RWQW#Pga~Pr+QkbF`Q<$Te zQdpvxQ&^)|QrMzcQ`n=}QrS~Dni-=wQW>&17jUI;E@X`2PGJmY(BygvGSjb$)utdZ z#jc9grZg`bL?z`HgQ!#pl~<Z$moA>ix^?T0$;WOnXXd3<@zv?;B_}3lr0N%!79<vF z^4wy|FOFgkaCC`c4)ybnVs`Qmj$(H855C3h7wU71+1JzW7He8geqzZjW=}u2TPy{M zB^kH4QY#7)^HNHSQ;Tk~Iy*XhxUOU<;$~og5WlSTGxBp&^-B^<G86L>^^$TDQ!-PF z^po>*3-Wc-3rciz^HWlDATH1^Ey>I&2Fc~-=jjzx-r}&y%}*)KNws4Hg^~~h0|N&W P3lj??6f$uz3NQfxK^R}e literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/common.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/common.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a95bf475fc0c1b5ed5fbe397eed664cc93daf29 GIT binary patch literal 496 zcmZ3^%ge>Uz`&q%Uo~R~0|Ucj5C?{tp^VQ33=9m@8B!Qh7;_k+7*d#`7*m*|m{M4x zm{VAzSW?)cSX0=e*q9hn*;6={F)}c$W`ycwh~h|P$l`?Y7J%)7@nCccCz>Aa6vki% zO|F+91%6emHU)_(c2%r4rFq#PDk;AhM5RKgywV)Ibn!gaty_0YK6Z;aGcT=*uTEbt zIWajSRlm5jAhAf3=N40b@h#>6N0(d7p?==Cn4SECZ!x=q2)|IDTg<+mez#cDa`F>P zZZUiMx!qzZNG!>?#g$r7keHWJTAW&Ri`CiD*~4`u!)K6-etGI=<maa9mn4>CCgvsT zCFLZhWTqDBC+FuD<m;BCR+Q+bmL=xsmn7z8CdL;h7iAWd6hoY%Us{rxQw&m>o1dpw zQ2C3)CO1E&G$+-rNSJ|v0TgP*p$rTRAD9^#89%TwFmg3;g5U!--Uj9yScnH~+#m_= rhSUz%#+;U%2IdDGTs`d9IixOeNL`TDzR00-g+r%-6$Fa}85kG<fB1zj literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/config.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ca40a0457ad92a8c30fc0f85221363889e017cd GIT binary patch literal 4218 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 Jm_W1$GXTwohEo6l literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/config.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c702557431115d22e5cd81b51b3e043b2e3df185 GIT binary patch literal 7268 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 IssaZD0KUHYN&o-= literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/data.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/data.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86c2665f120944e63bad5a419675ff4d4c8cdfdc GIT binary patch literal 15054 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/data.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/data.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6e9fad9bc068980a106abf82b540436629543ca GIT binary patch literal 25699 zcmZ3^%ge>Uz`&q%Up1rAjDg`Xhy%l{5C-GtON<N*(-~42QW$d>av7r-89{8O9HuCy z6owS09OfuyFwGLh0;XA`Siv+~6dRakk77?@NMX+5$mNXU1nXtV;mYNX;?CuX;>qQW z;?3oY;sc8_<?!bUL<vIKLQz6s{ld8-QKDcm)*P{1@hEXHn=MBoS29X6S1L*>S2{`> zEXJNAlPen~n=2P32j+9+$mc3VDdZ|fDT4W&IZC<8QOdb0Q7T|QSB`3~T9g_i0~154 zY^wS)Mh1q}j1XTlFhprEF}O3NaJMj|@T3Z5X~M*_wBRgl7;70b1H)=&7%xg2tdqBe zA%zczP92z9G@UwNo%}5fDFQfj>f+F;3)U&v!jK}A%ATc%LzRAta0^3}K?+kagQmz! zkRnaSTil6xdHE%YC7Jno#eSNMxA>Ct^GZ@HN^%qP64O(QG+A!3xMU`m+~V*oNi9lD z%1OP&;*(iia*H)IFEc++lkpa_r=Oc9^DT~~%)G>+%&OE|Tq&t=Hd}UXYGPioCetmh z^wg60oc#3k)S_EF1x5MkMXANb@kxnAnoPIYGmGO>K!$Q=7RTo%7MG-gL|L5@OOi8g zafTEn<`t*q7v*X)-r~(ktg4JJD9SHLEh?!@2KfPoSs)C?&kYO=4DAfl8B!Ud7*iOc zm{J&{m^m3BFhw;*t%D(rF-4$-H;N@iu!SLtHASd}A&LzgHtZ=PEeuf{DWWY5QJg7a zEeugysoW{zEey*T7#LPVEMQ<@h~j~m1|w6{Q#4XkT3DlaI~Xb$qxgauG&OIryCjw* z7N?dZ=CU&|a49G#C_n`iN-`2l6f%nylJj#55=%0Za#9t_GfOfQtdesQi;JxiO7e@6 zGxSPJGINUcQW8rN^`IIPbQFqHi^?+d(iIYm6%rN7ixLY8Qi~MQ@{1I56Z0|)N^=rR zz_K|x3LuRNX_=`xDaByR!8Vj+q$+@d4x%h6H6yVsGrzQ`SRo}fEi*4QMIkc}?uxqN z(t^Yys544nai9l}jRZZgxgi;;$aX2@rzs@n<S2k_%FHV+Nz5zBOe{%FQ7BH$D@n~u zPAyhQPRvtCN>xZqPEIW@PE7&(B~Kx-q@*Y_sk9^&WCBPx$OFZxC3;+7YaENxi><&c zP)Nd^qo4tIk0wGIq{J~#0b+kL*hE;^67-cqevv|E2`EI0GRq*@0^(7Sp&$(MFx=#f z{G1d}R1~KcWu_K`oSu`Pm;#Q2ycC6kqI{4aL0qJ;2FFBEYI<T(ib6>~IHZaTQj;^& zGLxYpnO~HfSc0$>6cP#=;QSU{TvDW?0LzN8=zdm6%gjm5OUz9L`65vvC$qQ&<R+MN ziy=v`JToT;6axi`;PB7PE6G=|%1tfFuu6ajtRBc8&?pA^Iyo^pBUM2oDL+34%~H=a zg@lBVqSDla1RaGEa4?kQE0h+ef_+v{lnP2>#W|G<U?Wl#U}ZxJ+_MU4iNz%fAPY0| z(h=SUS?ignP?C{ZtWcg<2}=C1B$QZ`3Ra(*qL81bTauBgo0d}vN>TYm;J}9lYi?>u zBG?u*LqRTfOUx+-I~kN(5s4EPHYu4!smUcdl`w0-fdopHxv9DNMU|)qx}>HhmgbaL zDI_F7jYY`Ayh}LjU@Aee1j$pysU-^edC92?Nu`-NV2@>%=qdQ;<y0z^=NDxcD`bLv z0uEPONDSyH5O9lvMsZ0IS_}pxmSlhnk>W&f;R16=3OG3x>nIeZ7M5lffr<yb_W9-K zr6wSyncT#R_?*-{1&z$S5;QA=;iW-pMRIB?*l(cF%}LEmFUe3q#6od$Vo^$J3W~qb z?a3}rEJ`m{&;Zp_X!eBUr>B-=q!vL6*aT2cO3+b&YJk~7I3IxWDX3m7%7>I}(6p)m z&(*L}3RZ~Gr>sJxGDHH_0M*XXu<*q!Az)<!LI=n*sVNF+MfthlEDH)Ggvp>>=$e?E z0WZK6GV_viN>fscp|y)beo|^BsE7l_A4o4KDdi@XAlE4gh=K(<fq={g7azz;SVtih zWL+kxSS`rU%qvMP0tG+FbeNkJic9jr$q`gKq(TZ7a9V{p+s*G5C%hml5@KLrxWxi; z*e?-mW#}zdu<f^4KxJDIs6~8>IVm&m7ISe)(Jgjp8otGxnOAa)tthpmv?wo`9o`aP zU;weX85kHp*D*6NOl6$TPy%m6GBA`dAyn2dEMsC|SPd6h0B0f8FrYOw7#V69YZ&6; zjmsLQ8isgiLx+K(hPj3z9@<c6V5niKVTfmgnN`DD!w?U08(5%*t$?jW0L%mvH4O2b zU<LyNLk)WkLp;daV1XLu35-RSCE{QXn5bbYkpMHm1gam3<V&Q$!eAnc4@@yIFf8DQ zv5@H+Ce%iDF@K37LOz8NRkn$-h9L{?g9h#zrWB?skb4>81!21KvP-04YzBrbP*j7t z$U0M)*RY_vnvnsAtA)Xu(FkO-aOe|3(*owA`!<DD5-biPP~C&+uNsCdcuW@O;jk5Z z7&BzSLkBfHi+ng4O5mLq28J3Wl_|_?*wEa>j&N-aL%bNs)gYY05X_*=Py+8_Ffgbv z6iG5Nlo*0!AvlEt+3eX2DV%eeQQgwSSk6$v9LZ452r>_ZON=3UK_nAH4PzEOUDYt9 zF=jH<urFckLrWp(?$YG)t1<)Ej-X~xu>z=-keHK`Uk)nW@{3?C4{)PSM<J=SL?JJ~ zL?JD|G%ux!S+AfZM3eCrM`}f8aY=lB_DfJUUdeci1=NVR#R)5VimT*Zi;D6=jqcLC z6ovAP%$!sOc!vj63|86bfP|AX6mk<Q6*3abQWcU?Q}Yy(^NWf~3rawBSx8Z(LQ$$N zw4McN$}CYx%PcA`QPh;a#adiikXlqE3M#ia;^Q;(GE3s)i$F0@1j?30pojsNQ$?V( zU&P74z)&O$Qp^Ua*KToT7Q<S6MKT}>ru^btECq=r8MoNL-YdQ(=$4t2>X%>Q2J$@E zL$_GcK&2i>Zen(7N@h{<EtahO%)DEy#RWN;B}LpIOH@H-ak^F{rxt*^i??`!O7luG zb5o)EK{d-Q7Eo=X$$5*VI5j5?x1&MsEz$s+7atGq_Qb~*gM0$25<s}&m%DyOer~Eh zsB4;-m#CMNlbDj3TBHx^H0A4pdZ@aoWr;cZC5d^NiSfnBMVSR9#rohri$1vPqz@|c z^$IGB)EO8Ussx~YC_Pw!+A%ON6rW{eVEEC%@KuC?ldm^@LdiuAnJXMJ*Ev)#aj0J8 zP`|>Vet|>%fuvFgOAp@-5s40#9?l!0QXMQkTsI^XI#_ymZwQNZu=H@;5SN=!w^X@< zrHAK+m`n#t5BCFZfsYLQoKB2)g=J@?EOovptZ_wH;{yXDZxZ8HrY-E-`8M(GD7k3h za>c*}B6?R${eniqMX|&yVu=?75^wMe_f%Zqm%kySu)uVt&jgk!oD(>o3J6W%p5Zdb zV@1gY0h5aYCRYSZE(n<1m64m{KHq1S&kB(>5?hV7m~Xe;WP3p5qOsc*W48l^SByO` z%6MIo@j4NDQ6>mv(hXtpDYhRNSb5zTmj*2fUmmw8ZiCAf&x@*dS5)mF;vbk;1l<_# zs_JiG*}{2%<$|i~MOD`;s;&pJuc!u1aGBya!Eb`!kGtXu9~hVf-58O{yHaW&7#KBN z8Bd6uk%X|2$&U<-(r%1jz~l!8Mo~A$56mDVe*F0HfgR)|r~|;xgRsByF~}(`&|9Fn zL~n!01to_IN)9{3AoN99$1Adq9WFh79ey2t#XJlQ3`YeNU5y!z8Y{brF(-qvF{n@h zVNhMk463WAfCsf|7_va3V4MY4H=7}aaV}FWV+~^pQwc~1SRPzn!s}tw(rh-vT&5~s z28LS35>OI`t50D@EmMo6Y8X>k(9DF}K%|+hSj=QYGZS8S;4%}rPAlTAVN7917D4!@ zh9Qds>Kz8KI#9_D7eP@6_jw6YZI}(#4A#k6!;l46gQSx&g$ojPHH^Uwn%sWB7&WSR z^5Ws;t?ex~P?3^aRK=sCkQbi>8WTz_w!OukRGOTfT2c%ZhHz}FICLP*LE9>B9aw>% zYFovnqX2Em+5TeG)Z{KQ2bDb>@$sO}a(w(P=A6{LB5?V}o{?A#8jC2h1{HZWAOca~ zf{QJXFEp8o%s?hE78iq>aS94W79cK1e0))AK~a1>a(M$0Ndc8N{}>n;8W=!XyY33V z+65j>2<l+G!NGZf*Kn@$0+uCw7iILX$mn0-HN3!Uc#*@fgYho6&;*ki5*N9Zu5c@T zU|{4lzQMzLLC|O^^8%M8-WL@Nt|%B>5Hz|VXmpXssKXJWT=F8f@)d4nka82Sa$~S^ zpNk5HR}>5{2pV4yG``4V+~IhGo4>~jq)Zd6Ok;-29Ip$48W#jLF7jwVq-{ac`e13j z86|USF9_;g5Y)TKqX&_;nX7z>TlNCCELerkjFdS!7X)=K2<lwq(dlr!!NJ)P+{w|w zc!OV{gX1$OMWAF#P^JQBO3=_MYV)~<0g)|HlX5V_N=83TrXqV#{D9(ZB_lXOib2^J z8X4^Ipx$SEd=)>U?9WNfi;ph>MFps>*uZd?Uuc5K6uXQ3N>})mE^sInIWsUYB!i+9 z<W3L<<xjBlKxM^rP^$?f3dThWB_PLx+2Ha4uCIn63ocW`2ueQ?MW}f<j|Z2!V1^=B z1_lOA7D#0eu6;pGE^rcsr9IZnyp+@ml=R0PAD^CDl39|P8y{aKjPN#GupH!deMl;_ zcivNVfj_0UYKF=j%>^M#;x@QmQMJ0rZ+(T|`U1c8iIOvQ7vhqy_@`XpNWl{>8jK7K z?TphIIvG<KTTsFW5qU0X{hBhyBK8t^KZbz;+}4MOSW#pNyo_OB$O6RxIQSO8%QY|; zN+6e9sEMSA3%UF%X0BnVWy+IfLUki3H-k;8VaVbFGZ+{cz%5ROEKs<Eg+Oi3TBZ)h zG{zLB7LFPwbpHf1faRE5K;<K-3IglGRHez{hmrP$K@}3HnKqpvgQ12YmJ?L<fD#+n z42DTeJzT*ID;YEyZ?S+1D@~?bOnL^l7}Jm={uifBacT*uX=GQWh7#?dqAWgM&n727 zIWec$P7kiG8k7=1jqC=73*sISw7_r%;~X{!`+~R!B+@}S3gQ$722fNOgWL-$?WQt% zGcYoMvP7&%EhBQbw}!Ek2{oyQF-&J<WatqEHTA(sdnMy7_Vm;ekn>hD7x{w=Pgt2> z<OgyaC^;x7G=K}%Uz|4Ssd=dt1w{n?2UFJsG6OVU^5X@=3x)=U3&L&}gxxl9Om&~( zu^{E5i1rl`ZHO2$iRoofngd6X0RyCepAL#7AwnLW$kZbo%uwVDDxZQuL@3BTD1PFy z0kxPRk*1D6(%=f4L8d4(fLpB>_}w9Bg~wF(85|2#E()k$5m1MSUEp^I`$dx%+z7uV zkd~8JQj(gNni3D06u8Cb2pg;dx8ETp4X6w*0(BCLK$BEO;4%l4D~e1(egJnrK&^I2 zIm8Sua>20$7AOXLF9BNoLdqgg1Y?v%P(hGiHbeY!gPR|c>{hU>;k%;YenH&hqPWKu zagPh!Aaqwq;R25Ww5DR^bZ5NFFW6JwU)NPPBV|tJMShJd{2Ct^n0dVzH;8PJg|KeO zC`{m-!1+K%e}>B(zbi7}hU^6y&kHi1J3{tELs%0yZ-CPUBn|BFyddm$QP}N@u-gS5 zw;QnVy}<9jgJloj1%CI7{O(uy-7j!J!WJbfgR%*@o&XKAfHDOl3&Tot##<cm@hO?f zpzfR-$nzjQ(9q%mm)ylAi6yD=@l_%y$pI?b3ep0K3`h&2_5z0tIEqoKD^L`GongfQ znzu!6;w}JL2g}KDx(2ON4VoK;Ihd&^4wNz3N()jFOH$$W4%j`&#m_CC`1s<~60kU` z>k*<IAlJ)5Y90=r9^UI5GM6}HW`thkP`<*Ud;x|aK0<aWsG0!#C<env#e&c(2d*Bo z$VF=!gTe>w_Y|}eDwsi&8E@eX&i81A^F(mr49?}Cp@QPfDo`kaO0yzIkbgl90%+T? zC=%2SRfI(>NNF)ru?)}QeIR|%a#`5;0vOFGoZvXc4Z^-4Yzz*gTdZIsU`+&28wk=% z2j^L|<W-abvYZ#i@@|ktCg2Epz%SfW1#07&+yL9Rz-5Ww1!3ch!p2vGjW6&R-{qGC zw-LfG^6OsV*S)}@3wA=05(5K6ND;`BFJCY-Fx=t-x6b214!gyf7Y}Wr-(oM$C{0Vt zNxj7ln&gGd@}=BjNi9pw11SSdWuz7r-{LCB%!`LiuiWBF&M3{x2Ah-&ub~+j7(g{L zI5DKLfF^m{Iof&Jd8adUBK72ob-@$7j4d3U4A_%=Cqov<&ERB!+G0RYKAjBlaFr7n z^CpylY6Gx728Jw9!UVGyfT~3>3z_Id8pA`irAVt2X=Jllxdc99#{lvP+>R8cHE2D^ z6c$8V63uN+C7>29)BznF9SmtqDXc9Vs1w(<oGENA3|&0PeY6FjFoo(vP$}%l?w`$& z!ht@9$H-8Ea12`eu4pwALk%Yr$T#q;nZ*k;y^{ekQVeQobuwhZ$1*`JE!5C5WvJys z9w$bOZ>DgftL)<K;OXE^V@ly_;i%z4kIh={61Y7K;Kdy^+~{hMeVxLzh6i<tMhY*& z%edkq1++j0ZLFV>A&*;`!H}VtrJM;e?#ajy$-u|}Dr`aOQ5#FRRhNLWIW!niW41`R z1T@YCmCJ(n!BJJ=i?d=y%F`k8_;LxT@db5H38>2fWp^@U!RHfd&<f!`2GkhsWQd0c zcnPQpf-nP~t~wb?K%IGn3|vPIV-0f+OAYHXRtARE@H|?>Rsw3hLe<x>ui;z9#=x)| zp6fap;z8YfuzV*&FoPyPYPA3|2;3laL2eMrpf?E7Ji>(N3_%7()=SkePGstlg*Fml zeOZvzn$QL@V<xzP1!-16Tf%772zX)`TQxEdRJwy=;70?)1=&OhTHtur_(b7JvomHF zLL#n&BwX@NxZs^IBk=;5zTlkzF4jYeKn+ZAiw>oQ11g8Xjejd928O9j?F{Wq?aYua z0CM9W;ZfAISIdap<3se17r@I=aF9cZ8paex)LhZUOqzZiszK2QwF5zQvLfbNP$Le_ z4NRS^h&ic5juNC9qZGyx(2zaU&`z|JoXOaUUY0Y#6DmUr(ilM(11CcVO9xX2a|de& zLmF!ea|;LZd>nGAo5F%T|AlU6Cktxnh3Yf(k`K~FOX4U2B|)e!5alxVW}-3!@#<kS zKANn4;Isv9J)k5oP!<Fyun<trVud8F8irV<7$(r*YAsVIdks?!QztWM8n6{9_&QlT zS!Oe&Fw`*4W|+&|$%bfpr?Ei1)uWsO8eU}j#i-|}$q1e<(c}PkJBvW0LEzR}Q6Z?Y z%aoRMiz%%bob$l$EC!85C@3g2fB?8RS`-dyP3gm0Q)qb*Je!P^C1D-XwV)iC3hM4a zI;0;M80BLaA>>VE^#z6t5<f6AC~B=xT;aGPYo*T$y(<cqJB$t}?Wo>SeV`CTo^Uzi zb3r~5q6a?-&dK1WnWn%kj*`^e0??e;E%w~(6cDEf(a{6-Yj1HRB^HAh4newnpvk6N z0_i#VNr^e}h^cf?=c5QT$$N`4HLo-`wJ5P9^%iSUVqSVGcqHx?TX6<x?&TI+QEo|5 zYN{q1I0SF8rh)CO0QDg&K?EqI!694>it_{o2ZshoM<3h^t&+hPv`awYXat(L`SAnV zw|^?5az#exqKw`Z8NCUvcO|9gh|iaqC9@!PMf62U%PW$W6P%C)*9NT#zpiV0N!NBq z%AU-Nx*k__JuXUmUXk>i;PgOUdr92|5tX|N8Y{H7)*SG>Xzq8#-0y;>|AoNdiwYrE z6hbb9hFwtzzYvjpMImK^=LaTMQQZ$rh^WLLEfCqe+9q2=cNp$XKA^cXZ%^Kdtc#|R zS4<->YDZnsj{3k1GVCKbb$kJn9~c-V!6^knvN6c&-j$G>!@D5$qJ+*B37rct^y33F zcDWxvet>634(Z#vFf$xs7I%?iPDU<!K_w%&VguD3?TqcrsDrWK5iUm12p4+Efm*KA zGITIQ$H^GbRn{_~j+mw}gGLO|Ri&`ZVM1>iAkUr$Gib75*2&<K15~r)9+&E5szIw% zprr$1TuPG>+>3%%!9`)9)Cx+nsFg6d05HRmO2IiJGdVFQvnmx!Ij{wke!(>}q#U?l zn0mo5^+d&1tsOxJBrY0xT`}^4h#`~U{ESjs!lMh+(+4d)0e4Wv3AIC@tq)Of>q7$8 z`d|d-Uzo4KMIxvgK=n1a2Ww86ui^dLtsrlM)=`5RBnn;^z-U3?Uf~^qJH_^h9Z<hy z>3PA@bAjLmFnz(&6VuC}&O11TLWWDh9>(1xFG>Rqp))~Bc~C?m4_QFkQRI4N8^|-D z+4ly93vT&P6q$IS;z%u&<CYJ0z9tj61O)fLA*C@>Q7tG<fr?U17KkJ$eHDQVM{t;f z@}xq7LISw1xy6H=oT`+G2z}6yT5&$8qWRIla96<qIT>AuPPt&1deJcTiec(Sg|sUQ zX%jqefTIEuAuBvDD0p2|@VcVlHNo?)wDJZ`sDD!PF1Y1ibj!cumVZH|0ECK4E=reP zkuJSZR(?gg;(|y8*uzz_!Kta)pd}3@`H-17_?j}%Dy}Lv$U29Y3ZQuwcpIL9fdNzz zfa4Z4<u;XRIzu{WoK>Qhv6FcLv^9cCVP@uuOg)nD1bvG;v7jKQGCr}mGA~(^1)K_Q zv4V#cirPUHJxf7;eoiqsuoYmn4>*Ox$7s+hcEoV)9#Hhd(y~(Q1u!}hy1?YRvhgKl z;|)FsR4*!fTv7Ib$Xrm01&0kv_64P7aFGRChyZWuNPq_avHKUbH4QDeB;f<<pq2RP zsU@0_^nQ!62qm?H3oHd3i3dKmz8B;#P|E;XG8y??F!I?^xWRC{=_b>S=3C4!fJKl= zu*WnRZ?Wd47Nw_x+jN?2kRfMw&;pF&)RJ4g&|#s(+=86cqFdZ~rMdC&L7(LOoE*@g zXIfrS0Vu!9ftvte6Ck+*<Q}X;(x7pRB2fH+W{AQ23Rp7p((;Qy1F&f0)wh^(3vRIl z<mcxUfkpssv494mZm}mN78PZt7J<0QCAXNXG7E}8lQ)pu3QC8!xIjVXlb@K9T6Bv& z7~+AVDWD7tnjY5V12<xdK<&*UP{CT11Cq)G5qTgYA4Gt>1#Vk{eRhitoCb?;u@|Kl zm*$idgHvNs4=CtCO{)aZ>K6qC1rY7v04W1l!6~r{K7I%0P6X+A!o<Mv<HwI54GbS7 z7z9K>qj)Nu!HhRxJ-!RFi7Q0b%dL_F4Pal?bibnMenB?zqHN+7*+kHqiB7+-YzzWI zm}BV*yur}1bP(&VqV@`xHJ&?ME+{%)RCK(e=y*W;ilW~HmMMG_`JM{Oe_-Mf)cwGK zNql5x5K@>T2a%Uy7OZ6az<?mXaxn;sPv@S*eL==|hsz$%3o^bCbWy<Xih$n*0l%lh zG83(*Sc5c`GTxAsn<08Z-e^Y2oVqLWMjK4FSYD9#xghUzfaM4`gmqEU_ll(N2L>k5 zQpO8`;a4N0uS6zXNKC#MnQ|pE1uCAAa|4`X;koldSj+{b*o#WBSCnFBu;0}*grx8T z?iY-FE*kk<G4eT)awhXaeDVd&l#7}vS2R;Dq^4cbOuvv(d_}Wl2Fo1253C>?A?8EK zk6<@^0h16B{3K}g3(<<HX!ut)1`+9rmQyT0Ffa-#-xZOV;xo|?w7Tc6xWdHhDb*n1 zV0`O<o{CG)bzUmAf@KZY2G5I%c2^YbF38wl6nD5H?f_a4byrMbg~=Mb8=AUz_02Yv zY^gaAbs;d~LR9L7^z4iJIal;^Zs?lb)iJxFWA=fYRovnu1FN{j7ZB0G(!>3Mhe1H3 zgS!|s#B<n0)K!o92&W^Ht2paXZXQ=X=A+^)uF{-GrI|r&IYtm$9?aHbaW!H;YRc$p z#IDKW=H}<8$p<M@K%=CPb#$OnC~%f60u8rAR@8x6po$&5a1Pv0ECNkh6v=~fGN^yA z$qp{$+}t1o-yubrpi)Z+QU-vPf(rsL3tSq2jRY47U>3Ms0JFe_16UongaC_yJ4RqJ zgoXS?peo`PSA2YKeoARhYJ5CszNN4<F$Xjs93Ov+Jw84qKRG@gywa`63FK0D5a9(P zK(i)A@gP<*hyV>(K+3m;ph}Pzy813TH76%NekCJ#T?}{;1*GT!uR;V9pg<|+19iI^ z7+~-NlL9Np2L=$~!^j{mb3;<@hOqbzap@2I%B)U|9~g)reHi&z1wSyr2?a)0(4rL> z!N$m%3hE>yNH$JZ55^A+NTe7etLz5`IKjrqssiFd2{r~c;SWsAta=|9m|68cGBdCV zx5PpO1Q?{GZ%D}AkWsuLDtSXv>V~xZ4Jo+~!j`Ne9~g)u!1W(EfIz_uZ=rx{cLvZz zxes{K3Ue!3ifD>h3U3Q*6iW&pcoP~wXcJm0dx`+YW;2cy@f6_}mMG2?kzfW*i6T(< zEb$66bW<6$QiAO4DK0H2$S*1>1}(u?fK0z+R)N>MDkSECb{l1<=IQ37mZjz>fa_$? zo+Gd{Z2tnvE-Q!u*f&-<Du5<3A-3iw78FAk?I)+^l@#S?f^1UA%uC4xZTHGgQ%KG! z1?}lW-UX%y-^&H6??8L1;Cev|WmAg_^7B%PK}|-`!vDmw)S|@nR0Zhv5a=E=*m{9t z(6%*@GKhl_MuYtbo<zd72PGsQEi@EB6IXf)Ajd%JW>7O0Y=#18^G9N4Ua>+^erb9} zP9?ZeTMXK0l~<aZlv)JZWmN()uNbtQEg=D{3v4s;eh2707~!ozAkP#-S{snPFfg4- z`6U_9h%E+3DMS@G1i;%Sph19l8xW}R1D%B<!zoFrpv_(2t%Aw<d0C}-$)Lr+3gBIB zuw8bL9gKN-dIgC^i8(o`IeIRc#nAnIDWE1*08~5yB^iJ>Mi!-lR3?MA;3bwMDu5RM zf#RVgUm;PUxHJj8Cn^mb{?PU%BECUM3E%!F(2OG)K2A(YQAn*QDN2N=>5_Z}&^l?j zD-=K`=Ts`BWR_(XgEw?0CKu%wLw0f%r55C5CMOo-bSHG{7C0!}LW)2Q&tHNrnaL&5 zX*v0cB{~YAEj_VFH4Iw40<Ka(^+htM69p@SKwBrkQ>AfC3=Hi|(-}HJn@3=>kj*3T z4p<Fn^9X#Z6TEo@T7)q$ATMf7VQgWjVZ=V+iP}LyAJpk%0FC0JY*9hlpwhtv88Sk) z3waX+$|5h6Z8Yfi)G)+@25iCpOkqx8L0)#64B9XQ>Uo1@YZ&4|T?iN()bfY0S&I6Q zht(02m8d>M-Zq1x9@NDEn}ner$v(tl*czmTW>rj}g@o}4w=m#P$Hu^r!ki6`qayPf zh6=_kgdWx+rWBSu734`%<i%~sA%bEz8v_HV?ZSXIbpcwQo6Ll86DUj(TW~-fP)%0U z;W$vI4BVGT9;X3Ce=TDzQw?JcQyLS}$_eoD3E0q6I;d5`1}Vj$qfd|(GLQiq6=-z_ zU&fC#zy=>`dJpOufd&{F7%phUK+sN~9WDpdR;X-XTOkJ#xu6jPuDnrt<)Argu*=tg zrXU!hqYwcww<FJUp^Rjr?QB9`bW#G!h~VVFz)-`8PgfNy14Acs6*qbWq@c|vqs~c9 zWa<e7Er$g+OEp<;G3RFHfk*RhG3O>$++r;PZSjB(fE0m(w+OV69bB3~M?X-e7KsYs zkDw3+4X=SZo(zmqzMv)=oV+QgH6vw#+gD}=X}P({3)E(2&&ghEytZ^h$X@3IY&*U8 zcwaPiKcRKeG~}Xw=oS6Y3*iwLwIi=+M_!bQx*`?z0mDFWJb{PLAfAM_w!y_9xMdA4 z0q1~{4l8K!YcZsS3o1xK3rxV3acc1`{=E2-{F20+cxa`0i=`+rFZ&i(9%#`vxQGU+ zhDsLA1R2KxI<)|-iVwsp&o9bJ0axoqpho&F*3^Rh<P1$V$S?rNK5)3A4FiBDITXM> zdT@Up+)l3&Ku^k#K!K_cX<>g5V31brVCmt%Aub2%MBR{9>tMOUApzZl@>E$3l88^Z zpZ7iGd(!`m{{@YhiyARkG-56&$6n+BZBF5u;4;PM0}FcWK!W$Kp5X?SEm}KL_T*gD z^S+|z{ec;z@FO_vzktaOmL9$bre-@BcbHtU_P@Yk1ls;G!DNa(XnD{BZm|yxtelyQ zcO_)z@Xq9)!{6c3<9Sz3>581;MLFXua>gAlJ^nXj6|cw|ZV1^De^J&2G~RH7U-$~Y z@`98l`4{<3cL-kMx4OV@bwfa80^bzA1tk}hG8QN<P~0lKA!JMB0g)??p%)@zu0*6? zbWFcwntstR<BDO%MS%>E;v1r3plvuETpe8C)Pa(VK@|YF>a$}8uM%QyXKQC~=Rlp$ zz%@_Z#oo!j0A3YBGcK6wL|WC2I_JU2&<QGn!NoC1X$m8>&_swZr86Wm)iQRmb}}GV z4i)o&hT1_oKp3&oIgh1-J&h4G^IOYQ0xFY0(hLkptA>!*Y9P--cOtD~Ms*`To(sbS z##oLn4rJY(9EkbpF18Lf@R}m#6qXhaWV<_&DlcRmsJ5Y3(zVP?3^hzB?q);Pfy!F| zuiT&k0j6rub``oX#4f32sbTD7K&&;YVgs+K0*$PJ^<;x%w#c}X75g654z@H#(7LG_ zmIa`3M6e!Y0<}s<_ZO<G85vM~$cif4iM0O`>MDEW^*tS|X^bgsEgYbbLRO1v3gxa$ zW@2Oj;a~>PnhQ|6t!3<4I)Sl=3tY9c`+>_`aOsPZ$>5bdXaX5D|AbsQA~IJELnq@J zv{|=c22Cc=Su>oVx$&aJl6>%SFW^qYEsmnZyp)2}qFha;TZ|RA7}Fu+*pTVrUmP|$ ziMdHBiFQ>=NX2JKY7xpBcc>axMh1pr&?wK328N@iN9-;H1z(6yxZs?4(K+#ob7BJn zX2}7cR09p0Ol5}F{~D;1YMp4ceGOw37Xw2I1BmQoL3q8B8IglP4Z9Qu(87g@Og);x z3`L;j0I)?rn?OTItdJ=R#w<wv3@RAF)k-nQP2lARkjeu*M}b^RWB5L^7_t?B1LS{8 z&_qxJ!v(1v2s)8C*LeZkOz%0~D->t?uSmQoqrbsri{AmmD<-ZNrCm=jUX=EPsJtMR zgBd{ZSXV%9AaT_)f~I2--kr$Q!wsE^L22F{28}_1+8@xi9VA*Y+jcnp#0&BhXqpT( zji~H)0gN^%E^u36xWp5}yP)ib>26R#44!TQEni2PA?87MIdo!$7nJzHI~7pe4~iAg zyg^BFMrtvtAHY*A%6L*GD6xZfFz|!C09vdEUA=HYKJ0>g*owjh>?;_Ta6x#;B-k^W z!bPCjnOmIhsd=Dv7x_iExN{TpN<poe)YO!souGgPHHdDpC4v`Z+~UkENi8Y?&2img zO|DGNNiC`esR8ep0=HB^sjdjLZMz6GH(Lanm%hc8SWu9fmvW1(Bp=kAE&@$--eLin zq{#_Rjkj3AO(<|SO;3$a%e%!5-XRQb6cyiM1-G?|j)80fMRU;s5DOG);N88TNeu-D z2iUv@Xm>L>rcoM0V3EI|#?Ts2V+b<6ahFH1$NwUa>=hna@NT(&-Y(t=DO0j8awuNm zP`tpQc!PtdgR6&YLSiRBh<+d`HN&ZcuY<Lt`~w?<hR%|j3&M$0O{dsQu(@EF2uB?p zcLk-U$S)OLTD-z!jm<@Mi!16D7Zok9C|X_=w7Mc_^?`wlQ~D!_=y1FtDmf))f#Q_- z4!0Yy>;%s$SA!!iM8;l;Ouvwkc_lLIVsQ4A;Oq-hITxjJu1Mu{ct4O-oFTDPc|qDj z?Iqe5CH1aI>Rp#Kxg=?_A^M`E;}uEA4-9O)(qLi&>jPnl876b=FA8g|NLiD4N!a{? zu=x!U>FIux{NQQ)g0kC&((N^yYBttwsk@-;c2U{win7~95%()1?iWPd?+S}eD4%FE z#b$xY61z*nh8Khl?@G%fr>hMf8$5P|?1{T*;&a8s=ekMoC6nNbCZShMLNCaNU6c>I zA|G~9I_!#c*aZ<3bVERNhTuf539J)XKk|ay%*n+m4Gt%8N=2z8Km!cmmKdlq#jz^_ zoXCpMSFD3Zu&ekH*$KRJPY9HCKpl9<7KpkF9I}{pg0ec;PSDIDYMT$=hC*;=*JQfI zTwI!41kM}iP6AD=SBb-%gw~l51vw2gxzNDy6x*gka1Oo20y?_}Wy1!jJpy(uXvyw$ z$ax>|1_!(l(qshdhi<_Dvmx~&q;m{9pP(cj+!?77ggLM{6)GeNavG==*}wqZy$)|S z`)M+}xrJ!*fCrt5R)8`qcrsHC!~zv3khu|XCks450q$vmS)c(Y@L04a3)ns29uZ`o z<T|K6;{s1x6fFXov=~Hy7H)yNK1G*7Tu=nx;(#6HRs;&%qMINI@SZ8qK1@h`2O91M z+jACFB=mzfEFdNzgg_GzAi{t_QVueZ|AAMMRr~`37Q#%JRr&)1oX}!ql><!_KnXSm zHogx`u;~ZTL;+t*1Vn(15u_0Z0ZxHn7oto7fFc$=1)ziFJUZ|e1*R5`C>Ah_xrHN& z6?}FaTQF$X=UmVN!>8Z@K}VEh-trPlGRsooXS9KvOwc3RK%=4Hlj0!L)d>ozc^Qd$ z$*C!jp;^d5SPBJ2scEU8+N%gM92uONs*q7qQedU8UtE%yoSk2mT9lTPU#^#&pQ~S3 znpzAR+%48OH#RahGc(aIs4U6I&(j4}W#D$3Zb4D1F4#cOXf)WtAk&Ji^!3v-OEOB6 zz~=acdAfKy>L(VYR_JFI7ni0M>l+)GKpcRQ89+@P@L@V0(AEVL%5gfVjc-IlD+P2w z2oq@Q0QA5dXxM`qW#G0ZtPWQLr7uv`3!V$qWC2%cU^e(L3drmisEGqw?+HnMAk~nq zw2*Lxk36Y@ausN++>Zu^8yph7texyV>{mD>E^vT063;M$&=)wApyx+)@OAKklL|@! z3Gy*G`-8F_dMg^axI!LMLJfxnpaKtGWWX4xYEXxaVEemRZV3iJ(*wL&0SOIoK!LI; zti%D$zd}kJXp;>ji5@QCnp+DLE}(r1pw&nG3JXM*$ZZwfD85Dfx}oDGL&uAT&Q}bb zFY>!w;di;f;Q|g3O?Coh#ZpkbfqYa9s!*U)lb}pe1R`WXHiGuo|A3VX4GbSxSU@EM zh~QxcO(tR?xENVoK?7GLkzfadt;L?(LG4SVvnSb8m|7U4m_Z92qgYZ{z*Bv!psBtT zP)_G4x(D(ZXde~IQcO^cf>VVT_@D|<`w14Wh*Xb#kfH`{^cI>UKqi8XKptU73^<^7 zrBRNV0?ix1XBJXG2U5X@G?5RLLX1=|09Dao+mH!R{DInp5V0a<9D3nn<Pdcb5>;;v z17b9~hG7AyYJ(_4B2jgKHrjwof)Gu<Tbv~sMXBIZ8gH?MfSHhL3B2l=wXig`H1!s1 zAcz7V0&$BiB{4NOKM&FXXGtziNxa3ASsb5OmYA6XJ`t5IxTGjGG4~c*F@$C<E=epZ zK`CB9%Y{I-9i;Sy4ZK2XZ?NrEQW#kgUep+X5;$nXb_2s*4#6uN64yBtFL5X?P(eSV z=BcREl;{N#7e%$Mh-!hx$DpUt+z<mDTEl&pTcF44I=9j#Zl#OdDp$BcGvu6lcctX# zXkC}mz9gl6QA+oUlx~MhkM{!(o_?+_u1=mFo(?bsr+bv53zQYXi4>GJKy5o{u>vk^ zG1_zB@&dab!NrCx$d90O1#a4PaAVpBDwo0bT?5alBM&#!Fre=iDKbModkwMQkC?)8 z0mvq#qy%BsAe}^jItIfCI#B==2w;T^K%M}zkO|b}2wLUWz>b^&nixUnpR8o^D*_$N ztI1j904f+jUB04cpn+(<<kF&|)Vz{-XcFTtPt1gIz*>qx$2S*&c8}iT4KB$q0G|;G zs=QZ1jw&g-1ZqBkDn{srRM2MRywr-4_;~C|4<hFPik2vFqYHAb2+}bmj*OsQnb&n5 z)k{387kSjL@TgzsF}}oOyuoFQ_eCCuD?APtcpPpBh)m&{&NqqgqJY8`0fi3M8{7gN zws(c(FYw6U;1}uO!Hj882!dm}jtR7h89Am=!?DPZ{8%nBz@Zmw?3W-FOGtZ#P>uyg zPZh|!4Y8!qDjfEMMz4{R4w#L6k_D<grVQZp#|c)(z`)?b5NlG)Sc5bUjD3e^4I_?G zRix2VRGUzFj0`=doZ!8VDQNRkxc4vS*&t6o($l4c!y^Tw;sp1;-huiueBfoH;0geo z9gCiW@+23ihn13AmYJLio-Hcc4$8COj0?)d;K~D>EpIUwl$P9L2Oag0Uz`eQVSPf+ zj?6`+c~zpAl|WHxo(CusCNYA}4*JT*z$4sg*#lax$7wuQbdJ<@NrOw01{Wobu1Fez z_HY|RGo|7s9>t|9OLQ0NFVVlqV|0bb=mL)sS{`QOw7V-PHbv^XpwcBlr3EHStS<`c zUlG**z`(={TE7J%Z^$ani3Y6#1PL$-Ix$Xgy&)no#S1hTvA}e>?IPO^B3tAxDmz?J zcDN|wctynV0vLT@1}Xl)3^D`RypLeBzko?(aa?T3!brGtkd^)Tz`-CTH%A(DfSMhc zn7|4zZf2Cuubox9B4kb6MR}Vm@-`O*Y_AB|UI3#T96UW-{d`?~up{3taL7PVF{lfF zNYK_<n)$Fai?clYVI@Xqd3Ha@cr8Xd71TR`bZ0+<;{FGSK<mGPTX-Ns4-|`_V?dBw zsoboh9~e*xDMrxpGdRJ<22uhi1b9G;-7pDoDGF{*qEynLb|1JX1&!CD4~C#-XlV7V z$yfy1kFLpBv>%j2LA5-znKA|BI}i~L@(HNb)xdC<TVR4<r$vuNgFn~>nuef-ifN@K zrA4Xn@kJo(i%x;`fd*s1nW3lw#08Cn7d>QPV7SEvT3eM`QIeCH1YONtQdy9hmtF+w z8Wn-6)gn-RPy{L#Z;2HomSp4?>*bc_lw=}~*S^J%CQvjTWC^JHyd?<fBqJ?)DgqB@ zfaiCGzy}6Gd(g@Gxu9kqs3g6`hb)nn2U#5ossq3)#BT{BOM_0e2RRrNB9QHIBFNIP zHBgW;1T+wKOB7iivA+%!?vV3pCD9xWI-MWl$|CRzPSA?bqN$+ZV+C!vD~7CS1+7m7 z4@7|bCq<wMWpIjstXM})m%lh{Aj?VZir5($7(mfn?7_sq@PV0;k?{i?1EcZ<1|?+l zfI;8_4BcShYyiU>3_J~Bc!Pnr0Ss?2@Hc?r4VdB!3<5V8R4<^S8w`3E2%!fI$`?=( zl649f7*Nm+RM%c$P`bfjegQYS!C-L#8@j<@d;uG}!C-U&8^ToofK#|bYJ$f_PT4D* zvJGq>*z%beMLsZKCp%Jmvaj&TUEx#v2v+e0OhQ$su=+AGN`GL$P9kdssrZ7dE`f=U z5!AWGPEHV=B7H?r@rt0%M+T6JFJSTmgj7;vl>NYfNzCB9BBAjSB=H4AK$HYAGJ-sZ INq|cO07RSj_W%F@ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/embed.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/embed.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06e59dca4554b13420c432192952564973ebd013 GIT binary patch literal 13204 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 GJWl~b1v`BJ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/embed.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/embed.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50a582efc082811b6496eeb81a30e62f80b7f484 GIT binary patch literal 19798 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 E0ISx{od5s; literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/field.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/field.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67521b6cccf3e5ff86e13752f33222767dc10c66 GIT binary patch literal 16475 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 R$ODA}%mVTZ^#W-kF#zWj;Vu9G literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/field.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/field.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..448dcecae208170106c7fee557c7e348e4ae066f GIT binary patch literal 24575 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 W(c%LGCNV+uBS`cMh(MDECu0Dg{q<o0 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/fn.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/fn.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d4582deab9dc73c2dbc769f06c95e6ab6002084 GIT binary patch literal 13456 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/fn.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/fn.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b894334d6aceb12d3be2fb5c1afb8363709ba8d3 GIT binary patch literal 26506 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 W8LeiBd|+T^v|6A7rf?GA(iQ+l((*9? literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/logging.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/logging.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d47f1e45e93b38ad9f76e9acb3bef318cf82085f GIT binary patch literal 3238 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 Cq2iSQ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/logging.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/logging.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f52d49b3cbff680cb6322a30b5b1986941d883a6 GIT binary patch literal 5351 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 L$TYBlAUN&;ZHk}Y literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/metric.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/metric.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eb49a374e350bfdb86f44ddc9bb384ce41fe121 GIT binary patch literal 10873 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/metric.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/metric.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d685d90d287c335bc5300af1b9cb989c3df9b65 GIT binary patch literal 20588 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 a#2m^9auIfNg4#z0kjxh_`2m9j#~lD?=~$!y literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/optim.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/optim.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf0d056ae56044d19b2e5e290f45058425bc2af3 GIT binary patch literal 2798 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/optim.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/optim.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f34b83e7bcd94eda11b8b415630ab6d562cf1c79 GIT binary patch literal 4195 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/parallel.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/parallel.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d12400edeb441199d157172e73705a9fc94003fb GIT binary patch literal 2976 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 a4kjK(9!3#nE*>sk9ySg>4i*j;9!>yoz<{X$ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/parallel.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/parallel.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20c67aea66c324dbdeb02c9220e11cd0318b49f8 GIT binary patch literal 5035 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb268708f3777028bfa8541824a2616c07fc8b52 GIT binary patch literal 9291 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37128ac854fdfde72e08c626b1a6cda83b86d673 GIT binary patch literal 15768 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 U1csaX$N-l60--)&qri~?02)QaGXMYp literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/transform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa125d981767ec90dad382896177289419f0d04a GIT binary patch literal 9574 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 Rj66&Nj2uh?%mNM~jsSB0r<VW# literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/transform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd491045274e55fd2e1572e2fcbdf56acaec5e61 GIT binary patch literal 15399 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 literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/vocab.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/vocab.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89fc3d6b458d28f39f20492fa93b0fd4981e51fd GIT binary patch literal 4122 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 F834(3r5gYM literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/__pycache__/vocab.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/vocab.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37a8843712eaa44afd7d45ac81dfeef4e4038e50 GIT binary patch literal 6223 zcmZ3^%ge>Uz`&q%Up3=47X!m%5C?`?Aq>XPK@1EG(-~42QW$d>av7r-89{8O9Hw06 zDCS(2C>AiEIfpfuEs8CdJ&HY-BZ`BOfr-JLA%&%dA%!)Sa~U%O!)j)Tc?=9uTq$h9 z44UjOK?0hLx40AY^72a(OEUBGiZz*Tu{-CN=9Q!t-QrG3O-n4zDM`spF41JZ#o<|! zT9lZSlX{Caq_hA;h2~}E=Ou$ofnlf}jGq(0Zcb&0VoYI(VoG6*VoqUVVn}6K#=yX^ z8m5{dg*lBmMJk1-g*A#bg|~$viY-MtMX-e>iakZBg&~R~MYx3_iZex|1>|PY7KSM9 z6qyu>7M3WU6v<!)P1#$lVfo34Nr@WF3=CWf3JMA?scD&csl^J33S}UP(wxMiN`?HS ztkmQZg_4ZK5{2^2oE(LuRE5&w)D(r1e1*Ky+|;7X<iwoJs#JwUg|y7noD@ASuvv~p z>BUxH7RcmeNT4Wa)FtQV<fJBpLrV`DRGJ8NAhlM>If=!^RteaYCcvDNk)M;2nU}6m zl98&AR+L&;nwpoKnOdxnpQezSn4F<dmY7qTs*sjnnwO%GnFm&ul30?c2X|3!W?no< zqk=|eUJ05DLNZbnax?QXb4zpKhF2=&rKYApyq%esoKu<t@^MLic4{8X0z{zcfr1hg z`Bn;s2rG*VQj;?ibBYx-z$qZQxTGi+i_JNi#U&trK$R<i?I>2zNYzW%(@`i$Owmy& z&CAwNNXjo(NX$!7NX;+SM2((;qSS)aJg8$qA%xXs2?^1$2?+@2mF8u~XXd4(R^SQ} zh-7{m$a;vYko;)?i}#X}qRgbyl2oMF&n(GD;(_AWQ32*lu<sO#ONuh{(u)<qR-~pV zBvpc<EVBra!W1%7Qu9hO(=t<wiV<!uF3HbCO+AhZSkn(uW`w7q+{A(ca2f(fBFqWM z$r{trmy8Sy3`I-~3=Fr}p^3VP1;pckC8%4>nRz9*IH0jtT*MBN<%9?BEw-Z6lG38Q zWM}~e&dqEL3=GT+42+*M7#SGanc7*VGn9ZV0!uP5)G#k&WMEhg7pY;0hqFtN%;{iB zV@zRe;lNN0Em#;BY8bNM>;)iqLv27%DNHR4CEN&p4MP^(E>v?}7*LBNR9Qxb8V2k( zbTFkcrZBf~)G#gp`5R#sl!a<4AzM0GY8c`{VGPz?A_%6yL=6L~i)t9+Il&SP3=Am@ z!3>%#eki3c$eY5TNZ?>#V3^7{ouQK<m|-QO-%5s+j70(r3=G8}6%D^U^fU5vQ}sbb zeqvstUQ$kCN@i-2esX?pLB4KDYDI}|YFT2Aeo10pW@3DCa#3bMNwI!$X+dI<erZW& zPO&~XH|iBs{^GF7Nz6@3Nwlj{0GGsi@$s2?nI-Y@dNw)v$%#3|c6u-s3LyJI-u%(P zu!6IJ;WNl5$sh-T7$6LaO|bK&z?DZPLk&YLM+_4KLoH)1Qw>uM<7B2D&R~WjQBVQ~ z5i6N*G3goHV$8h73eJSZpp>DYpim^vz`*c}%LY_&fjnhbrG(RUa5ah`_sKCZFf=e+ zko16{g%t}5SE$ZVT_6bIUy$@Dl4M|D!0v1{XsD-y9L|eycqel<IEk<4u3?<W)We7D z1x=PB8IX5C7T;n473W2~Acug$LP0^H0p=A@VME9(a5YLG6Vw?P7=AP`To4I@pqbS( zN*AOY5IG@n$uaPPW8j3)3t;+!V<6a1nq0S7KqlN`0Tp&dAQ#_a0hLa-*h&jh5=&BV zai)T6OAwPavm`aQ7@VeVG3TV_-D1lFN4zHMEtcZcoU|eykf%UCDdGpQz=;oJq=G_% zLIT)Rw>V&FrHT(Vc0gfKya43<9}Nt5MI>fOO!S-L*TK@mc~?aKf`TC&T@*38B4PxR zxWU2G!+D)U;u41hB&N1n?g-fvdC}PYin03zNso(?9#<qiE^>HY;qbh`;dz6Dr=Pov z8xk-Oaz*<3+*P?N^Vj5G5DB^{5_Cl*=psk(6^`Hw9Kkmvl{#2@`0k2H&QO_{IVH1$ zrH8wNyMr4XZYXI1lmNlSpcXg@qZENSi=kkKA`u1#22G|SO;A{=Fff4ft2QVSLD>V6 zoNuwm$LFNx#m86i!a@to1tq#-Q1CV|+~pUVU^2zBv#zJ^0*5TvakrSWQ!9T-f*Wel znRz8Tpn6J20oIa>g-I2c6zM2{<>6Avpeh2CEkPKR9Krtj#lXPO&VW|9GnOE!UB<+~ zuo})U;_YO}g7az^LAeKHAOk}%Y6Zbqf>e~Eno$fg1LOj*Mto+ZAeoQHO?({;X^bgM zpaLAda1Lew%Yh4bOgT*!KXA>766YY7fr~9roP$bTaQ^47W$a|i0=pPQAiH`ZQ;z_& z3|PrnqzZ~|W=JU@3yObm#DfwNEc+LM@^h6cEZWmkOF+2~wT#UyE&&%0`V0&VpXEV$ zr-9*uupR_02%O+D#dAjD6dwrxg0LPqbx_S4nv6xDR9j>QO0(oT-4Nt?a}WVaB$}+Z zxH5|~^NLFn^O93<F&CE<frF|DluW?3X)+aof~v>>WGN_#B|viucYHiNjH(1Nf(?|( ziaQ}ebeCInLh@YWi`?>8xaB`Euyg9)5Eh?eIU{(A-31=SyMod)oR>;m6x6yRsP%z? z6-|~`d<OFj$2n|EnJ@CHT;Wyuz`zVr0S)vE!g?!|F9_>h6xO>UtapJ&?*S}2Fk~Q+ z0rCPUsemwu4bE?%f?+yC4Py-hA}y6MKue4wQ%JD^4hC?k3DO6x|8DWb$0z6Kl_X~7 z701U{3BkevA!ZB;I8gE2z;J_KWCqI|&I|mC7dR9l&H)uYAg6#ZC`!T3i6Nm_t7Swh z{y>fcnTFn~VN7APVPIgWVGL%_Wby;YvL^E_7EsL$sw6;kd^|)L66Lp86H7{pii<%8 zBKbBwwWPQtu_P7Qw+JzC+5}aK4Gd2OL?(nxiM=SGd__RHgY~I|%#4sZku&+{@OQ9w zq;>M%;1}uOfrJ9c3b30Q7#Khq9UKavx(U4y1Q#0^Emu&xWdU+X!pvf*VN78HrE`b? zYCDgS0o2+_VFHB;a`B1FBy`>2wjnc)wxJNTmC}inqG0Js43zuyK*<8+W=P|sNP>ZZ zp-Kgoe2U?LjM>Dq1L@?1<g5iIOY9mLz<~&fI%aT_q6k!96*+*?Ei*X#-eLvE8CVUt z{g!|fqX^3o=@%hp3$iX0V%=SSsSDDEaCDL1=nB742Me^KpWr$}ZHn(j4y7v`N*6ek zZb-;LBbtM!hxa;%%q0$)8KD<Bl&^3oUw|R7(@{!DP+9=TzX>=OAZJPJF@xF<fCjQA z6WFgs8Yp26DZ0RdRosxU1{Lzf&LBU63IR|a74E6*ukWhA$ggmPU*Q6W0@#VSSi!CF zUn-DF9#(&Y`{p{3R=JJ>betj<rBVmQ6xcsWjGzG~l-!E1N@uTOL{#auj3uB(JtP@3 zlz_~HvTGPo)8ztC`wuFIplTShKqWd@098FIuNG7Uf?@!yasiT^U;!|JZX+Y8w+J_V z0jO65R)<WaFt#w12qQ#l7)wB13#b4d*P%3X(3=XVZU?yoT(+SkCs1($ZZ{Cy-6@g= zB?eGg4C~_*foghK*9+20N6M9;f)m^*@B!%q)eoSqO~?gF5JK+SfcO_AL%_*Nle@?g zlrll%lHh9g7F%(CQAujbE#~6Xl3QFUnQ3XMMX7noso-RMi!HUHBsDJulCMF<E4UF0 ztD8MQHiKdfnyJCcs(2s?9O7U%kdg`Deix`VPMsTikz4r+xAF%DMo#$~B9c?QI$WO$ zh)pe?VLGvDO4W67olD|6D?-*pUKBUKB5r<Bz~YL4MF%TV4`7DqMGpBZ9P$@9<dH-n z-rj1tBlM{A36?XQ2mOxtT{I59VjO%yGUTFU$Q8+uiyWa>I6^OQgx=s6hPLkgG`S#s z8BlD2yJkgvpx^;jo8W;Fa32UF2I{#Nfx=Cb1>7hp0=H<uqDG(skEI9{97UcW{a{hB zT3%2cmzS8E8Xtd)D?UCqKczGW#O8^QFDy;Wfy%JQ$EV~c$H(7dEdh<a7U_Tt0X6oD ztU)YLQCQ>zVu6AaT#SH&8q!w=)idBe7ua=Rf)f<#yTGB|zyN_Cn1on4J}`g?4F)Ug z6R9UsPo|$qzmSpnfq{)x0V^TE$SU`N0Zy=Su<CzcKqW*NS(QLapadH$tLO&?IKjul zs`7yWPVg|YDuNV42{v|Ckq-<w2yk)*d&W<b8x(YDr6r|Bsqyhepe%BW8)=*tJirC6 ze{QjrRDy=gAk9cnDN+O~7H+ZSg9nMh#-Rn;FAf_>q}UZjGB7ZJYR2MT1_p)?%#4hT xAJ`Zel`k+TA)^NjIv22^8w{EkaH9`wE{u#K9~iKc9c~}NGGD+XrYdk?006WhY&QS^ literal 0 HcmV?d00001 diff --git a/tania_scripts/supar/utils/common.py b/tania_scripts/supar/utils/common.py new file mode 100644 index 0000000..f320d29 --- /dev/null +++ b/tania_scripts/supar/utils/common.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +import os + +PAD = '<pad>' +UNK = '<unk>' +BOS = '<bos>' +EOS = '<eos>' +NUL = '<nul>' + +MIN = -1e32 +INF = float('inf') + +CACHE = os.path.expanduser('~/.cache/supar') diff --git a/tania_scripts/supar/utils/config.py b/tania_scripts/supar/utils/config.py new file mode 100644 index 0000000..28b18ad --- /dev/null +++ b/tania_scripts/supar/utils/config.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import argparse +import yaml +import os +from ast import literal_eval +from configparser import ConfigParser +from typing import Any, Dict, Optional, Sequence + +import supar +from omegaconf import OmegaConf +from supar.utils.fn import download + + +class Config(object): + + def __init__(self, **kwargs: Any) -> None: + super(Config, self).__init__() + + self.update(kwargs) + + def __repr__(self) -> str: + return yaml.dump(self.__dict__) + + def __getitem__(self, key: str) -> Any: + return getattr(self, key) + + def __contains__(self, key: str) -> bool: + return hasattr(self, key) + + def __getstate__(self) -> Dict[str, Any]: + return self.__dict__ + + def __setstate__(self, state: Dict[str, Any]) -> None: + self.__dict__.update(state) + + @property + def primitive_config(self) -> Dict[str, Any]: + from enum import Enum + from pathlib import Path + primitive_types = (int, float, bool, str, bytes, Enum, Path) + return {name: value for name, value in self.__dict__.items() if type(value) in primitive_types} + + def keys(self) -> Any: + return self.__dict__.keys() + + def items(self) -> Any: + return self.__dict__.items() + + def update(self, kwargs: Dict[str, Any]) -> Config: + for key in ('self', 'cls', '__class__'): + kwargs.pop(key, None) + kwargs.update(kwargs.pop('kwargs', dict())) + for name, value in kwargs.items(): + setattr(self, name, value) + return self + + def get(self, key: str, default: Optional[Any] = None) -> Any: + return getattr(self, key, default) + + def pop(self, key: str, default: Optional[Any] = None) -> Any: + return self.__dict__.pop(key, default) + + def save(self, path): + with open(path, 'w') as f: + f.write(str(self)) + + @classmethod + def load(cls, conf: str = '', unknown: Optional[Sequence[str]] = None, **kwargs: Any) -> Config: + if conf and not os.path.exists(conf): + conf = download(supar.CONFIG['github'].get(conf, conf)) + if conf.endswith(('.yml', '.yaml')): + config = OmegaConf.load(conf) + else: + config = ConfigParser() + config.read(conf) + config = dict((name, literal_eval(value)) for s in config.sections() for name, value in config.items(s)) + if unknown is not None: + parser = argparse.ArgumentParser() + for name, value in config.items(): + parser.add_argument('--'+name.replace('_', '-'), type=type(value), default=value) + config.update(vars(parser.parse_args(unknown))) + return cls(**config).update(kwargs) diff --git a/tania_scripts/supar/utils/data.py b/tania_scripts/supar/utils/data.py new file mode 100644 index 0000000..587b32d --- /dev/null +++ b/tania_scripts/supar/utils/data.py @@ -0,0 +1,344 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import itertools +import os +import queue +import shutil +import tempfile +import threading +from contextlib import contextmanager +from typing import Dict, Iterable, List, Union + +import pathos.multiprocessing as mp +import torch +import torch.distributed as dist +from supar.utils.common import INF +from supar.utils.fn import binarize, debinarize, kmeans +from supar.utils.logging import get_logger, progress_bar +from supar.utils.parallel import is_dist, is_master +from supar.utils.transform import Batch, Transform +from torch.distributions.utils import lazy_property + +logger = get_logger(__name__) + + +class Dataset(torch.utils.data.Dataset): + r""" + Dataset that is compatible with :class:`torch.utils.data.Dataset`, serving as a wrapper for manipulating all data fields + with the operating behaviours defined in :class:`~supar.utils.transform.Transform`. + The data fields of all the instantiated sentences can be accessed as an attribute of the dataset. + + Args: + transform (Transform): + An instance of :class:`~supar.utils.transform.Transform` or its derivations. + The instance holds a series of loading and processing behaviours with regard to the specific data format. + data (Union[str, Iterable]): + A filename or a list of instances that will be passed into :meth:`transform.load`. + cache (bool): + If ``True``, tries to use the previously cached binarized data for fast loading. + In this way, sentences are loaded on-the-fly according to the meta data. + If ``False``, all sentences will be directly loaded into the memory. + Default: ``False``. + binarize (bool): + If ``True``, binarizes the dataset once building it. Only works if ``cache=True``. Default: ``False``. + bin (str): + Path for saving binarized files, required if ``cache=True``. Default: ``None``. + max_len (int): + Sentences exceeding the length will be discarded. Default: ``None``. + kwargs (Dict): + Together with `data`, kwargs will be passed into :meth:`transform.load` to control the loading behaviour. + + Attributes: + transform (Transform): + An instance of :class:`~supar.utils.transform.Transform`. + sentences (List[Sentence]): + A list of sentences loaded from the data. + Each sentence includes fields obeying the data format defined in ``transform``. + If ``cache=True``, each is a pointer to the sentence stored in the cache file. + """ + + def __init__( + self, + transform: Transform, + data: Union[str, Iterable], + cache: bool = False, + binarize: bool = False, + bin: str = None, + max_len: int = None, + **kwargs + ) -> Dataset: + super(Dataset, self).__init__() + + self.transform = transform + self.data = data + self.cache = cache + self.binarize = binarize + self.bin = bin + self.max_len = max_len or INF + self.kwargs = kwargs + + if cache: + if not isinstance(data, str) or not os.path.exists(data): + raise FileNotFoundError("Only files are allowed for binarization, but not found") + if self.bin is None: + self.fbin = data + '.pt' + else: + os.makedirs(self.bin, exist_ok=True) + self.fbin = os.path.join(self.bin, os.path.split(data)[1]) + '.pt' + if not self.binarize and os.path.exists(self.fbin): + try: + self.sentences = debinarize(self.fbin, meta=True)['sentences'] + except Exception: + raise RuntimeError(f"Error found while debinarizing {self.fbin}, which may have been corrupted. " + "Try re-binarizing it first!") + else: + self.sentences = list(transform.load(data, **kwargs)) + + + def __repr__(self): + s = f"{self.__class__.__name__}(" + s += f"n_sentences={len(self.sentences)}" + if hasattr(self, 'loader'): + s += f", n_batches={len(self.loader)}" + if hasattr(self, 'buckets'): + s += f", n_buckets={len(self.buckets)}" + if self.cache: + s += f", cache={self.cache}" + if self.binarize: + s += f", binarize={self.binarize}" + if self.max_len < INF: + s += f", max_len={self.max_len}" + s += ")" + return s + + def __len__(self): + return len(self.sentences) + + def __getitem__(self, index): + return debinarize(self.fbin, self.sentences[index]) if self.cache else self.sentences[index] + + def __getattr__(self, name): + if name not in {f.name for f in self.transform.flattened_fields}: + raise AttributeError + if self.cache: + if os.path.exists(self.fbin) and not self.binarize: + sentences = self + else: + sentences = self.transform.load(self.data, **self.kwargs) + return (getattr(sentence, name) for sentence in sentences) + return [getattr(sentence, name) for sentence in self.sentences] + + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, state): + self.__dict__.update(state) + + @lazy_property + def sizes(self): + if not self.cache: + return [s.size for s in self.sentences] + return debinarize(self.fbin, 'sizes') + + def build( + self, + batch_size: int, + n_buckets: int = 1, + shuffle: bool = False, + distributed: bool = False, + even: bool = True, + n_workers: int = 0, + pin_memory: bool = True, + chunk_size: int = 1000, + ) -> Dataset: + # numericalize all fields + if not self.cache: + self.sentences = [i for i in self.transform(self.sentences) if len(i) < self.max_len] + else: + # if not forced to do binarization and the binarized file already exists, directly load the meta file + if os.path.exists(self.fbin) and not self.binarize: + self.sentences = debinarize(self.fbin, meta=True)['sentences'] + else: + @contextmanager + def cache(sentences): + ftemp = tempfile.mkdtemp() + fs = os.path.join(ftemp, 'sentences') + fb = os.path.join(ftemp, os.path.basename(self.fbin)) + global global_transform + global_transform = self.transform + sentences = binarize({'sentences': progress_bar(sentences)}, fs)[1]['sentences'] + try: + yield ((sentences[s:s+chunk_size], fs, f"{fb}.{i}", self.max_len) + for i, s in enumerate(range(0, len(sentences), chunk_size))) + finally: + del global_transform + shutil.rmtree(ftemp) + + def numericalize(sentences, fs, fb, max_len): + sentences = global_transform((debinarize(fs, sentence) for sentence in sentences)) + sentences = [i for i in sentences if len(i) < max_len] + return binarize({'sentences': sentences, 'sizes': [sentence.size for sentence in sentences]}, fb)[0] + + logger.info(f"Seeking to cache the data to {self.fbin} first") + # numericalize the fields of each sentence + if is_master(): + with cache(self.transform.load(self.data, **self.kwargs)) as chunks, mp.Pool(32) as pool: + results = [pool.apply_async(numericalize, chunk) for chunk in chunks] + self.sentences = binarize((r.get() for r in results), self.fbin, merge=True)[1]['sentences'] + if is_dist(): + dist.barrier() + if not is_master(): + self.sentences = debinarize(self.fbin, meta=True)['sentences'] + # NOTE: the final bucket count is roughly equal to n_buckets + self.buckets = dict(zip(*kmeans(self.sizes, n_buckets))) + self.loader = DataLoader(transform=self.transform, + dataset=self, + batch_sampler=Sampler(self.buckets, batch_size, shuffle, distributed, even), + num_workers=n_workers, + collate_fn=collate_fn, + pin_memory=pin_memory) + return self + + +class Sampler(torch.utils.data.Sampler): + r""" + Sampler that supports for bucketization and token-level batchification. + + Args: + buckets (Dict): + A dict that maps each centroid to indices of clustered sentences. + The centroid corresponds to the average length of all sentences in the bucket. + batch_size (int): + Token-level batch size. The resulting batch contains roughly the same number of tokens as ``batch_size``. + shuffle (bool): + If ``True``, the sampler will shuffle both buckets and samples in each bucket. Default: ``False``. + distributed (bool): + If ``True``, the sampler will be used in conjunction with :class:`torch.nn.parallel.DistributedDataParallel` + that restricts data loading to a subset of the dataset. + Default: ``False``. + even (bool): + If ``True``, the sampler will add extra indices to make the data evenly divisible across the replicas. + Default: ``True``. + """ + + def __init__( + self, + buckets: Dict[float, List], + batch_size: int, + shuffle: bool = False, + distributed: bool = False, + even: bool = True + ) -> Sampler: + self.batch_size = batch_size + self.shuffle = shuffle + self.distributed = distributed + self.even = even + #print("237 utils data buckets items", buckets.items()) + self.sizes, self.buckets = zip(*[(size, bucket) for size, bucket in buckets.items()]) + # number of batches in each bucket, clipped by range [1, len(bucket)] + self.n_batches = [min(len(bucket), max(round(size * len(bucket) / batch_size), 1)) + for size, bucket in zip(self.sizes, self.buckets)] + self.rank, self.n_replicas, self.n_samples = 0, 1, self.n_total_samples + + if distributed: + self.rank = dist.get_rank() + self.n_replicas = dist.get_world_size() + self.n_samples = self.n_total_samples // self.n_replicas + if self.n_total_samples % self.n_replicas != 0: + self.n_samples += 1 if even else int(self.rank < self.n_total_samples % self.n_replicas) + self.epoch = 1 + + def __iter__(self): + g = torch.Generator() + g.manual_seed(self.epoch) + self.epoch += 1 + + total, batches = 0, [] + # if `shuffle=True`, shuffle both the buckets and samples in each bucket + # for distributed training, make sure each process generates the same random sequence at each epoch + range_fn = torch.arange if not self.shuffle else lambda x: torch.randperm(x, generator=g) + for i in itertools.cycle(range(len(self.buckets))): + bucket = self.buckets[i] + split_sizes = [(len(bucket) - j - 1) // self.n_batches[i] + 1 for j in range(self.n_batches[i])] + # DON'T use `torch.chunk` which may return wrong number of batches + for batch in range_fn(len(bucket)).split(split_sizes): + #print('supar utils 270', batch) + if total % self.n_replicas == self.rank: + batches.append([bucket[j] for j in batch.tolist()]) + if len(batches) == self.n_samples: + return iter(batches[i] for i in range_fn(self.n_samples).tolist()) + total += 1 + + def __len__(self): + return self.n_samples + + @property + def n_total_samples(self): + return sum(self.n_batches) + + def set_epoch(self, epoch: int) -> None: + self.epoch = epoch + + +class DataLoader(torch.utils.data.DataLoader): + + r""" + A wrapper for native :class:`torch.utils.data.DataLoader` enhanced with a data prefetcher. + See http://stackoverflow.com/questions/7323664/python-generator-pre-fetch and + https://github.com/NVIDIA/apex/issues/304. + """ + + def __init__(self, transform, **kwargs): + super().__init__(**kwargs) + + self.transform = transform + + def __iter__(self): + return PrefetchGenerator(self.transform, super().__iter__()) + + +class PrefetchGenerator(threading.Thread): + + def __init__(self, transform, loader, prefetch=1): + threading.Thread.__init__(self) + + self.transform = transform + + self.queue = queue.Queue(prefetch) + self.loader = loader + self.daemon = True + if torch.cuda.is_available(): + self.stream = torch.cuda.Stream() + + self.start() + + def __iter__(self): + return self + + def __next__(self): + if hasattr(self, 'stream'): + torch.cuda.current_stream().wait_stream(self.stream) + batch = self.queue.get() + if batch is None: + raise StopIteration + return batch + + def run(self): + # `torch.cuda.current_device` is thread local + # see https://github.com/pytorch/pytorch/issues/56588 + if is_dist() and torch.cuda.is_available(): + torch.cuda.set_device(dist.get_rank()) + if hasattr(self, 'stream'): + with torch.cuda.stream(self.stream): + for batch in self.loader: + self.queue.put(batch.compose(self.transform)) + else: + for batch in self.loader: + self.queue.put(batch.compose(self.transform)) + self.queue.put(None) + + +def collate_fn(x): + return Batch(x) diff --git a/tania_scripts/supar/utils/embed.py b/tania_scripts/supar/utils/embed.py new file mode 100644 index 0000000..c132b4d --- /dev/null +++ b/tania_scripts/supar/utils/embed.py @@ -0,0 +1,334 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import Iterable, Optional, Union + +import torch +from supar.utils.common import CACHE +from supar.utils.fn import download +from supar.utils.logging import progress_bar +from torch.distributions.utils import lazy_property + + +class Embedding(object): + r""" + Defines a container object for holding pretrained embeddings. + This object is callable and behaves like :class:`torch.nn.Embedding`. + For huge files, this object supports lazy loading, seeking to retrieve vectors from the disk on the fly if necessary. + + Currently available embeddings: + - `GloVe`_ + - `Fasttext`_ + - `Giga`_ + - `Tencent`_ + + Args: + path (str): + Path to the embedding file or short name registered in ``supar.utils.embed.PRETRAINED``. + unk (Optional[str]): + The string token used to represent OOV tokens. Default: ``None``. + skip_first (bool) + If ``True``, skips the first line of the embedding file. Default: ``False``. + cache (bool): + If ``True``, instead of loading entire embeddings into memory, seeks to load vectors from the disk once called. + Default: ``True``. + sep (str): + Separator used by embedding file. Default: ``' '``. + + Examples: + >>> import torch.nn as nn + >>> from supar.utils.embed import Embedding + >>> glove = Embedding.load('glove-6b-100') + >>> glove + GloVeEmbedding(n_tokens=400000, dim=100, unk=unk, cache=True) + >>> fasttext = Embedding.load('fasttext-en') + >>> fasttext + FasttextEmbedding(n_tokens=2000000, dim=300, skip_first=True, cache=True) + >>> giga = Embedding.load('giga-100') + >>> giga + GigaEmbedding(n_tokens=372846, dim=100, cache=True) + >>> indices = torch.tensor([glove.vocab[i.lower()] for i in ['She', 'enjoys', 'playing', 'tennis', '.']]) + >>> indices + tensor([ 67, 8371, 697, 2140, 2]) + >>> glove(indices).shape + torch.Size([5, 100]) + >>> glove(indices).equal(nn.Embedding.from_pretrained(glove.vectors)(indices)) + True + + .. _GloVe: + https://nlp.stanford.edu/projects/glove/ + .. _Fasttext: + https://fasttext.cc/docs/en/crawl-vectors.html + .. _Giga: + https://github.com/yzhangcs/parser/releases/download/v1.1.0/giga.100.zip + .. _Tencent: + https://ai.tencent.com/ailab/nlp/zh/download.html + """ + + CACHE = os.path.join(CACHE, 'data/embeds') + + def __init__( + self, + path: str, + unk: Optional[str] = None, + skip_first: bool = False, + cache: bool = True, + sep: str = ' ', + **kwargs + ) -> Embedding: + super().__init__() + + self.path = path + self.unk = unk + self.skip_first = skip_first + self.cache = cache + self.sep = sep + self.kwargs = kwargs + + self.vocab = {token: i for i, token in enumerate(self.tokens)} + + def __len__(self): + return len(self.vocab) + + def __repr__(self): + s = f"{self.__class__.__name__}(" + s += f"n_tokens={len(self)}, dim={self.dim}" + if self.unk is not None: + s += f", unk={self.unk}" + if self.skip_first: + s += f", skip_first={self.skip_first}" + if self.cache: + s += f", cache={self.cache}" + s += ")" + return s + + def __contains__(self, token): + return token in self.vocab + + def __getitem__(self, key: Union[int, Iterable[int], torch.Tensor]) -> torch.Tensor: + indices = key + if not isinstance(indices, torch.Tensor): + indices = torch.tensor(key) + if self.cache: + elems, indices = indices.unique(return_inverse=True) + with open(self.path) as f: + vectors = [] + for index in elems.tolist(): + f.seek(self.positions[index]) + vectors.append(list(map(float, f.readline().strip().split(self.sep)[1:]))) + vectors = torch.tensor(vectors) + else: + vectors = self.vectors + return torch.embedding(vectors, indices) + + def __call__(self, key: Union[int, Iterable[int], torch.Tensor]) -> torch.Tensor: + return self[key] + + @lazy_property + def dim(self): + return len(self[0]) + + @lazy_property + def unk_index(self): + if self.unk is not None: + return self.vocab[self.unk] + raise AttributeError + + @lazy_property + def tokens(self): + with open(self.path) as f: + if self.skip_first: + f.readline() + return [line.strip().split(self.sep)[0] for line in progress_bar(f)] + + @lazy_property + def vectors(self): + with open(self.path) as f: + if self.skip_first: + f.readline() + return torch.tensor([list(map(float, line.strip().split(self.sep)[1:])) for line in progress_bar(f)]) + + @lazy_property + def positions(self): + with open(self.path) as f: + if self.skip_first: + f.readline() + positions = [f.tell()] + while True: + line = f.readline() + if line: + positions.append(f.tell()) + else: + break + return positions + + @classmethod + def load(cls, path: str, unk: Optional[str] = None, **kwargs) -> Embedding: + if path in PRETRAINED: + cfg = dict(**PRETRAINED[path]) + embed = cfg.pop('_target_') + return embed(**cfg, **kwargs) + return cls(path, unk, **kwargs) + + +class GloVeEmbedding(Embedding): + + r""" + `GloVe`_: Global Vectors for Word Representation. + Training is performed on aggregated global word-word co-occurrence statistics from a corpus, + and the resulting representations showcase interesting linear substructures of the word vector space. + + Args: + src (str): + Size of the source data for training. Default: ``6B``. + dim (int): + Which dimension of the embeddings to use. Default: 100. + reload (bool): + If ``True``, forces a fresh download. Default: ``False``. + + Examples: + >>> from supar.utils.embed import Embedding + >>> Embedding.load('glove-6b-100') + GloVeEmbedding(n_tokens=400000, dim=100, unk=unk, cache=True) + + .. _GloVe: + https://nlp.stanford.edu/projects/glove/ + """ + + def __init__(self, src: str = '6B', dim: int = 100, reload=False, *args, **kwargs) -> GloVeEmbedding: + if src == '6B' or src == 'twitter.27B': + url = f'https://nlp.stanford.edu/data/glove.{src}.zip' + else: + url = f'https://nlp.stanford.edu/data/glove.{src}.{dim}d.zip' + path = os.path.join(os.path.join(self.CACHE, 'glove'), f'glove.{src}.{dim}d.txt') + if not os.path.exists(path) or reload: + download(url, os.path.join(self.CACHE, 'glove'), clean=True) + + super().__init__(path=path, unk='unk', *args, **kwargs, ) + + +class FasttextEmbedding(Embedding): + + r""" + `Fasttext`_ word embeddings for 157 languages, trained using CBOW, in dimension 300, + with character n-grams of length 5, a window of size 5 and 10 negatives. + + Args: + lang (str): + Language code. Default: ``en``. + reload (bool): + If ``True``, forces a fresh download. Default: ``False``. + + Examples: + >>> from supar.utils.embed import Embedding + >>> Embedding.load('fasttext-en') + FasttextEmbedding(n_tokens=2000000, dim=300, skip_first=True, cache=True) + + .. _Fasttext: + https://fasttext.cc/docs/en/crawl-vectors.html + """ + + def __init__(self, lang: str = 'en', reload=False, *args, **kwargs) -> FasttextEmbedding: + url = f'https://dl.fbaipublicfiles.com/fasttext/vectors-crawl/cc.{lang}.300.vec.gz' + path = os.path.join(self.CACHE, 'fasttext', f'cc.{lang}.300.vec') + if not os.path.exists(path) or reload: + download(url, os.path.join(self.CACHE, 'fasttext'), clean=True) + + super().__init__(path=path, skip_first=True, *args, **kwargs) + + +class GigaEmbedding(Embedding): + + r""" + `Giga`_ word embeddings, trained on Chinese Gigaword Third Edition for Chinese using word2vec, + used by :cite:`zhang-etal-2020-efficient` and :cite:`zhang-etal-2020-fast`. + + Args: + reload (bool): + If ``True``, forces a fresh download. Default: ``False``. + + Examples: + >>> from supar.utils.embed import Embedding + >>> Embedding.load('giga-100') + GigaEmbedding(n_tokens=372846, dim=100, cache=True) + + .. _Giga: + https://github.com/yzhangcs/parser/releases/download/v1.1.0/giga.100.zip + """ + + def __init__(self, reload=False, *args, **kwargs) -> GigaEmbedding: + url = 'https://github.com/yzhangcs/parser/releases/download/v1.1.0/giga.100.zip' + path = os.path.join(self.CACHE, 'giga', 'giga.100.txt') + if not os.path.exists(path) or reload: + download(url, os.path.join(self.CACHE, 'giga'), clean=True) + + super().__init__(path=path, *args, **kwargs) + + +class TencentEmbedding(Embedding): + + r""" + `Tencent`_ word embeddings. + The embeddings are trained on large-scale text collected from news, webpages, and novels with Directional Skip-Gram. + 100-dimension and 200-dimension embeddings for over 12 million Chinese words are provided. + + Args: + dim (int): + Which dimension of the embeddings to use. Currently 100 and 200 are available. Default: 100. + large (bool): + If ``True``, uses large version with larger vocab size (12,287,933); 2,000,000 otherwise. Default: ``False``. + reload (bool): + If ``True``, forces a fresh download. Default: ``False``. + + Examples: + >>> from supar.utils.embed import Embedding + >>> Embedding.load('tencent-100') + TencentEmbedding(n_tokens=2000000, dim=100, skip_first=True, cache=True) + >>> Embedding.load('tencent-100-large') + TencentEmbedding(n_tokens=12287933, dim=100, skip_first=True, cache=True) + + .. _Tencent: + https://ai.tencent.com/ailab/nlp/zh/download.html + """ + + def __init__(self, dim: int = 100, large: bool = False, reload=False, *args, **kwargs) -> TencentEmbedding: + url = f'https://ai.tencent.com/ailab/nlp/zh/data/tencent-ailab-embedding-zh-d{dim}-v0.2.0{"" if large else "-s"}.tar.gz' # noqa + name = f'tencent-ailab-embedding-zh-d{dim}-v0.2.0{"" if large else "-s"}' + path = os.path.join(os.path.join(self.CACHE, 'tencent'), name, f'{name}.txt') + if not os.path.exists(path) or reload: + download(url, os.path.join(self.CACHE, 'tencent'), clean=True) + + super().__init__(path=path, skip_first=True, *args, **kwargs) + + +PRETRAINED = { + 'glove-6b-50': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 50}, + 'glove-6b-100': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 100}, + 'glove-6b-200': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 200}, + 'glove-6b-300': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 300}, + 'glove-42b-300': {'_target_': GloVeEmbedding, 'src': '42B', 'dim': 300}, + 'glove-840b-300': {'_target_': GloVeEmbedding, 'src': '84B', 'dim': 300}, + 'glove-twitter-27b-25': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 25}, + 'glove-twitter-27b-50': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 50}, + 'glove-twitter-27b-100': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 100}, + 'glove-twitter-27b-200': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 200}, + 'fasttext-bg': {'_target_': FasttextEmbedding, 'lang': 'bg'}, + 'fasttext-ca': {'_target_': FasttextEmbedding, 'lang': 'ca'}, + 'fasttext-cs': {'_target_': FasttextEmbedding, 'lang': 'cs'}, + 'fasttext-de': {'_target_': FasttextEmbedding, 'lang': 'de'}, + 'fasttext-en': {'_target_': FasttextEmbedding, 'lang': 'en'}, + 'fasttext-es': {'_target_': FasttextEmbedding, 'lang': 'es'}, + 'fasttext-fr': {'_target_': FasttextEmbedding, 'lang': 'fr'}, + 'fasttext-it': {'_target_': FasttextEmbedding, 'lang': 'it'}, + 'fasttext-nl': {'_target_': FasttextEmbedding, 'lang': 'nl'}, + 'fasttext-no': {'_target_': FasttextEmbedding, 'lang': 'no'}, + 'fasttext-ro': {'_target_': FasttextEmbedding, 'lang': 'ro'}, + 'fasttext-ru': {'_target_': FasttextEmbedding, 'lang': 'ru'}, + 'giga-100': {'_target_': GigaEmbedding}, + 'tencent-100': {'_target_': TencentEmbedding, 'dim': 100}, + 'tencent-100-large': {'_target_': TencentEmbedding, 'dim': 100, 'large': True}, + 'tencent-200': {'_target_': TencentEmbedding, 'dim': 200}, + 'tencent-200-large': {'_target_': TencentEmbedding, 'dim': 200, 'large': True}, +} diff --git a/tania_scripts/supar/utils/field.py b/tania_scripts/supar/utils/field.py new file mode 100644 index 0000000..dd14bc7 --- /dev/null +++ b/tania_scripts/supar/utils/field.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from collections import Counter +from typing import Callable, Iterable, List, Optional, Union + +import torch +from supar.utils.data import Dataset +from supar.utils.embed import Embedding +from supar.utils.fn import pad +from supar.utils.logging import progress_bar +from supar.utils.parallel import wait +from supar.utils.vocab import Vocab + + +class RawField(object): + r""" + Defines a general datatype. + + A :class:`RawField` object does not assume any property of the datatype and + it holds parameters relating to how a datatype should be processed. + + Args: + name (str): + The name of the field. + fn (function): + The function used for preprocessing the examples. Default: ``None``. + """ + + def __init__(self, name: str, fn: Optional[Callable] = None) -> RawField: + self.name = name + self.fn = fn + + def __repr__(self): + return f"({self.name}): {self.__class__.__name__}()" + + def preprocess(self, sequence: Iterable) -> Iterable: + return self.fn(sequence) if self.fn is not None else sequence + + def transform(self, sequences: Iterable[List]) -> Iterable[List]: + return (self.preprocess(seq) for seq in sequences) + + def compose(self, sequences: Iterable[List]) -> Iterable[List]: + return sequences + + +class Field(RawField): + r""" + Defines a datatype together with instructions for converting to :class:`~torch.Tensor`. + :class:`Field` models common text processing datatypes that can be represented by tensors. + It holds a :class:`~supar.utils.vocab.Vocab` object that defines the set of possible values + for elements of the field and their corresponding numerical representations. + The :class:`Field` object also holds other parameters relating to how a datatype + should be numericalized, such as a tokenization method. + + Args: + name (str): + The name of the field. + pad_token (str): + The string token used as padding. Default: ``None``. + unk_token (str): + The string token used to represent OOV words. Default: ``None``. + bos_token (str): + A token that will be prepended to every example using this field, or ``None`` for no `bos_token`. + Default: ``None``. + eos_token (str): + A token that will be appended to every example using this field, or ``None`` for no `eos_token`. + lower (bool): + Whether to lowercase the text in this field. Default: ``False``. + use_vocab (bool): + Whether to use a :class:`~supar.utils.vocab.Vocab` object. + If ``False``, the data in this field should already be numerical. + Default: ``True``. + tokenize (function): + The function used to tokenize strings using this field into sequential examples. Default: ``None``. + fn (function): + The function used for preprocessing the examples. Default: ``None``. + """ + + def __init__( + self, + name: str, + pad: Optional[str] = None, + unk: Optional[str] = None, + bos: Optional[str] = None, + eos: Optional[str] = None, + lower: bool = False, + use_vocab: bool = True, + tokenize: Optional[Callable] = None, + fn: Optional[Callable] = None, + delay: Optional[int] = 0 + ) -> Field: + self.name = name + self.pad = pad + self.unk = unk + self.bos = bos + self.eos = eos + self.lower = lower + self.use_vocab = use_vocab + self.tokenize = tokenize + self.fn = fn + self.delay = delay + + self.specials = [token for token in [pad, unk, bos, eos] if token is not None] + + def __repr__(self): + s, params = f"({self.name}): {self.__class__.__name__}(", [] + if hasattr(self, 'vocab'): + params.append(f"vocab_size={len(self.vocab)}") + if self.pad is not None: + params.append(f"pad={self.pad}") + if self.unk is not None: + params.append(f"unk={self.unk}") + if self.bos is not None: + params.append(f"bos={self.bos}") + if self.eos is not None: + params.append(f"eos={self.eos}") + if self.lower: + params.append(f"lower={self.lower}") + if not self.use_vocab: + params.append(f"use_vocab={self.use_vocab}") + if self.delay > 0: + params.append(f'delay={self.delay}') + return s + ', '.join(params) + ')' + + @property + def pad_index(self): + if self.pad is None: + return 0 + if hasattr(self, 'vocab'): + return self.vocab[self.pad] + return self.specials.index(self.pad) + + @property + def unk_index(self): + if self.unk is None: + return 0 + if hasattr(self, 'vocab'): + return self.vocab[self.unk] + return self.specials.index(self.unk) + + @property + def bos_index(self): + if hasattr(self, 'vocab'): + return self.vocab[self.bos] + return self.specials.index(self.bos) + + @property + def eos_index(self): + if hasattr(self, 'vocab'): + return self.vocab[self.eos] + return self.specials.index(self.eos) + + @property + def device(self): + return 'cuda' if torch.cuda.is_available() else 'cpu' + + def preprocess(self, data: Union[str, Iterable]) -> Iterable: + r""" + Loads a single example and tokenize it if necessary. + The sequence will be first passed to ``fn`` if available. + If ``tokenize`` is not None, the input will be tokenized. + Then the input will be lowercased optionally. + + Args: + data (Union[str, Iterable]): + The data to be preprocessed. + + Returns: + A list of preprocessed sequence. + """ + + if self.fn is not None: + data = self.fn(data) + if self.tokenize is not None: + data = self.tokenize(data) + if self.lower: + data = [str.lower(token) for token in data] + return data + + def build( + self, + dataset: Dataset, + min_freq: int = 1, + embed: Optional[Embedding] = None, + norm: Callable = None + ) -> Field: + r""" + Constructs a :class:`~supar.utils.vocab.Vocab` object for this field from the dataset. + If the vocabulary has already existed, this function will have no effect. + + Args: + dataset (Dataset): + A :class:`~supar.utils.data.Dataset` object. + One of the attributes should be named after the name of this field. + min_freq (int): + The minimum frequency needed to include a token in the vocabulary. Default: 1. + embed (Embedding): + An Embedding object, words in which will be extended to the vocabulary. Default: ``None``. + norm (Callable): + Callable function used for normalizing embedding weights. Default: ``None``. + """ + + if hasattr(self, 'vocab'): + return + + @wait + def build_vocab(dataset): + return Vocab(counter=Counter(token + for seq in progress_bar(getattr(dataset, self.name)) + for token in self.preprocess(seq)), + min_freq=min_freq, + specials=self.specials, + unk_index=self.unk_index) + self.vocab = build_vocab(dataset) + + if not embed: + self.embed = None + else: + tokens = self.preprocess(embed.tokens) + # replace the `unk` token in the pretrained with a self-defined one if existed + if embed.unk: + tokens[embed.unk_index] = self.unk + + self.vocab.update(tokens) + self.embed = torch.zeros(len(self.vocab), embed.dim) + self.embed[self.vocab[tokens]] = embed.vectors + if norm is not None: + self.embed = norm(self.embed) + return self + + def transform(self, sequences: Iterable[List[str]]) -> Iterable[torch.Tensor]: + r""" + Turns a list of sequences that use this field into tensors. + + Each sequence is first preprocessed and then numericalized if needed. + + Args: + sequences (Iterable[List[str]]): + A list of sequences. + + Returns: + A list of tensors transformed from the input sequences. + """ + + for seq in sequences: + seq = self.preprocess(seq) + if self.use_vocab: + try: + seq = [self.vocab[token] for token in seq] + except: + raise AssertionError + if self.bos: + seq = [self.bos_index] + seq + if self.delay > 0: + seq = seq + [self.pad_index for _ in range(self.delay)] + if self.eos: + seq = seq + [self.eos_index] + yield torch.tensor(seq, dtype=torch.long) + + def compose(self, batch: Iterable[torch.Tensor]) -> torch.Tensor: + r""" + Composes a batch of sequences into a padded tensor. + + Args: + batch (Iterable[~torch.Tensor]): + A list of tensors. + + Returns: + A padded tensor converted to proper device. + """ + + return pad(batch, self.pad_index).to(self.device, non_blocking=True) + + +class SubwordField(Field): + r""" + A field that conducts tokenization and numericalization over each token rather the sequence. + + This is customized for models requiring character/subword-level inputs, e.g., CharLSTM and BERT. + + Args: + fix_len (int): + A fixed length that all subword pieces will be padded to. + This is used for truncating the subword pieces exceeding the length. + To save the memory, the final length will be the smaller value + between the max length of subword pieces in a batch and `fix_len`. + + Examples: + >>> from supar.utils.tokenizer import TransformerTokenizer + >>> tokenizer = TransformerTokenizer('bert-base-cased') + >>> field = SubwordField('bert', + pad=tokenizer.pad, + unk=tokenizer.unk, + bos=tokenizer.bos, + eos=tokenizer.eos, + fix_len=20, + tokenize=tokenizer) + >>> field.vocab = tokenizer.vocab # no need to re-build the vocab + >>> next(field.transform([['This', 'field', 'performs', 'token-level', 'tokenization']])) + tensor([[ 101, 0, 0], + [ 1188, 0, 0], + [ 1768, 0, 0], + [10383, 0, 0], + [22559, 118, 1634], + [22559, 2734, 0], + [ 102, 0, 0]]) + """ + + def __init__(self, *args, **kwargs): + self.fix_len = kwargs.pop('fix_len') if 'fix_len' in kwargs else 0 + super().__init__(*args, **kwargs) + + def build( + self, + dataset: Dataset, + min_freq: int = 1, + embed: Optional[Embedding] = None, + norm: Callable = None + ) -> SubwordField: + if hasattr(self, 'vocab'): + return + + @wait + def build_vocab(dataset): + return Vocab(counter=Counter(piece + for seq in progress_bar(getattr(dataset, self.name)) + for token in seq + for piece in self.preprocess(token)), + min_freq=min_freq, + specials=self.specials, + unk_index=self.unk_index) + self.vocab = build_vocab(dataset) + + if not embed: + self.embed = None + else: + tokens = self.preprocess(embed.tokens) + # if the `unk` token has existed in the pretrained, + # then replace it with a self-defined one + if embed.unk: + tokens[embed.unk_index] = self.unk + + self.vocab.update(tokens) + self.embed = torch.zeros(len(self.vocab), embed.dim) + self.embed[self.vocab[tokens]] = embed.vectors + if norm is not None: + self.embed = norm(self.embed) + return self + + def transform(self, sequences: Iterable[List[str]]) -> Iterable[torch.Tensor]: + for seq in sequences: + seq = [self.preprocess(token) for token in seq] + if self.use_vocab: + seq = [[self.vocab[i] if i in self.vocab else self.unk_index for i in token] if token else [self.unk_index] + for token in seq] + if self.bos: + seq = [[self.bos_index]] + seq + if self.delay > 0: + seq = seq + [[self.pad_index] for _ in range(self.delay)] + if self.eos: + seq = seq + [[self.eos_index]] + if self.fix_len > 0: + seq = [ids[:self.fix_len] for ids in seq] + yield pad([torch.tensor(ids, dtype=torch.long) for ids in seq], self.pad_index) + + +class ChartField(Field): + r""" + Field dealing with chart inputs. + + Examples: + >>> chart = [[ None, 'NP', None, None, 'S*', 'S'], + [ None, None, 'VP*', None, 'VP', None], + [ None, None, None, 'VP*', 'S::VP', None], + [ None, None, None, None, 'NP', None], + [ None, None, None, None, None, 'S*'], + [ None, None, None, None, None, None]] + >>> next(field.transform([chart])) + tensor([[ -1, 37, -1, -1, 107, 79], + [ -1, -1, 120, -1, 112, -1], + [ -1, -1, -1, 120, 86, -1], + [ -1, -1, -1, -1, 37, -1], + [ -1, -1, -1, -1, -1, 107], + [ -1, -1, -1, -1, -1, -1]]) + """ + + def build( + self, + dataset: Dataset, + min_freq: int = 1 + ) -> ChartField: + @wait + def build_vocab(dataset): + return Vocab(counter=Counter(i + for chart in progress_bar(getattr(dataset, self.name)) + for row in self.preprocess(chart) + for i in row if i is not None), + min_freq=min_freq, + specials=self.specials, + unk_index=self.unk_index) + self.vocab = build_vocab(dataset) + return self + + def transform(self, charts: Iterable[List[List]]) -> Iterable[torch.Tensor]: + for chart in charts: + chart = self.preprocess(chart) + if self.use_vocab: + chart = [[self.vocab[i] if i is not None else -1 for i in row] for row in chart] + if self.bos: + chart = [[self.bos_index]*len(chart[0])] + chart + if self.eos: + chart = chart + [[self.eos_index]*len(chart[0])] + yield torch.tensor(chart, dtype=torch.long) diff --git a/tania_scripts/supar/utils/fn.py b/tania_scripts/supar/utils/fn.py new file mode 100644 index 0000000..95d826a --- /dev/null +++ b/tania_scripts/supar/utils/fn.py @@ -0,0 +1,383 @@ +# -*- coding: utf-8 -*- + +import gzip +import mmap +import os +import pickle +import shutil +import struct +import sys +import tarfile +import unicodedata +import urllib +import zipfile +from collections import defaultdict +from typing import Any, Dict, Iterable, List, Optional, Tuple, Union + +import torch +from omegaconf import DictConfig, OmegaConf +from supar.utils.common import CACHE +from supar.utils.parallel import wait + + +def ispunct(token: str) -> bool: + return all(unicodedata.category(char).startswith('P') for char in token) + + +def isfullwidth(token: str) -> bool: + return all(unicodedata.east_asian_width(char) in ['W', 'F', 'A'] for char in token) + + +def islatin(token: str) -> bool: + return all('LATIN' in unicodedata.name(char) for char in token) + + +def isdigit(token: str) -> bool: + return all('DIGIT' in unicodedata.name(char) for char in token) + + +def tohalfwidth(token: str) -> str: + return unicodedata.normalize('NFKC', token) + + +def kmeans(x: List[int], k: int, max_it: int = 32) -> Tuple[List[float], List[List[int]]]: + r""" + KMeans algorithm for clustering the sentences by length. + + Args: + x (List[int]): + The list of sentence lengths. + k (int): + The number of clusters, which is an approximate value. + The final number of clusters can be less or equal to `k`. + max_it (int): + Maximum number of iterations. + If centroids does not converge after several iterations, the algorithm will be early stopped. + + Returns: + List[float], List[List[int]]: + The first list contains average lengths of sentences in each cluster. + The second is the list of clusters holding indices of data points. + + Examples: + >>> x = torch.randint(10, 20, (10,)).tolist() + >>> x + [15, 10, 17, 11, 18, 13, 17, 19, 18, 14] + >>> centroids, clusters = kmeans(x, 3) + >>> centroids + [10.5, 14.0, 17.799999237060547] + >>> clusters + [[1, 3], [0, 5, 9], [2, 4, 6, 7, 8]] + """ + + x = torch.tensor(x, dtype=torch.float) + # collect unique datapoints + datapoints, indices, freqs = x.unique(return_inverse=True, return_counts=True) + # the number of clusters must not be greater than the number of datapoints + k = min(len(datapoints), k) + # initialize k centroids randomly + centroids = datapoints[torch.randperm(len(datapoints))[:k]] + # assign each datapoint to the cluster with the closest centroid + dists, y = torch.abs_(datapoints.unsqueeze(-1) - centroids).min(-1) + + for _ in range(max_it): + # if an empty cluster is encountered, + # choose the farthest datapoint from the biggest cluster and move that the empty one + mask = torch.arange(k).unsqueeze(-1).eq(y) + none = torch.where(~mask.any(-1))[0].tolist() + for i in none: + # the biggest cluster + biggest = torch.where(mask[mask.sum(-1).argmax()])[0] + # the datapoint farthest from the centroid of the biggest cluster + farthest = dists[biggest].argmax() + # update the assigned cluster of the farthest datapoint + y[biggest[farthest]] = i + # re-calculate the mask + mask = torch.arange(k).unsqueeze(-1).eq(y) + # update the centroids + centroids, old = (datapoints * freqs * mask).sum(-1) / (freqs * mask).sum(-1), centroids + # re-assign all datapoints to clusters + dists, y = torch.abs_(datapoints.unsqueeze(-1) - centroids).min(-1) + # stop iteration early if the centroids converge + if centroids.equal(old): + break + # assign all datapoints to the new-generated clusters + # the empty ones are discarded + assigned = y.unique().tolist() + # get the centroids of the assigned clusters + centroids = centroids[assigned].tolist() + # map all values of datapoints to buckets + clusters = [torch.where(indices.unsqueeze(-1).eq(torch.where(y.eq(i))[0]).any(-1))[0].tolist() for i in assigned] + + return centroids, clusters + + +def stripe(x: torch.Tensor, n: int, w: int, offset: Tuple = (0, 0), horizontal: bool = True) -> torch.Tensor: + r""" + Returns a parallelogram stripe of the tensor. + + Args: + x (~torch.Tensor): the input tensor with 2 or more dims. + n (int): the length of the stripe. + w (int): the width of the stripe. + offset (tuple): the offset of the first two dims. + horizontal (bool): `True` if returns a horizontal stripe; `False` otherwise. + + Returns: + A parallelogram stripe of the tensor. + + Examples: + >>> x = torch.arange(25).view(5, 5) + >>> x + tensor([[ 0, 1, 2, 3, 4], + [ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19], + [20, 21, 22, 23, 24]]) + >>> stripe(x, 2, 3) + tensor([[0, 1, 2], + [6, 7, 8]]) + >>> stripe(x, 2, 3, (1, 1)) + tensor([[ 6, 7, 8], + [12, 13, 14]]) + >>> stripe(x, 2, 3, (1, 1), 0) + tensor([[ 6, 11, 16], + [12, 17, 22]]) + """ + + x = x.contiguous() + seq_len, stride = x.size(1), list(x.stride()) + numel = stride[1] + return x.as_strided(size=(n, w, *x.shape[2:]), + stride=[(seq_len + 1) * numel, (1 if horizontal else seq_len) * numel] + stride[2:], + storage_offset=(offset[0]*seq_len+offset[1])*numel) + + +def diagonal_stripe(x: torch.Tensor, offset: int = 1) -> torch.Tensor: + r""" + Returns a diagonal parallelogram stripe of the tensor. + + Args: + x (~torch.Tensor): the input tensor with 3 or more dims. + offset (int): which diagonal to consider. Default: 1. + + Returns: + A diagonal parallelogram stripe of the tensor. + + Examples: + >>> x = torch.arange(125).view(5, 5, 5) + >>> diagonal_stripe(x) + tensor([[ 5], + [36], + [67], + [98]]) + >>> diagonal_stripe(x, 2) + tensor([[10, 11], + [41, 42], + [72, 73]]) + >>> diagonal_stripe(x, -2) + tensor([[ 50, 51], + [ 81, 82], + [112, 113]]) + """ + + x = x.contiguous() + seq_len, stride = x.size(1), list(x.stride()) + n, w, numel = seq_len - abs(offset), abs(offset), stride[2] + return x.as_strided(size=(n, w, *x.shape[3:]), + stride=[((seq_len + 1) * x.size(2) + 1) * numel] + stride[2:], + storage_offset=offset*stride[1] if offset > 0 else abs(offset)*stride[0]) + + +def expanded_stripe(x: torch.Tensor, n: int, w: int, offset: Tuple = (0, 0)) -> torch.Tensor: + r""" + Returns an expanded parallelogram stripe of the tensor. + + Args: + x (~torch.Tensor): the input tensor with 2 or more dims. + n (int): the length of the stripe. + w (int): the width of the stripe. + offset (tuple): the offset of the first two dims. + + Returns: + An expanded parallelogram stripe of the tensor. + + Examples: + >>> x = torch.arange(25).view(5, 5) + >>> x + tensor([[ 0, 1, 2, 3, 4], + [ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19], + [20, 21, 22, 23, 24]]) + >>> expanded_stripe(x, 2, 3) + tensor([[[ 0, 1, 2, 3, 4], + [ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14]], + + [[ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19]]]) + >>> expanded_stripe(x, 2, 3, (1, 1)) + tensor([[[ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19]], + + [[10, 11, 12, 13, 14], + [15, 16, 17, 18, 19], + [20, 21, 22, 23, 24]]]) + + """ + x = x.contiguous() + stride = list(x.stride()) + return x.as_strided(size=(n, w, *list(x.shape[1:])), + stride=stride[:1] + [stride[0]] + stride[1:], + storage_offset=(offset[1])*stride[0]) + + +def pad( + tensors: List[torch.Tensor], + padding_value: int = 0, + total_length: int = None, + padding_side: str = 'right' +) -> torch.Tensor: + size = [len(tensors)] + [max(tensor.size(i) for tensor in tensors) + for i in range(len(tensors[0].size()))] + if total_length is not None: + assert total_length >= size[1] + size[1] = total_length + out_tensor = tensors[0].data.new(*size).fill_(padding_value) + for i, tensor in enumerate(tensors): + out_tensor[i][[slice(-i, None) if padding_side == 'left' else slice(0, i) for i in tensor.size()]] = tensor + return out_tensor + + +@wait +def download(url: str, path: Optional[str] = None, reload: bool = False, clean: bool = False) -> str: + filename = os.path.basename(urllib.parse.urlparse(url).path) + if path is None: + path = CACHE + os.makedirs(path, exist_ok=True) + path = os.path.join(path, filename) + if reload and os.path.exists(path): + os.remove(path) + if not os.path.exists(path): + sys.stderr.write(f"Downloading {url} to {path}\n") + try: + torch.hub.download_url_to_file(url, path, progress=True) + except (ValueError, urllib.error.URLError): + raise RuntimeError(f"File {url} unavailable. Please try other sources.") + return extract(path, reload, clean) + + +def extract(path: str, reload: bool = False, clean: bool = False) -> str: + extracted = path + if zipfile.is_zipfile(path): + with zipfile.ZipFile(path) as f: + extracted = os.path.join(os.path.dirname(path), f.infolist()[0].filename) + if reload or not os.path.exists(extracted): + f.extractall(os.path.dirname(path)) + elif tarfile.is_tarfile(path): + with tarfile.open(path) as f: + extracted = os.path.join(os.path.dirname(path), f.getnames()[0]) + if reload or not os.path.exists(extracted): + f.extractall(os.path.dirname(path)) + elif path.endswith('.gz'): + extracted = path[:-3] + with gzip.open(path) as fgz: + with open(extracted, 'wb') as f: + shutil.copyfileobj(fgz, f) + if clean: + os.remove(path) + return extracted + + +def binarize( + data: Union[List[str], Dict[str, Iterable]], + fbin: str = None, + merge: bool = False +) -> Tuple[str, torch.Tensor]: + start, meta = 0, defaultdict(list) + # the binarized file is organized as: + # `data`: pickled objects + # `meta`: a dict containing the pointers of each kind of data + # `index`: fixed size integers representing the storage positions of the meta data + with open(fbin, 'wb') as f: + # in this case, data should be a list of binarized files + if merge: + for file in data: + if not os.path.exists(file): + raise RuntimeError("Some files are missing. Please check the paths") + mi = debinarize(file, meta=True) + for key, val in mi.items(): + val[:, 0] += start + meta[key].append(val) + with open(file, 'rb') as fi: + length = int(sum(val[:, 1].sum() for val in mi.values())) + f.write(fi.read(length)) + start = start + length + meta = {key: torch.cat(val) for key, val in meta.items()} + else: + for key, val in data.items(): + for i in val: + bytes = pickle.dumps(i) + f.write(bytes) + meta[key].append((start, len(bytes))) + start = start + len(bytes) + meta = {key: torch.tensor(val) for key, val in meta.items()} + pickled = pickle.dumps(meta) + # append the meta data to the end of the bin file + f.write(pickled) + # record the positions of the meta data + f.write(struct.pack('LL', start, len(pickled))) + return fbin, meta + + +def debinarize( + fbin: str, + pos_or_key: Optional[Union[Tuple[int, int], str]] = (0, 0), + meta: bool = False +) -> Union[Any, Iterable[Any]]: + with open(fbin, 'rb') as f, mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm: + if meta or isinstance(pos_or_key, str): + length = len(struct.pack('LL', 0, 0)) + mm.seek(-length, os.SEEK_END) + offset, length = struct.unpack('LL', mm.read(length)) + mm.seek(offset) + if meta: + return pickle.loads(mm.read(length)) + # fetch by key + objs, meta = [], pickle.loads(mm.read(length))[pos_or_key] + for offset, length in meta.tolist(): + mm.seek(offset) + objs.append(pickle.loads(mm.read(length))) + return objs + # fetch by positions + offset, length = pos_or_key + mm.seek(offset) + return pickle.loads(mm.read(length)) + + +def resolve_config(args: Union[Dict, DictConfig]) -> DictConfig: + OmegaConf.register_new_resolver("eval", eval) + return DictConfig(OmegaConf.to_container(args, resolve=True)) + + +def collect_args(args: Union[Dict, DictConfig]) -> DictConfig: + for key in ('self', 'cls', '__class__'): + args.pop(key, None) + args.update(args.pop('kwargs', dict())) + return DictConfig(args) + + +def get_rng_state() -> Dict[str, torch.Tensor]: + state = {'rng_state': torch.get_rng_state()} + if torch.cuda.is_available(): + state['cuda_rng_state'] = torch.cuda.get_rng_state() + return state + + +def set_rng_state(state: Dict) -> None: + torch.set_rng_state(state['rng_state']) + if torch.cuda.is_available(): + torch.cuda.set_rng_state(state['cuda_rng_state']) diff --git a/tania_scripts/supar/utils/logging.py b/tania_scripts/supar/utils/logging.py new file mode 100644 index 0000000..73e4a77 --- /dev/null +++ b/tania_scripts/supar/utils/logging.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- + +import logging +import os +from logging import FileHandler, Formatter, Handler, Logger, StreamHandler +from typing import Iterable, Optional + +from supar.utils.parallel import is_master +from tqdm import tqdm + + +def get_logger(name: Optional[str] = None) -> Logger: + logger = logging.getLogger(name) + # init the root logger + if name is None: + logging.basicConfig(format='[%(asctime)s %(levelname)s] %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + handlers=[TqdmHandler()]) + return logger + + +class TqdmHandler(StreamHandler): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def emit(self, record): + try: + msg = self.format(record) + tqdm.write(msg) + self.flush() + except (KeyboardInterrupt, SystemExit): + raise + except Exception: + self.handleError(record) + + +def init_logger( + logger: Logger, + path: Optional[str] = None, + mode: str = 'w', + handlers: Optional[Iterable[Handler]] = None, + verbose: bool = True +) -> Logger: + if not handlers: + if path: + os.makedirs(os.path.dirname(path) or './', exist_ok=True) + logger.addHandler(FileHandler(path, mode)) + for handler in logger.handlers: + handler.setFormatter(ColoredFormatter(colored=not isinstance(handler, FileHandler))) + logger.setLevel(logging.INFO if is_master() and verbose else logging.WARNING) + return logger + + +def progress_bar( + iterator: Iterable, + ncols: Optional[int] = None, + bar_format: str = '{l_bar}{bar:20}| {n_fmt}/{total_fmt} {elapsed}<{remaining}, {rate_fmt}{postfix}', + leave: bool = False, + **kwargs +) -> tqdm: + return tqdm(iterator, + ncols=ncols, + bar_format=bar_format, + ascii=True, + disable=(not (logger.level == logging.INFO and is_master())), + leave=leave, + **kwargs) + + +class ColoredFormatter(Formatter): + + BLACK = '\033[30m' + RED = '\033[31m' + GREEN = '\033[32m' + GREY = '\033[37m' + RESET = '\033[0m' + + COLORS = { + logging.ERROR: RED, + logging.WARNING: RED, + logging.INFO: GREEN, + logging.DEBUG: BLACK, + logging.NOTSET: BLACK + } + + def __init__(self, colored=True, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.colored = colored + + def format(self, record): + fmt = '[%(asctime)s %(levelname)s] %(message)s' + if self.colored: + fmt = f'{self.COLORS[record.levelno]}[%(asctime)s %(levelname)s]{self.RESET} %(message)s' + datefmt = '%Y-%m-%d %H:%M:%S' + return Formatter(fmt=fmt, datefmt=datefmt).format(record) + + +logger = get_logger() diff --git a/tania_scripts/supar/utils/metric.py b/tania_scripts/supar/utils/metric.py new file mode 100644 index 0000000..f64940c --- /dev/null +++ b/tania_scripts/supar/utils/metric.py @@ -0,0 +1,346 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from collections import Counter +from typing import Dict, List, Optional, Tuple + +import torch + + +class Metric(object): + + def __init__(self, reverse: Optional[bool] = None, eps: float = 1e-12) -> Metric: + super().__init__() + + self.n = 0.0 + self.count = 0.0 + self.total_loss = 0.0 + self.reverse = reverse + self.eps = eps + + def __repr__(self): + return f"loss: {self.loss:.4f} - " + ' '.join([f"{key}: {val:6.2%}" for key, val in self.values.items()]) + + def __lt__(self, other: Metric) -> bool: + if not hasattr(self, 'score'): + return True + if not hasattr(other, 'score'): + return False + return (self.score < other.score) if not self.reverse else (self.score > other.score) + + def __le__(self, other: Metric) -> bool: + if not hasattr(self, 'score'): + return True + if not hasattr(other, 'score'): + return False + return (self.score <= other.score) if not self.reverse else (self.score >= other.score) + + def __gt__(self, other: Metric) -> bool: + if not hasattr(self, 'score'): + return False + if not hasattr(other, 'score'): + return True + return (self.score > other.score) if not self.reverse else (self.score < other.score) + + def __ge__(self, other: Metric) -> bool: + if not hasattr(self, 'score'): + return False + if not hasattr(other, 'score'): + return True + return (self.score >= other.score) if not self.reverse else (self.score <= other.score) + + def __add__(self, other: Metric) -> Metric: + return other + + @property + def score(self): + raise AttributeError + + @property + def loss(self): + return self.total_loss / (self.count + self.eps) + + @property + def values(self): + raise AttributeError + + +class AttachmentMetric(Metric): + + def __init__( + self, + loss: Optional[float] = None, + preds: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + golds: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + mask: Optional[torch.BoolTensor] = None, + reverse: bool = False, + eps: float = 1e-12 + ) -> AttachmentMetric: + super().__init__(reverse=reverse, eps=eps) + + self.n_ucm = 0.0 + self.n_lcm = 0.0 + self.total = 0.0 + self.correct_arcs = 0.0 + self.correct_rels = 0.0 + + if loss is not None: + self(loss, preds, golds, mask) + + def __call__( + self, + loss: float, + preds: Tuple[torch.Tensor, torch.Tensor], + golds: Tuple[torch.Tensor, torch.Tensor], + mask: torch.BoolTensor + ) -> AttachmentMetric: + lens = mask.sum(1) + arc_preds, rel_preds, arc_golds, rel_golds = *preds, *golds + arc_mask = arc_preds.eq(arc_golds) & mask + rel_mask = rel_preds.eq(rel_golds) & arc_mask + arc_mask_seq, rel_mask_seq = arc_mask[mask], rel_mask[mask] + + self.n += len(mask) + self.count += 1 + self.total_loss += float(loss) + self.n_ucm += arc_mask.sum(1).eq(lens).sum().item() + self.n_lcm += rel_mask.sum(1).eq(lens).sum().item() + + self.total += len(arc_mask_seq) + self.correct_arcs += arc_mask_seq.sum().item() + self.correct_rels += rel_mask_seq.sum().item() + return self + + def __add__(self, other: AttachmentMetric) -> AttachmentMetric: + metric = AttachmentMetric(eps=self.eps) + metric.n = self.n + other.n + metric.count = self.count + other.count + metric.total_loss = self.total_loss + other.total_loss + metric.n_ucm = self.n_ucm + other.n_ucm + metric.n_lcm = self.n_lcm + other.n_lcm + metric.total = self.total + other.total + metric.correct_arcs = self.correct_arcs + other.correct_arcs + metric.correct_rels = self.correct_rels + other.correct_rels + metric.reverse = self.reverse or other.reverse + return metric + + @property + def score(self): + return self.las + + @property + def ucm(self): + return self.n_ucm / (self.n + self.eps) + + @property + def lcm(self): + return self.n_lcm / (self.n + self.eps) + + @property + def uas(self): + return self.correct_arcs / (self.total + self.eps) + + @property + def las(self): + return self.correct_rels / (self.total + self.eps) + + @property + def values(self) -> Dict: + return {'UCM': self.ucm, + 'LCM': self.lcm, + 'UAS': self.uas, + 'LAS': self.las} + + +class SpanMetric(Metric): + + def __init__( + self, + loss: Optional[float] = None, + preds: Optional[List[List[Tuple]]] = None, + golds: Optional[List[List[Tuple]]] = None, + reverse: bool = False, + eps: float = 1e-12 + ) -> SpanMetric: + super().__init__(reverse=reverse, eps=eps) + + self.n_ucm = 0.0 + self.n_lcm = 0.0 + self.utp = 0.0 + self.ltp = 0.0 + self.pred = 0.0 + self.gold = 0.0 + + if loss is not None: + self(loss, preds, golds) + + def __call__( + self, + loss: float, + preds: List[List[Tuple]], + golds: List[List[Tuple]] + ) -> SpanMetric: + self.n += len(preds) + self.count += 1 + self.total_loss += float(loss) + for pred, gold in zip(preds, golds): + upred, ugold = Counter([tuple(span[:-1]) for span in pred]), Counter([tuple(span[:-1]) for span in gold]) + lpred, lgold = Counter([tuple(span) for span in pred]), Counter([tuple(span) for span in gold]) + utp, ltp = list((upred & ugold).elements()), list((lpred & lgold).elements()) + self.n_ucm += len(utp) == len(pred) == len(gold) + self.n_lcm += len(ltp) == len(pred) == len(gold) + self.utp += len(utp) + self.ltp += len(ltp) + self.pred += len(pred) + self.gold += len(gold) + return self + + def __add__(self, other: SpanMetric) -> SpanMetric: + metric = SpanMetric(eps=self.eps) + metric.n = self.n + other.n + metric.count = self.count + other.count + metric.total_loss = self.total_loss + other.total_loss + metric.n_ucm = self.n_ucm + other.n_ucm + metric.n_lcm = self.n_lcm + other.n_lcm + metric.utp = self.utp + other.utp + metric.ltp = self.ltp + other.ltp + metric.pred = self.pred + other.pred + metric.gold = self.gold + other.gold + metric.reverse = self.reverse or other.reverse + return metric + + @property + def score(self): + return self.lf + + @property + def ucm(self): + return self.n_ucm / (self.n + self.eps) + + @property + def lcm(self): + return self.n_lcm / (self.n + self.eps) + + @property + def up(self): + return self.utp / (self.pred + self.eps) + + @property + def ur(self): + return self.utp / (self.gold + self.eps) + + @property + def uf(self): + return 2 * self.utp / (self.pred + self.gold + self.eps) + + @property + def lp(self): + return self.ltp / (self.pred + self.eps) + + @property + def lr(self): + return self.ltp / (self.gold + self.eps) + + @property + def lf(self): + return 2 * self.ltp / (self.pred + self.gold + self.eps) + + @property + def values(self) -> Dict: + return {'UCM': self.ucm, + 'LCM': self.lcm, + 'UP': self.up, + 'UR': self.ur, + 'UF': self.uf, + 'LP': self.lp, + 'LR': self.lr, + 'LF': self.lf} + + +class ChartMetric(Metric): + + def __init__( + self, + loss: Optional[float] = None, + preds: Optional[torch.Tensor] = None, + golds: Optional[torch.Tensor] = None, + reverse: bool = False, + eps: float = 1e-12 + ) -> ChartMetric: + super().__init__(reverse=reverse, eps=eps) + + self.tp = 0.0 + self.utp = 0.0 + self.pred = 0.0 + self.gold = 0.0 + + if loss is not None: + self(loss, preds, golds) + + def __call__( + self, + loss: float, + preds: torch.Tensor, + golds: torch.Tensor + ) -> ChartMetric: + self.n += len(preds) + self.count += 1 + self.total_loss += float(loss) + pred_mask = preds.ge(0) + gold_mask = golds.ge(0) + span_mask = pred_mask & gold_mask + self.pred += pred_mask.sum().item() + self.gold += gold_mask.sum().item() + self.tp += (preds.eq(golds) & span_mask).sum().item() + self.utp += span_mask.sum().item() + return self + + def __add__(self, other: ChartMetric) -> ChartMetric: + metric = ChartMetric(eps=self.eps) + metric.n = self.n + other.n + metric.count = self.count + other.count + metric.total_loss = self.total_loss + other.total_loss + metric.tp = self.tp + other.tp + metric.utp = self.utp + other.utp + metric.pred = self.pred + other.pred + metric.gold = self.gold + other.gold + metric.reverse = self.reverse or other.reverse + return metric + + @property + def score(self): + return self.f + + @property + def up(self): + return self.utp / (self.pred + self.eps) + + @property + def ur(self): + return self.utp / (self.gold + self.eps) + + @property + def uf(self): + return 2 * self.utp / (self.pred + self.gold + self.eps) + + @property + def p(self): + return self.tp / (self.pred + self.eps) + + @property + def r(self): + return self.tp / (self.gold + self.eps) + + @property + def f(self): + return 2 * self.tp / (self.pred + self.gold + self.eps) + + @property + def values(self) -> Dict: + return {'UP': self.up, + 'UR': self.ur, + 'UF': self.uf, + 'P': self.p, + 'R': self.r, + 'F': self.f} diff --git a/tania_scripts/supar/utils/optim.py b/tania_scripts/supar/utils/optim.py new file mode 100644 index 0000000..e67730b --- /dev/null +++ b/tania_scripts/supar/utils/optim.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from torch.optim import Optimizer +from torch.optim.lr_scheduler import _LRScheduler + + +class InverseSquareRootLR(_LRScheduler): + + def __init__( + self, + optimizer: Optimizer, + warmup_steps: int, + last_epoch: int = -1 + ) -> InverseSquareRootLR: + self.warmup_steps = warmup_steps + self.factor = warmup_steps ** 0.5 + super(InverseSquareRootLR, self).__init__(optimizer, last_epoch) + + def get_lr(self): + epoch = max(self.last_epoch, 1) + scale = min(epoch ** -0.5, epoch * self.warmup_steps ** -1.5) * self.factor + return [scale * lr for lr in self.base_lrs] + + +class PolynomialLR(_LRScheduler): + r""" + Set the learning rate for each parameter group using a polynomial defined as: `lr = base_lr * (1 - t / T) ^ (power)`, + where `t` is the current epoch and `T` is the maximum number of epochs. + """ + + def __init__( + self, + optimizer: Optimizer, + warmup_steps: int = 0, + steps: int = 100000, + power: float = 1., + last_epoch: int = -1 + ) -> PolynomialLR: + self.warmup_steps = warmup_steps + self.steps = steps + self.power = power + super(PolynomialLR, self).__init__(optimizer, last_epoch) + + def get_lr(self): + epoch = max(self.last_epoch, 1) + if epoch <= self.warmup_steps: + return [epoch / self.warmup_steps * lr for lr in self.base_lrs] + t, T = (epoch - self.warmup_steps), (self.steps - self.warmup_steps) + return [lr * (1 - t / T) ** self.power for lr in self.base_lrs] + + +def LinearLR(optimizer: Optimizer, warmup_steps: int = 0, steps: int = 100000, last_epoch: int = -1) -> PolynomialLR: + return PolynomialLR(optimizer, warmup_steps, steps, 1, last_epoch) diff --git a/tania_scripts/supar/utils/parallel.py b/tania_scripts/supar/utils/parallel.py new file mode 100644 index 0000000..f6f1e0b --- /dev/null +++ b/tania_scripts/supar/utils/parallel.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import functools +import os +import re +from typing import Any, Iterable + +import torch +import torch.distributed as dist +import torch.nn as nn + + +class DistributedDataParallel(nn.parallel.DistributedDataParallel): + + def __init__(self, module, **kwargs): + super().__init__(module, **kwargs) + + def __getattr__(self, name): + wrapped = super().__getattr__('module') + if hasattr(wrapped, name): + return getattr(wrapped, name) + return super().__getattr__(name) + + +def wait(fn) -> Any: + @functools.wraps(fn) + def wrapper(*args, **kwargs): + value = None + if is_master(): + value = fn(*args, **kwargs) + if is_dist(): + dist.barrier() + value = gather(value)[0] + return value + return wrapper + + +def gather(obj: Any) -> Iterable[Any]: + objs = [None] * dist.get_world_size() + dist.all_gather_object(objs, obj) + return objs + + +def reduce(obj: Any, reduction: str = 'sum') -> Any: + objs = gather(obj) + if reduction == 'sum': + return functools.reduce(lambda x, y: x + y, objs) + elif reduction == 'mean': + return functools.reduce(lambda x, y: x + y, objs) / len(objs) + elif reduction == 'min': + return min(objs) + elif reduction == 'max': + return max(objs) + else: + raise NotImplementedError(f"Unsupported reduction {reduction}") + + +def is_dist(): + return dist.is_available() and dist.is_initialized() + + +def is_master(): + return not is_dist() or dist.get_rank() == 0 + + +def get_free_port(): + import socket + s = socket.socket() + s.bind(('', 0)) + port = str(s.getsockname()[1]) + s.close() + return port + + +def get_device_count(): + if 'CUDA_VISIBLE_DEVICES' in os.environ: + return len(re.findall(r'\d+', os.environ['CUDA_VISIBLE_DEVICES'])) + return torch.cuda.device_count() diff --git a/tania_scripts/supar/utils/tokenizer.py b/tania_scripts/supar/utils/tokenizer.py new file mode 100644 index 0000000..35920b6 --- /dev/null +++ b/tania_scripts/supar/utils/tokenizer.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +import re +import tempfile +from collections import Counter, defaultdict +from typing import Any, Dict, List, Optional, Union + +import torch.distributed as dist +from supar.utils.parallel import is_dist, is_master +from supar.utils.vocab import Vocab +from torch.distributions.utils import lazy_property + + +class Tokenizer: + + def __init__(self, lang: str = 'en') -> Tokenizer: + import stanza + try: + self.pipeline = stanza.Pipeline(lang=lang, processors='tokenize', verbose=False, tokenize_no_ssplit=True) + except Exception: + stanza.download(lang=lang, resources_url='stanford') + self.pipeline = stanza.Pipeline(lang=lang, processors='tokenize', verbose=False, tokenize_no_ssplit=True) + + def __call__(self, text: str) -> List[str]: + return [i.text for i in self.pipeline(text).sentences[0].tokens] + + +class TransformerTokenizer: + + def __init__(self, name) -> TransformerTokenizer: + from transformers import AutoTokenizer + self.name = name + try: + self.tokenizer = AutoTokenizer.from_pretrained(name, local_files_only=True) + except Exception: + self.tokenizer = AutoTokenizer.from_pretrained(name, local_files_only=False) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.name})" + + def __len__(self) -> int: + return self.vocab_size + + def __call__(self, text: str) -> List[str]: + from tokenizers.pre_tokenizers import ByteLevel + if isinstance(self.tokenizer.backend_tokenizer.pre_tokenizer, ByteLevel): + text = ' ' + text + return self.tokenizer.tokenize(text) + + def __getattr__(self, name: str) -> Any: + return getattr(self.tokenizer, name) + + def __getstate__(self) -> Dict: + return self.__dict__ + + def __setstate__(self, state: Dict): + self.__dict__.update(state) + + @lazy_property + def vocab(self): + return defaultdict(lambda: self.tokenizer.vocab[self.unk], self.tokenizer.get_vocab()) + + @lazy_property + def tokens(self): + return sorted(self.vocab, key=lambda x: self.vocab[x]) + + @property + def vocab_size(self): + return len(self.vocab) + + @property + def pad(self): + return self.tokenizer.pad_token + + @property + def unk(self): + return self.tokenizer.unk_token + + @property + def bos(self): + return self.tokenizer.bos_token or self.tokenizer.cls_token + + @property + def eos(self): + return self.tokenizer.eos_token or self.tokenizer.sep_token + + def decode(self, text: List) -> str: + return self.tokenizer.decode(text, skip_special_tokens=True, clean_up_tokenization_spaces=False) + + +class BPETokenizer: + + def __init__( + self, + path: str = None, + files: Optional[List[str]] = None, + vocab_size: Optional[int] = 32000, + min_freq: Optional[int] = 2, + dropout: float = None, + backend: str = 'huggingface', + pad: Optional[str] = None, + unk: Optional[str] = None, + bos: Optional[str] = None, + eos: Optional[str] = None, + ) -> BPETokenizer: + + self.path = path + self.files = files + self.min_freq = min_freq + self.dropout = dropout or .0 + self.backend = backend + self.pad = pad + self.unk = unk + self.bos = bos + self.eos = eos + self.special_tokens = [i for i in [pad, unk, bos, eos] if i is not None] + + if backend == 'huggingface': + from tokenizers import Tokenizer + from tokenizers.decoders import BPEDecoder + from tokenizers.models import BPE + from tokenizers.pre_tokenizers import WhitespaceSplit + from tokenizers.trainers import BpeTrainer + path = os.path.join(path, 'tokenizer.json') + if is_master() and not os.path.exists(path): + # start to train a tokenizer from scratch + self.tokenizer = Tokenizer(BPE(dropout=dropout, unk_token=unk)) + self.tokenizer.pre_tokenizer = WhitespaceSplit() + self.tokenizer.decoder = BPEDecoder() + self.tokenizer.train(files=files, + trainer=BpeTrainer(vocab_size=vocab_size, + min_frequency=min_freq, + special_tokens=self.special_tokens, + end_of_word_suffix='</w>')) + self.tokenizer.save(path) + if is_dist(): + dist.barrier() + self.tokenizer = Tokenizer.from_file(path) + self.vocab = self.tokenizer.get_vocab() + + elif backend == 'subword-nmt': + import argparse + from argparse import Namespace + + from subword_nmt.apply_bpe import BPE, read_vocabulary + from subword_nmt.learn_joint_bpe_and_vocab import learn_joint_bpe_and_vocab + fmerge = os.path.join(path, 'merge.txt') + fvocab = os.path.join(path, 'vocab.txt') + separator = '@@' + if is_master() and (not os.path.exists(fmerge) or not os.path.exists(fvocab)): + with tempfile.TemporaryDirectory() as ftemp: + fall = os.path.join(ftemp, 'fall') + with open(fall, 'w') as f: + for file in files: + with open(file) as fi: + f.write(fi.read()) + learn_joint_bpe_and_vocab(Namespace(input=[argparse.FileType()(fall)], + output=argparse.FileType('w')(fmerge), + symbols=vocab_size, + separator=separator, + vocab=[argparse.FileType('w')(fvocab)], + min_frequency=min_freq, + total_symbols=False, + verbose=False, + num_workers=32)) + if is_dist(): + dist.barrier() + self.tokenizer = BPE(codes=open(fmerge), separator=separator, vocab=read_vocabulary(open(fvocab), None)) + self.vocab = Vocab(counter=Counter(self.tokenizer.vocab), + specials=self.special_tokens, + unk_index=self.special_tokens.index(unk)) + else: + raise ValueError(f'Unsupported backend: {backend} not in (huggingface, subword-nmt)') + + def __repr__(self) -> str: + s = self.__class__.__name__ + f'({self.vocab_size}, min_freq={self.min_freq}' + if self.dropout > 0: + s += f", dropout={self.dropout}" + s += f", backend={self.backend}" + if self.pad is not None: + s += f", pad={self.pad}" + if self.unk is not None: + s += f", unk={self.unk}" + if self.bos is not None: + s += f", bos={self.bos}" + if self.eos is not None: + s += f", eos={self.eos}" + s += ')' + return s + + def __len__(self) -> int: + return self.vocab_size + + def __call__(self, text: Union[str, List]) -> List[str]: + is_pretokenized = isinstance(text, list) + if self.backend == 'huggingface': + return self.tokenizer.encode(text, is_pretokenized=is_pretokenized).tokens + else: + if not is_pretokenized: + text = text.split() + return self.tokenizer.segment_tokens(text, dropout=self.dropout) + + @lazy_property + def tokens(self): + return sorted(self.vocab, key=lambda x: self.vocab[x]) + + @property + def vocab_size(self): + return len(self.vocab) + + def decode(self, text: List) -> str: + if self.backend == 'huggingface': + return self.tokenizer.decode(text) + else: + text = self.vocab[text] + text = ' '.join([i for i in text if i not in self.special_tokens]) + return re.sub(f'({self.tokenizer.separator} )|({self.tokenizer.separator} ?$)', '', text) diff --git a/tania_scripts/supar/utils/transform.py b/tania_scripts/supar/utils/transform.py new file mode 100644 index 0000000..f8d070c --- /dev/null +++ b/tania_scripts/supar/utils/transform.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from typing import Any, Iterable, Optional, Tuple + +import torch +from torch.distributions.utils import lazy_property + +from supar.utils.fn import debinarize +from supar.utils.logging import get_logger, progress_bar + +logger = get_logger(__name__) + + +class Transform(object): + r""" + A :class:`Transform` object corresponds to a specific data format, which holds several instances of data fields + that provide instructions for preprocessing and numericalization, etc. + + Attributes: + training (bool): + Sets the object in training mode. + If ``False``, some data fields not required for predictions won't be returned. + Default: ``True``. + """ + + fields = [] + + def __init__(self): + self.training = True + + def __len__(self): + return len(self.fields) + + def __repr__(self): + s = '\n' + '\n'.join([f" {f}" for f in self.flattened_fields]) + '\n' + return f"{self.__class__.__name__}({s})" + + def __call__(self, sentences: Iterable[Sentence]) -> Iterable[Sentence]: + return [sentence.numericalize(self.flattened_fields) for sentence in progress_bar(sentences)] + + def __getitem__(self, index): + return getattr(self, self.fields[index]) + + @property + def flattened_fields(self): + flattened = [] + for field in self: + if field not in self.src and field not in self.tgt: + continue + if not self.training and field in self.tgt: + continue + if not isinstance(field, Iterable): + field = [field] + for f in field: + if f is not None: + flattened.append(f) + return flattened + + def train(self, training=True): + self.training = training + + def eval(self): + self.train(False) + + def append(self, field): + self.fields.append(field.name) + setattr(self, field.name, field) + + @property + def src(self): + raise AttributeError + + @property + def tgt(self): + raise AttributeError + + +class Batch(object): + + def __init__(self, sentences: Iterable[Sentence]) -> Batch: + self.sentences = sentences + + self.names, self.fields = [], {} + + def __repr__(self): + return f'{self.__class__.__name__}({", ".join([f"{name}" for name in self.names])})' + + def __len__(self): + return len(self.sentences) + + def __getitem__(self, index): + return self.fields[self.names[index]] + + def __getattr__(self, name): + return [s.fields[name] for s in self.sentences] + + def __setattr__(self, name: str, value: Iterable[Any]): + if name not in ('sentences', 'fields', 'names'): + for s, v in zip(self.sentences, value): + setattr(s, name, v) + else: + self.__dict__[name] = value + + def __getstate__(self): + return self.__dict__ + + def __setstate__(self, state): + self.__dict__.update(state) + + @property + def device(self): + return 'cuda' if torch.cuda.is_available() else 'cpu' + + @lazy_property + def lens(self): + return torch.tensor([len(i) for i in self.sentences]).to(self.device, non_blocking=True) + + @lazy_property + def mask(self): + return self.lens.unsqueeze(-1).gt(self.lens.new_tensor(range(self.lens.max()))) + + def compose(self, transform: Transform) -> Batch: + for f in transform.flattened_fields: + self.names.append(f.name) + self.fields[f.name] = f.compose([s.fields[f.name] for s in self.sentences]) + return self + + def shrink(self, batch_size: Optional[int] = None) -> Batch: + if batch_size is None: + batch_size = len(self) // 2 + if batch_size <= 0: + raise RuntimeError(f"The batch has only {len(self)} sentences and can't be shrinked!") + return Batch([self.sentences[i] for i in torch.randperm(len(self))[:batch_size].tolist()]) + + def pin_memory(self): + for s in self.sentences: + for i in s.fields.values(): + if isinstance(i, torch.Tensor): + i.pin_memory() + return self + + +class Sentence(object): + + def __init__(self, transform, index: Optional[int] = None) -> Sentence: + self.index = index + # mapping from each nested field to their proper position + self.maps = dict() + # original values and numericalized values of each position + self.values, self.fields = [], {} + for i, field in enumerate(transform): + + if not isinstance(field, Iterable): + field = [field] + for f in field: + if f is not None: + self.maps[f.name] = i + self.fields[f.name] = None + + def __contains__(self, name): + return name in self.fields + + def __getattr__(self, name): + if name in self.fields: + return self.values[self.maps[name]] + raise AttributeError(f"`{name}` not found") + + def __setattr__(self, name, value): + if 'fields' in self.__dict__ and name in self: + index = self.maps[name] + if index >= len(self.values): + self.__dict__[name] = value + else: + self.values[index] = value + else: + self.__dict__[name] = value + + def __getstate__(self): + state = vars(self) + if 'fields' in state: + state['fields'] = { + name: ((value.dtype, value.tolist()) + if isinstance(value, torch.Tensor) + else value) + for name, value in state['fields'].items() + } + return state + + def __setstate__(self, state): + if 'fields' in state: + state['fields'] = { + name: (torch.tensor(value[1], dtype=value[0]) + if isinstance(value, tuple) and isinstance(value[0], torch.dtype) + else value) + for name, value in state['fields'].items() + } + self.__dict__.update(state) + + def __len__(self): + try: + return len(next(iter(self.fields.values()))) + except Exception: + raise AttributeError("Cannot get size of a sentence with no fields") + + @lazy_property + def size(self): + return len(self) + + def numericalize(self, fields): + for f in fields: + self.fields[f.name] = next(f.transform([getattr(self, f.name)])) + self.pad_index = fields[0].pad_index + return self + + @classmethod + def from_cache(cls, fbin: str, pos: Tuple[int, int]) -> Sentence: + return debinarize(fbin, pos) diff --git a/tania_scripts/supar/utils/vocab.py b/tania_scripts/supar/utils/vocab.py new file mode 100644 index 0000000..ee9cae0 --- /dev/null +++ b/tania_scripts/supar/utils/vocab.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +from collections import Counter, defaultdict +from typing import Iterable, Tuple, Union + + +class Vocab(object): + r""" + Defines a vocabulary object that will be used to numericalize a field. + + Args: + counter (~collections.Counter): + :class:`~collections.Counter` object holding the frequencies of each value found in the data. + min_freq (int): + The minimum frequency needed to include a token in the vocabulary. Default: 1. + specials (Tuple[str]): + The list of special tokens (e.g., pad, unk, bos and eos) that will be prepended to the vocabulary. Default: ``[]``. + unk_index (int): + The index of unk token. Default: 0. + + Attributes: + itos: + A list of token strings indexed by their numerical identifiers. + stoi: + A :class:`~collections.defaultdict` object mapping token strings to numerical identifiers. + """ + + def __init__(self, counter: Counter, min_freq: int = 1, specials: Tuple = tuple(), unk_index: int = 0) -> Vocab: + self.itos = list(specials) + self.stoi = defaultdict(lambda: unk_index) + self.stoi.update({token: i for i, token in enumerate(self.itos)}) + self.update([token for token, freq in counter.items() if freq >= min_freq]) + self.unk_index = unk_index + self.n_init = len(self) + + def __len__(self): + return len(self.itos) + + def __getitem__(self, key: Union[int, str, Iterable]) -> Union[str, int, Iterable]: + if isinstance(key, str): + return self.stoi[key] + elif not isinstance(key, Iterable): + return self.itos[key] + elif isinstance(key[0], str): + return [self.stoi[i] for i in key] + else: + return [self.itos[i] for i in key] + + def __contains__(self, token): + return token in self.stoi + + def __getstate__(self): + # avoid picking defaultdict + attrs = dict(self.__dict__) + # cast to regular dict + attrs['stoi'] = dict(self.stoi) + return attrs + + def __setstate__(self, state): + stoi = defaultdict(lambda: self.unk_index) + stoi.update(state['stoi']) + state['stoi'] = stoi + self.__dict__.update(state) + + def items(self): + return self.stoi.items() + + def update(self, vocab: Union[Iterable[str], Vocab, Counter]) -> Vocab: + if isinstance(vocab, Vocab): + vocab = vocab.itos + # NOTE: PAY CAREFUL ATTENTION TO DICT ORDER UNDER DISTRIBUTED TRAINING! + vocab = sorted(set(vocab).difference(self.stoi)) + self.itos.extend(vocab) + self.stoi.update({token: i for i, token in enumerate(vocab, len(self.stoi))}) + return self diff --git a/tania_scripts/supar/vector_quantize.py b/tania_scripts/supar/vector_quantize.py new file mode 100644 index 0000000..7e9a6ac --- /dev/null +++ b/tania_scripts/supar/vector_quantize.py @@ -0,0 +1,130 @@ +import numpy as np + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from clusopt_core.cluster import Streamkm + + +def ema_inplace(moving_avg, new, decay): + moving_avg.data.mul_(decay).add_(new, alpha=(1 - decay)) + + +def laplace_smoothing(x, n_categories, eps=1e-5): + return (x + eps) / (x.sum() + n_categories * eps) + + +class VectorQuantize(nn.Module): + # Based on: https://github.com/lucidrains/vector-quantize-pytorch + def __init__( + self, + dim, + n_embed, + decay=0.8, + commitment=1.0, + eps=1e-5, + wait_steps=0, + observe_steps=1245, + coreset_size_multiplier=10, + ): + super().__init__() + + self.dim = dim + self.n_embed = n_embed + self.decay = decay + self.eps = eps + self.commitment = commitment + + embed = torch.randn(dim, n_embed) + self.register_buffer("embed", nn.Parameter(embed)) + self.register_buffer("cluster_size", torch.zeros(n_embed)) + self.register_buffer("embed_avg", nn.Parameter(embed.clone())) + + self.wait_steps_remaining = wait_steps + self.observe_steps_remaining = observe_steps + self.clustering_model = Streamkm( + coresetsize=n_embed * coreset_size_multiplier, + length=1500000, + seed=42, + ) + self.data_chunks = [] + + def stream_cluster(self, input, expected_num_tokens=None): + input = input.reshape(-1, self.dim) + input_np = input.detach().cpu().numpy() + assert len(input.shape) == 2 + self.data_chunks.append(input_np) + if ( + expected_num_tokens is not None + and sum([chunk.shape[0] for chunk in self.data_chunks]) + < expected_num_tokens + ): + return # This is not the last sub-batch. + if self.wait_steps_remaining > 0: + self.wait_steps_remaining -= 1 + self.data_chunks.clear() + return + + self.observe_steps_remaining -= 1 + input_np = np.concatenate(self.data_chunks, axis=0) + self.data_chunks.clear() + self.clustering_model.partial_fit(input_np) + if self.observe_steps_remaining == 0: + print("\nInitializing vq clusters (this may take a while)...") + clusters, _ = self.clustering_model.get_final_clusters( + self.n_embed, seed=42 + ) + new_embed = torch.tensor( + clusters.T, dtype=self.embed.dtype, device=self.embed.device + ) + self.embed.copy_(new_embed) + # Don't set initial cluster sizes to zero! If a cluster is rare, + # embed_avg will be undergoing exponential decay until it's seen for + # the first time. If cluster_size is zero, this will lead to *embed* + # also undergoing exponential decay towards the origin before the + # cluster is ever encountered. Initializing to 1.0 will instead will + # instead leave embed in place for many iterations, up until + # cluster_size finally decays to near-zero. + self.cluster_size.fill_(1.0) + self.embed_avg.copy_(new_embed) + + def forward(self, input, expected_num_tokens=None): + if self.observe_steps_remaining > 0: + if self.training: + self.stream_cluster(input, expected_num_tokens) + return ( + input, + torch.zeros(input.shape[0], + dtype=torch.long, device=input.device), + torch.tensor(0.0, dtype=input.dtype, device=input.device), + None + ) + + dtype = input.dtype + flatten = input.reshape(-1, self.dim) + dist = ( + flatten.pow(2).sum(1, keepdim=True) + - 2 * flatten @ self.embed + + self.embed.pow(2).sum(0, keepdim=True) + ) + _, embed_ind = (-dist).max(1) + embed_onehot = F.one_hot(embed_ind, self.n_embed).type(dtype) + embed_ind = embed_ind.view(*input.shape[:-1]) + quantize = F.embedding(embed_ind, self.embed.transpose(0, 1)) + + if self.training: + ema_inplace(self.cluster_size, embed_onehot.sum(0), self.decay) + embed_sum = flatten.transpose(0, 1) @ embed_onehot + ema_inplace(self.embed_avg, embed_sum, self.decay) + cluster_size = ( + laplace_smoothing(self.cluster_size, self.n_embed, self.eps) + * self.cluster_size.sum() + ) + embed_normalized = self.embed_avg / cluster_size.unsqueeze(0) + self.embed.data.copy_(embed_normalized) + + loss = F.mse_loss(quantize.detach(), input) * self.commitment + quantize = input + (quantize - input).detach() + quantize = torch.reshape(quantize, input.size()) + return quantize, embed_ind, loss, dist diff --git a/tania_scripts/tania-some-other-metrics.ipynb b/tania_scripts/tania-some-other-metrics.ipynb index e23180b..ceb6052 100644 --- a/tania_scripts/tania-some-other-metrics.ipynb +++ b/tania_scripts/tania-some-other-metrics.ipynb @@ -88,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "2a882cc9-8f9d-4457-becb-d2e26ab3f14f", "metadata": {}, "outputs": [ @@ -107,7 +107,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "8897dcc3-4218-4ee5-9984-17b9a6d8dce2", "metadata": {}, "outputs": [], @@ -163,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "1363f307-fa4b-43ba-93d5-2d1c11ceb9e4", "metadata": {}, "outputs": [ @@ -184,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "1362e192-514a-4a77-a8cb-5c012026e2bb", "metadata": {}, "outputs": [], @@ -238,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "544ff6aa-4104-4580-a01f-97429ffcc228", "metadata": {}, "outputs": [ @@ -328,7 +328,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "b9052dc2-ce45-4af4-a0a0-46c60a13da12", "metadata": {}, "outputs": [], @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "1e9dd0fb-db6a-47d1-8bfb-1015845f6d3e", "metadata": {}, "outputs": [ @@ -398,7 +398,7 @@ "{'Flesch-Douma': 88.68, 'LIX': 11.55, 'Kandel-Moles': 5.86}" ] }, - "execution_count": 11, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -421,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "24bc84a5-b2df-4194-838a-8f24302599bd", "metadata": {}, "outputs": [], @@ -467,7 +467,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "0cdb972f-31b6-4e7e-82a8-371eda344f2c", "metadata": {}, "outputs": [ @@ -477,7 +477,7 @@ "{'Average Word Length': 3.79, 'Average Sentence Length': 7.0}" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -521,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "id": "56af520c-d56b-404a-aebf-ad7c2a9ca503", "metadata": {}, "outputs": [], @@ -567,7 +567,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "f7c8b125-4651-4b21-bcc4-93ef78a4239b", "metadata": {}, "outputs": [ @@ -603,7 +603,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 15, "id": "daa17c33-adca-4695-90eb-741579382939", "metadata": {}, "outputs": [], @@ -622,7 +622,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 16, "id": "80d8fa08-6b7d-4ab7-85cd-987823639277", "metadata": {}, "outputs": [ @@ -665,7 +665,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 18, "id": "3f9c7dc7-6820-4013-a85c-2af4f846d4f5", "metadata": {}, "outputs": [ @@ -693,7 +693,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "65e1a630-c46e-4b18-9831-b97864de53ee", "metadata": {}, "outputs": [], @@ -713,7 +713,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "1612e911-12a8-47c9-b811-b2d6885c3647", "metadata": {}, "outputs": [ @@ -742,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "925a3a75-aaaa-4851-b77b-b42cb1e21e11", "metadata": {}, "outputs": [], @@ -757,7 +757,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "6fa60897-ad26-43b4-b8de-861290ca6bd3", "metadata": {}, "outputs": [ @@ -783,25 +783,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 23, "id": "f3678462-e572-4ce5-8d3d-a5389b2356c8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Defaulting to user installation because normal site-packages is not writeable\n", - "Collecting scipy\n", - " Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)\n", - "Requirement already satisfied: numpy<2.5,>=1.23.5 in /public/conda/Miniconda/envs/pytorch-2.6/lib/python3.11/site-packages (from scipy) (2.2.4)\n", - "Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (37.7 MB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m37.7/37.7 MB\u001b[0m \u001b[31m75.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", - "\u001b[?25hInstalling collected packages: scipy\n", - "Successfully installed scipy-1.15.3\n" - ] - } - ], + "outputs": [], "source": [ "#!pip3 install seaborn\n", "#!pip3 install scipy" @@ -809,7 +794,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 24, "id": "b621b2a8-488f-44db-b085-fe156f453943", "metadata": {}, "outputs": [ @@ -830,7 +815,7 @@ "import matplotlib.pyplot as plt\n", "from scipy.stats import spearmanr\n", "\n", - "# Sample data (replace with your real values)\n", + "# Sample data (to be replaces with real values)\n", "data = {\n", " \"perplexity\": [32.5, 45.2, 28.1, 39.0, 50.3],\n", " \"avg_word_length\": [4.1, 4.3, 4.0, 4.2, 4.5],\n", @@ -853,10 +838,123 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "id": "45ee04fc-acab-4bba-ba06-e4cf4bca9fe5", + "metadata": {}, + "source": [ + "## Tree depth" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "79f99787-c220-4f1d-93a9-59230363ec3f", + "metadata": {}, + "outputs": [], + "source": [ + "def parse_sentence_block(text):\n", + " lines = text.strip().split('\\n')\n", + " result = []\n", + " tokenlist = []\n", + " for line in lines:\n", + " # Split the line by tab and strip whitespace\n", + " parts = tuple(line.strip().split('\\t'))\n", + " # Only include lines that have exactly 4 parts\n", + " if len(parts) == 4:\n", + " parentidx = int(parts[3])\n", + " if '@@' in parts[2]:\n", + " nonterm1 = parts[2].split('@@')[0]\n", + " nonterm2 = parts[2].split('@@')[1]\n", + " else:\n", + " nonterm1 = parts[2]\n", + " nonterm2 = '<nul>'\n", + " postag = parts[1]\n", + " token = parts[0]\n", + " result.append((parentidx, nonterm1, nonterm2, postag))\n", + " tokenlist.append(token)\n", + " return result, tokenlist\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "f567efb0-8b0b-4782-9345-052cf1785776", + "metadata": {}, + "outputs": [], + "source": [ + "example_sentence = \"\"\"\n", + "<s>\t<s>\t<s>\t1\n", + "--\tponct\t<nul>@@<nul>\t1\n", + "Eh\tnpp\t<nul>@@<nul>\t1\n", + "bien?\tadv\tAP@@<nul>\t1\n", + "fit\tv\tVN@@<nul>\t2\n", + "-il\tcls-suj\tVN@@VPinf-OBJ\t3\n", + ".\tponct\t<nul>@@<nul>\t4\n", + "</s>\t</s>\t</s>\t4\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "8d4ecba9-89b8-4000-a061-aa16aa68a404", + "metadata": {}, + "outputs": [], + "source": [ + "from transform import *\n", + "\n", + "def visualize_const_prediction(example_sent):\n", + " parsed, tokenlist = parse_sentence_block(example_sent)\n", + " tree = AttachJuxtaposeTree.totree(tokenlist, 'SENT')\n", + " AttachJuxtaposeTree.action2tree(tree, parsed).pretty_print()\n", + " nltk_tree = AttachJuxtaposeTree.action2tree(tree, parsed)\n", + " #print(\"NLTK TREE\", nltk_tree)\n", + " depth = nltk_tree.height() - 1 # NLTK includes the leaf level as height 1, so subtract 1 for tree depth \n", + " print(\"Tree depth:\", depth)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "bfd3abf3-b83a-4817-85ad-654daf72be88", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " SENT \n", + " | \n", + " <s> \n", + " | \n", + " <s> \n", + " ______________|__________ \n", + " | | | AP \n", + " | | | __________|________ \n", + " | | | | VPinf-OBJ \n", + " | | | | ______________|_______ \n", + " | | | | | VN \n", + " | | | | | ________________|____ \n", + " | | | | VN | | </s>\n", + " | | | | | | | | \n", + " | ponct npp adv v cls-suj ponct </s>\n", + " | | | | | | | | \n", + "<s> -- Eh bien? fit -il . </s>\n", + "\n", + "Tree depth: 8\n" + ] + } + ], + "source": [ + "visualize_const_prediction(example_sentence)" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "3a6e3b53-7104-45ef-a4b5-e831bdd6ca6f", + "id": "bc51ab44-6885-45cc-bad2-6a43a7791fdb", "metadata": {}, "outputs": [], "source": [] diff --git a/tania_scripts/transform.py b/tania_scripts/transform.py new file mode 100644 index 0000000..56e0f51 --- /dev/null +++ b/tania_scripts/transform.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union + +import nltk +import torch + +from supar.models.const.crf.transform import Tree +from supar.utils.common import NUL +from supar.utils.logging import get_logger +from supar.utils.tokenizer import Tokenizer +from supar.utils.transform import Sentence + +if TYPE_CHECKING: + from supar.utils import Field + +logger = get_logger(__name__) + + +class AttachJuxtaposeTree(Tree): + r""" + :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class, + supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`. + + Attributes: + WORD: + Words in the sentence. + POS: + Part-of-speech tags, or underscores if not available. + TREE: + The raw constituency tree in :class:`nltk.tree.Tree` format. + NODE: + The target node on each rightmost chain. + PARENT: + The label of the parent node of each terminal. + NEW: + The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children. + ``NUL`` represents the `Attach` action. + """ + + fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW'] + + def __init__( + self, + WORD: Optional[Union[Field, Iterable[Field]]] = None, + POS: Optional[Union[Field, Iterable[Field]]] = None, + TREE: Optional[Union[Field, Iterable[Field]]] = None, + NODE: Optional[Union[Field, Iterable[Field]]] = None, + PARENT: Optional[Union[Field, Iterable[Field]]] = None, + NEW: Optional[Union[Field, Iterable[Field]]] = None + ) -> Tree: + super().__init__() + + self.WORD = WORD + self.POS = POS + self.TREE = TREE + self.NODE = NODE + self.PARENT = PARENT + self.NEW = NEW + + @property + def src(self): + return self.WORD, self.POS, self.TREE + + @property + def tgt(self): + return self.NODE, self.PARENT, self.NEW + + @classmethod + def tree2action(cls, tree: nltk.Tree): + r""" + Converts a constituency tree into AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + A constituency tree in :class:`nltk.tree.Tree` format. + + Returns: + A sequence of AttachJuxtapose actions. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = nltk.Tree.fromstring(''' + (TOP + (S + (NP (_ Arthur)) + (VP + (_ is) + (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons))))) + (_ .))) + ''') + >>> tree.pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + >>> AttachJuxtaposeTree.tree2action(tree) + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')] + """ + + def isroot(node): + return node == tree[0] + + def isterminal(node): + return len(node) == 1 and not isinstance(node[0], nltk.Tree) + + def last_leaf(node): + pos = () + while True: + pos += (len(node) - 1,) + node = node[-1] + if isterminal(node): + return node, pos + + def parent(position): + return tree[position[:-1]] + + def grand(position): + return tree[position[:-2]] + + def detach(tree): + last, last_pos = last_leaf(tree) + siblings = parent(last_pos)[:-1] + + if len(siblings) > 0: + last_subtree = last + last_subtree_siblings = siblings + parent_label = NUL + else: + last_subtree, last_pos = parent(last_pos), last_pos[:-1] + last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1] + parent_label = last_subtree.label() + + target_pos, new_label, last_tree = 0, NUL, tree + if isroot(last_subtree): + last_tree = None + + elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]): + new_label = parent(last_pos).label() + new_label = new_label + target = last_subtree_siblings[0] + last_grand = grand(last_pos) + if last_grand is None: + last_tree = targetistermina + else: + last_grand[-1] = target + target_pos = len(last_pos) - 2 + else: + target = parent(last_pos) + target.pop() + target_pos = len(last_pos) - 2 + action = target_pos, parent_label, new_label + return action, last_tree + if tree is None: + return [] + action, last_tree = detach(tree) + return cls.tree2action(last_tree) + [action] + + @classmethod + def action2tree( + cls, + tree: nltk.Tree, + actions: List[Tuple[int, str, str]], + join: str = '::', + ) -> nltk.Tree: + r""" + Recovers a constituency tree from a sequence of AttachJuxtapose actions. + + Args: + tree (nltk.tree.Tree): + An empty tree that provides a base for building a result tree. + actions (List[Tuple[int, str, str]]): + A sequence of AttachJuxtapose actions. + join (str): + A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains. + Default: ``'::'``. + + Returns: + A result constituency tree. + + Examples: + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.action2tree(tree, + [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'), + (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'), + (0, '<nul>', '<nul>')]).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + """ + + def target(node, depth): + node_pos = () + for _ in range(depth): + node_pos += (len(node) - 1,) + node = node[-1] + return node, node_pos + + def parent(tree, position): + return tree[position[:-1]] + + def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree: + target_pos, parent_label, new_label, post = action + #print(target_pos, parent_label, new_label) + new_leaf = nltk.Tree(post, [terminal[0]]) + + # create the subtree to be inserted + new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf]) + # find the target position at which to insert the new subtree + target_node = tree + if target_node is not None: + target_node, target_pos = target(target_node, target_pos) + + # Attach + if new_label == NUL: + # attach the first token + if target_node is None: + return new_subtree + target_node.append(new_subtree) + # Juxtapose + else: + new_subtree = nltk.Tree(new_label, [target_node, new_subtree]) + if len(target_pos) > 0: + parent_node = parent(tree, target_pos) + parent_node[-1] = new_subtree + else: + tree = new_subtree + return tree + + tree, root, terminals = None, tree.label(), tree.pos() + for terminal, action in zip(terminals, actions): + tree = execute(tree, terminal, action) + # recover unary chains + nodes = [tree] + while nodes: + node = nodes.pop() + if isinstance(node, nltk.Tree): + nodes.extend(node) + if join in node.label(): + labels = node.label().split(join) + node.set_label(labels[0]) + subtree = nltk.Tree(labels[-1], node) + for label in reversed(labels[1:-1]): + subtree = nltk.Tree(label, [subtree]) + node[:] = [subtree] + return nltk.Tree(root, [tree]) + + @classmethod + def action2span( + cls, + action: torch.Tensor, + spans: torch.Tensor = None, + nul_index: int = -1, + mask: torch.BoolTensor = None + ) -> torch.Tensor: + r""" + Converts a batch of the tensorized action at a given step into spans. + + Args: + action (~torch.Tensor): ``[3, batch_size]``. + A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels. + spans (~torch.Tensor): + Spans generated at previous steps, ``None`` at the first step. Default: ``None``. + nul_index (int): + The index for the obj:`NUL` token, representing the Attach action. Default: -1. + mask (~torch.BoolTensor): ``[batch_size]``. + The mask for covering the unpadded tokens. + + Returns: + A tensor representing a batch of spans for the given step. + + Examples: + >>> from collections import Counter + >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab + >>> from supar.utils.common import NUL + >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL), + (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL), + (0, NUL, NUL)]) + >>> vocab = Vocab(Counter(sorted(set([*parents, *news])))) + >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1) + >>> spans = None + >>> for action in actions.unbind(-1): + ... spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL]) + ... + >>> spans + tensor([[[-1, 1, -1, -1, -1, -1, -1, 3], + [-1, -1, -1, -1, -1, -1, 4, -1], + [-1, -1, -1, 1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, 2, -1], + [-1, -1, -1, -1, -1, -1, 1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1]]]) + >>> sequence = torch.where(spans.ge(0)) + >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]])) + >>> sequence + [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')] + >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP') + >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print() + TOP + | + S + ______________|_______________________ + | VP | + | ________|___ | + | | NP | + | | ________|___ | + | | | PP | + | | | _______|___ | + NP | NP | NP | + | | | | ___|_____ | + _ _ _ _ _ _ _ + | | | | | | | + Arthur is King of the Britons . + + """ + + # [batch_size] + target, parent, new = action + if spans is None: + spans = action.new_full((action.shape[1], 2, 2), -1) + spans[:, 0, 1] = parent + return spans + if mask is None: + mask = torch.ones_like(target, dtype=bool) + juxtapose_mask = new.ne(nul_index) & mask + # ancestor nodes are those on the rightmost chain and higher than the target node + # [batch_size, seq_len] + rightmost_mask = spans[..., -1].ge(0) + ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1 + # should not include the target node for the Juxtapose action + ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1)) + target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1] + # the right boundaries of ancestor nodes should be aligned with the new generated terminals + spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1) + spans[..., -2].masked_fill_(ancestor_mask, -1) + spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask] + spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask] + # [batch_size, seq_len+1, seq_len+1] + spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1) + return spans + + def load( + self, + data: Union[str, Iterable], + lang: Optional[str] = None, + **kwargs + ) -> List[AttachJuxtaposeTreeSentence]: + r""" + Args: + data (Union[str, Iterable]): + A filename or a list of instances. + lang (str): + Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize. + ``None`` if tokenization is not required. + Default: ``None``. + + Returns: + A list of :class:`AttachJuxtaposeTreeSentence` instances. + """ + + if lang is not None: + tokenizer = Tokenizer(lang) + if isinstance(data, str) and os.path.exists(data): + if data.endswith('.txt'): + data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1) + else: + data = open(data) + else: + if lang is not None: + data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)] + else: + data = [data] if isinstance(data[0], str) else data + + index = 0 + for s in data: + + try: + tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root) + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + except ValueError: + logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!") + continue + except IndexError: + tree = nltk.Tree.fromstring('(S ' + s + ')') + sentence = AttachJuxtaposeTreeSentence(self, tree, index) + else: + yield sentence + index += 1 + self.root = tree.label() + + +class AttachJuxtaposeTreeSentence(Sentence): + r""" + Args: + transform (AttachJuxtaposeTree): + A :class:`AttachJuxtaposeTree` object. + tree (nltk.tree.Tree): + A :class:`nltk.tree.Tree` object. + index (Optional[int]): + Index of the sentence in the corpus. Default: ``None``. + """ + + def __init__( + self, + transform: AttachJuxtaposeTree, + tree: nltk.Tree, + index: Optional[int] = None + ) -> AttachJuxtaposeTreeSentence: + super().__init__(transform, index) + + words, tags = zip(*tree.pos()) + nodes, parents, news = None, None, None + if transform.training: + oracle_tree = tree.copy(True) + # the root node must have a unary chain + if len(oracle_tree) > 1: + oracle_tree[:] = [nltk.Tree('*', oracle_tree)] + oracle_tree.collapse_unary(joinChar='::') + if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree): + oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]]) + nodes, parents, news = zip(*transform.tree2action(oracle_tree)) + tags = [x.split("##")[0] for x in tags] + self.values = [words, tags, tree, nodes, parents, news] + + def __repr__(self): + return self.values[-4].pformat(1000000) + + def pretty_print(self): + self.values[-4].pretty_print() -- GitLab