edereynal Claude Opus 4.6 commited on
Commit
4aa1290
·
1 Parent(s): f33e554

Add paper.pdf, expand benchmarks to 65/67 entries, add MLM-pretrained model

Browse files

- Added paper.pdf to repo
- Expanded numeracy test from 29 to 65 ordering groups
- Expanded retrieval test from 20 to 67 query-match pairs
- Added MLM-pretrained checkpoint as 5th benchmark model
- Updated benchmark output formatting for 5-model comparison

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

paper.pdf ADDED
Binary file (57.2 kB). View file
 
tests/results/Bash tool output (oqtjfp) ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
2
+ Device: mps
3
+
4
+ Extracting encoder weights from CLS checkpoint...
5
+ Loading embedding model (BAAI/bge-base-en-v1.5)...
6
+
7
+ Loading weights: 0%| | 0/199 [00:00<?, ?it/s]
8
+ Loading weights: 100%|██████████| 199/199 [00:00<00:00, 9515.99it/s]
9
+ BertModel LOAD REPORT from: BAAI/bge-base-en-v1.5
10
+ Key | Status | |
11
+ ------------------------+------------+--+-
12
+ embeddings.position_ids | UNEXPECTED | |
13
+
14
+ Notes:
15
+ - UNEXPECTED :can be ignored when loading from different task/architecture; not ok if you expect identical arch.
16
+ Loading plain ModernBERT (answerdotai/ModernBERT-base)...
17
+
18
+ Loading weights: 0%| | 0/134 [00:00<?, ?it/s]
19
+ Loading weights: 100%|██████████| 134/134 [00:00<00:00, 5816.50it/s]
20
+ ModernBertModel LOAD REPORT from: answerdotai/ModernBERT-base
21
+ Key | Status | |
22
+ ------------------+------------+--+-
23
+ decoder.bias | UNEXPECTED | |
24
+ head.norm.weight | UNEXPECTED | |
25
+ head.dense.weight | UNEXPECTED | |
26
+
27
+ Notes:
28
+ - UNEXPECTED :can be ignored when loading from different task/architecture; not ok if you expect identical arch.
29
+ Loading FinancialModernBERT from /tmp/_test_cls_weights.pt...
30
+ Loading FinancialModernBERT from /tmp/_test_jepa_weights.pt...
31
+
32
+ ==========================================================================================================================
33
+ CLS RETRIEVAL BENCHMARK (Financial)
34
+ 67 queries, 67 candidates
35
+ ==========================================================================================================================
36
+ BGE-base ModernBERT CLS (enc/dec) CLS (JEPA)
37
+ sim rank sim rank sim rank sim rank
38
+ --------------------------------------------------------------------------------------------------------------------------
39
+ Revenue growth 0.724 1 HIT 0.979 16 0.785 1 HIT 0.386 30
40
+ Earnings miss 0.775 1 HIT 0.972 35 0.714 5 0.305 41
41
+ Debt issuance 0.661 1 HIT 0.965 56 0.662 23 0.182 39
42
+ Dividend cut 0.840 1 HIT 0.976 16 0.745 1 HIT 0.799 2
43
+ Share buyback 0.738 1 HIT 0.980 18 0.604 34 0.861 2
44
+ Margin expansion 0.785 1 HIT 0.977 8 0.718 2 0.746 13
45
+ Acquisition 0.762 1 HIT 0.973 42 0.766 6 0.545 17
46
+ Credit downgrade 0.780 1 HIT 0.981 9 0.782 1 HIT 0.219 13
47
+ IPO pricing 0.696 2 0.971 37 0.750 1 HIT 0.748 2
48
+ Guidance raise 0.707 1 HIT 0.965 22 0.721 1 HIT 0.641 8
49
+ Restructuring 0.808 1 HIT 0.983 18 0.656 14 0.687 9
50
+ Cash position 0.830 1 HIT 0.976 16 0.906 1 HIT 0.763 3
51
+ Interest expense 0.812 1 HIT 0.970 31 0.804 1 HIT 0.543 19
52
+ Capex 0.680 1 HIT 0.968 53 0.782 1 HIT 0.291 20
53
+ Inventory build 0.815 1 HIT 0.978 12 0.777 1 HIT 0.348 41
54
+ Tax rate 0.782 1 HIT 0.978 33 0.718 3 0.258 3
55
+ Leverage ratio 0.791 1 HIT 0.990 1 HIT 0.715 1 HIT 0.640 8
56
+ Free cash flow 0.835 1 HIT 0.974 16 0.862 1 HIT 0.507 32
57
+ Goodwill impairmen 0.821 1 HIT 0.977 19 0.791 1 HIT 0.699 3
58
+ Forex impact 0.743 1 HIT 0.963 57 0.841 1 HIT 0.916 2
59
+ Merger terms 0.792 1 HIT 0.981 2 0.635 3 0.644 3
60
+ Spinoff 0.773 1 HIT 0.981 9 0.749 7 0.745 6
61
+ Divestiture 0.860 1 HIT 0.965 33 0.855 1 HIT 0.582 4
62
+ Joint venture 0.803 1 HIT 0.977 31 0.864 1 HIT 0.403 13
63
+ Hostile bid 0.821 1 HIT 0.991 1 HIT 0.863 1 HIT 0.685 9
64
+ Convertible bonds 0.751 1 HIT 0.979 9 0.812 1 HIT 0.802 2
65
+ Preferred stock 0.876 1 HIT 0.976 34 0.812 2 0.514 3
66
+ Rights offering 0.830 1 HIT 0.973 18 0.749 1 HIT 0.935 1 HIT
67
+ Warrant exercise 0.844 1 HIT 0.978 3 0.738 1 HIT 0.697 1 HIT
68
+ Same-store sales 0.702 2 0.970 1 HIT 0.768 1 HIT 0.772 10
69
+ Subscriber growth 0.777 1 HIT 0.984 18 0.838 1 HIT 0.361 45
70
+ Load factor 0.773 1 HIT 0.972 6 0.801 1 HIT 0.918 1 HIT
71
+ Occupancy rate 0.790 1 HIT 0.979 6 0.720 3 0.948 2
72
+ ARPU 0.909 1 HIT 0.964 17 0.910 1 HIT 0.675 20
73
+ DAU/MAU ratio 0.857 1 HIT 0.976 2 0.827 1 HIT 0.539 2
74
+ Provision/credit l 0.784 1 HIT 0.985 3 0.877 1 HIT 0.952 1 HIT
75
+ NIM 0.749 1 HIT 0.961 53 0.887 1 HIT 0.089 37
76
+ CET1 ratio 0.687 1 HIT 0.979 33 0.886 1 HIT 0.956 1 HIT
77
+ Combined ratio 0.766 1 HIT 0.985 3 0.912 1 HIT 0.442 34
78
+ Premium growth 0.807 1 HIT 0.972 14 0.816 1 HIT 0.481 24
79
+ NOI 0.804 1 HIT 0.982 6 0.798 1 HIT 0.659 10
80
+ FFO 0.838 1 HIT 0.968 16 0.881 1 HIT 0.726 16
81
+ Cap rate 0.837 1 HIT 0.981 12 0.829 1 HIT 0.928 1 HIT
82
+ ARR 0.739 1 HIT 0.970 51 0.661 4 0.172 50
83
+ NRR 0.753 1 HIT 0.985 1 HIT 0.696 4 0.742 7
84
+ RPO 0.726 1 HIT 0.979 9 0.794 1 HIT 0.796 5
85
+ Billings 0.781 1 HIT 0.978 13 0.819 1 HIT 0.865 4
86
+ Customer count 0.759 1 HIT 0.977 22 0.720 1 HIT 0.819 10
87
+ Production volume 0.801 1 HIT 0.975 14 0.805 2 0.492 5
88
+ Proved reserves 0.873 1 HIT 0.982 1 HIT 0.746 2 0.416 27
89
+ Realized price 0.784 1 HIT 0.976 25 0.851 1 HIT 0.737 5
90
+ Finding cost 0.902 1 HIT 0.983 1 HIT 0.903 1 HIT 0.642 12
91
+ AISC 0.818 1 HIT 0.977 16 0.871 1 HIT 0.874 2
92
+ Bond yield move 0.763 1 HIT 0.966 50 0.770 1 HIT 0.180 60
93
+ Spread tightening 0.773 1 HIT 0.977 12 0.746 4 0.801 4
94
+ Rate hike impact 0.714 1 HIT 0.966 57 0.881 1 HIT 0.989 1 HIT
95
+ Inflation impact 0.812 1 HIT 0.982 1 HIT 0.804 1 HIT 0.820 9
96
+ Revenue beat 0.805 1 HIT 0.978 1 HIT 0.626 19 0.677 1 HIT
97
+ Guidance cut 0.776 1 HIT 0.977 28 0.699 16 0.633 7
98
+ Segment breakdown 0.900 1 HIT 0.979 8 0.886 1 HIT 0.617 21
99
+ One-time charges 0.790 1 HIT 0.980 7 0.834 1 HIT 0.724 3
100
+ Restatement 0.838 1 HIT 0.981 7 0.762 9 -0.234 50
101
+ Pension funding 0.816 1 HIT 0.985 3 0.827 1 HIT 0.913 1 HIT
102
+ Litigation settlem 0.823 1 HIT 0.982 1 HIT 0.841 1 HIT 0.840 3
103
+ Regulatory fine 0.775 1 HIT 0.983 3 0.758 1 HIT 0.326 38
104
+ CEO compensation 0.847 1 HIT 0.986 1 HIT 0.687 1 HIT 0.367 4
105
+ Store openings 0.897 1 HIT 0.978 27 0.858 1 HIT 0.852 2
106
+ --------------------------------------------------------------------------------------------------------------------------
107
+ Recall@1 65/67 10/67 48/67 9/67
108
+ Mean rank 1.0 18.0 3.1 13.2
109
+ MRR 0.985 0.238 0.786 0.295
110
+ ==========================================================================================================================
111
+ Shell cwd was reset to /Users/eloireynal/Documents/My projects/website_based_financial_prediction
tests/results/{Bash tool output (zgf110) → Bash tool output (xq3wlt)} RENAMED
@@ -1,9 +1,11 @@
 
1
  Device: mps
2
 
 
3
  Loading embedding model (BAAI/bge-base-en-v1.5)...
4
 
5
  Loading weights: 0%| | 0/199 [00:00<?, ?it/s]
6
- Loading weights: 100%|██████████| 199/199 [00:00<00:00, 8604.19it/s]
7
  BertModel LOAD REPORT from: BAAI/bge-base-en-v1.5
8
  Key | Status | |
9
  ------------------------+------------+--+-
@@ -14,17 +16,17 @@ embeddings.position_ids | UNEXPECTED | |
14
  Loading plain ModernBERT (answerdotai/ModernBERT-base)...
15
 
16
  Loading weights: 0%| | 0/134 [00:00<?, ?it/s]
17
- Loading weights: 100%|██████████| 134/134 [00:00<00:00, 5553.23it/s]
18
  ModernBertModel LOAD REPORT from: answerdotai/ModernBERT-base
19
  Key | Status | |
20
  ------------------+------------+--+-
21
- head.dense.weight | UNEXPECTED | |
22
  head.norm.weight | UNEXPECTED | |
 
23
  decoder.bias | UNEXPECTED | |
24
 
25
  Notes:
26
  - UNEXPECTED :can be ignored when loading from different task/architecture; not ok if you expect identical arch.
27
- Loading FinancialModernBERT from /Users/eloireynal/.cache/huggingface/hub/models--edereynal--financial_bert/snapshots/9ba65cb3df038c0591cdfc3c44842bc036f0a45a/checkpoints/cls_encoder_weights.pt...
28
  Loading FinancialModernBERT from /tmp/_test_jepa_weights.pt...
29
 
30
  ============================================================================================================================================
@@ -34,37 +36,73 @@ Loading FinancialModernBERT from /tmp/_test_jepa_weights.pt...
34
  --- BGE-base --- --- ModernBERT --- - CLS (enc/dec) - --- CLS (JEPA) ---
35
  l→m m→h l→h l→m m→h l→h l→m m→h l→h l→m m→h l→h
36
  --------------------------------------------------------------------------------------------------------------------------------------------
37
- Revenue 0.0003 0.0004 0.0004 soft 0.0022 0.0072 0.0045 - 0.1214 0.1155 0.1319 HARD 0.0540 0.0703 0.1111 HARD
38
- EBITDA 0.0003 0.0004 0.0003 - 0.0015 0.0019 0.0015 - 0.1238 0.0983 0.1272 HARD 0.1959 0.1967 0.1216 -
39
- Total debt 0.0003 0.0006 0.0004 soft 0.0018 0.0016 0.0024 HARD 0.1294 0.1222 0.1320 HARD 0.0847 0.0978 0.0992 HARD
40
- Liquidity 0.0005 0.0003 0.0003 - 0.0036 0.0043 0.0018 - 0.1039 0.0849 0.1161 HARD 0.1650 0.1431 0.1102 -
41
- Interest expense 0.0004 0.0004 0.0003 - 0.0023 0.0019 0.0031 HARD 0.0976 0.1150 0.1134 soft 0.6354 0.7224 0.9765 HARD
42
- R&D spend 0.0003 0.0003 0.0002 - 0.0011 0.0010 0.0007 - 0.1093 0.1134 0.1108 - 0.0689 0.0847 0.0482 -
43
- Operating cash flow 0.0003 0.0003 0.0003 - 0.0018 0.0010 0.0016 soft 0.1183 0.1323 0.1489 HARD 0.1011 0.1623 0.1138 -
44
- Total assets 0.0004 0.0003 0.0004 HARD 0.0025 0.0040 0.0050 HARD 0.1354 0.1351 0.1515 HARD 0.0940 0.0653 0.1226 HARD
45
- Capital returned 0.0004 0.0004 0.0004 HARD 0.0011 0.0024 0.0051 HARD 0.1056 0.1333 0.1362 HARD 1.1054 0.9924 0.8605 -
46
- Gross profit 0.0002 0.0002 0.0004 HARD 0.0021 0.0018 0.0013 - 0.1331 0.1268 0.1337 HARD 0.3321 0.0652 0.4545 HARD
47
- Capex 0.0004 0.0002 0.0003 soft 0.0011 0.0015 0.0010 - 0.1172 0.1031 0.1363 HARD 0.1793 0.0599 0.1995 HARD
48
- Goodwill 0.0003 0.0003 0.0004 HARD 0.0038 0.0017 0.0076 HARD 0.1388 0.1357 0.1425 HARD 0.0859 0.0555 0.0406 -
49
- SGA expense 0.0003 0.0003 0.0002 - 0.0015 0.0013 0.0011 - 0.0934 0.1017 0.1163 HARD 0.1134 0.1141 0.0419 -
50
- Net income 0.0003 0.0003 0.0004 HARD 0.0018 0.0055 0.0111 HARD 0.1253 0.1349 0.1398 HARD 0.0497 0.0953 0.1585 HARD
51
- EBITDA margin 0.0003 0.0003 0.0003 - 0.0018 0.0024 0.0010 - 0.0764 0.0809 0.0809 soft 0.2232 0.2604 0.3416 HARD
52
- Net margin 0.0006 0.0005 0.0005 - 0.0044 0.0009 0.0043 soft 0.0765 0.0961 0.0918 soft 0.2753 0.1836 0.0372 -
53
- Revenue growth % 0.0004 0.0005 0.0004 - 0.0013 0.0009 0.0021 HARD 0.1041 0.0914 0.0967 - 0.0201 0.0219 0.0109 -
54
- Revenue decline % 0.0003 0.0003 0.0002 - 0.0007 0.0013 0.0009 - 0.1059 0.1057 0.0933 - 0.0424 0.0513 0.0399 -
55
- Dividend yield 0.0003 0.0005 0.0005 soft 0.0008 0.0020 0.0027 HARD 0.1134 0.0949 0.0925 - 0.0300 0.0397 0.0769 HARD
56
- Debt-to-equity 0.0003 0.0004 0.0003 soft 0.0024 0.0031 0.0022 - 0.0899 0.0580 0.0844 soft 0.2764 0.4529 0.2267 -
57
- P/E ratio 0.0003 0.0003 0.0004 HARD 0.0019 0.0013 0.0011 - 0.0865 0.0964 0.0916 soft 0.1095 0.0816 0.2450 HARD
58
- Current ratio 0.0003 0.0003 0.0004 HARD 0.0018 0.0021 0.0019 - 0.1348 0.0915 0.1158 soft 1.3401 1.2263 0.0962 -
59
- EPS 0.0002 0.0003 0.0002 - 0.0062 0.0036 0.0066 HARD 0.1282 0.0887 0.1144 soft 0.2087 0.6721 0.7372 HARD
60
- Book value/share 0.0002 0.0003 0.0003 HARD 0.0016 0.0024 0.0050 HARD 0.0920 0.0893 0.0980 HARD 0.9521 0.0479 0.9496 soft
61
- Headcount 0.0004 0.0003 0.0003 - 0.0031 0.0029 0.0013 - 0.1471 0.1331 0.1269 - 0.1263 0.0855 0.1784 HARD
62
- Tbl: income stmt 0.0000 0.0001 0.0000 - 0.0070 0.0072 0.0017 - 0.1855 0.1661 0.2966 HARD 0.2581 0.3589 0.2519 -
63
- Tbl: balance sheet 0.0000 0.0000 0.0000 HARD 0.0022 0.0031 0.0016 - 0.1902 0.1688 0.2157 HARD 0.0854 0.0237 0.0986 HARD
64
- Tbl: cash flow 0.0000 0.0000 0.0000 - 0.0013 0.0023 0.0035 HARD 0.1876 0.1951 0.2121 HARD 0.6762 0.0641 0.5351 soft
65
- Tbl: per share 0.0000 0.0000 0.0000 HARD 0.0038 0.0119 0.0078 - 0.2135 0.1909 0.2156 HARD 0.7461 0.6553 0.2032 -
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  --------------------------------------------------------------------------------------------------------------------------------------------
67
- HARD 10/29 11/29 17/29 13/29
68
- SOFT 15/29 13/29 24/29 15/29
69
  ============================================================================================================================================
70
  Shell cwd was reset to /Users/eloireynal/Documents/My projects/website_based_financial_prediction
 
1
+ Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
2
  Device: mps
3
 
4
+ Extracting encoder weights from CLS checkpoint...
5
  Loading embedding model (BAAI/bge-base-en-v1.5)...
6
 
7
  Loading weights: 0%| | 0/199 [00:00<?, ?it/s]
8
+ Loading weights: 100%|██████████| 199/199 [00:00<00:00, 7736.27it/s]
9
  BertModel LOAD REPORT from: BAAI/bge-base-en-v1.5
10
  Key | Status | |
11
  ------------------------+------------+--+-
 
16
  Loading plain ModernBERT (answerdotai/ModernBERT-base)...
17
 
18
  Loading weights: 0%| | 0/134 [00:00<?, ?it/s]
19
+ Loading weights: 100%|██████████| 134/134 [00:00<00:00, 6264.62it/s]
20
  ModernBertModel LOAD REPORT from: answerdotai/ModernBERT-base
21
  Key | Status | |
22
  ------------------+------------+--+-
 
23
  head.norm.weight | UNEXPECTED | |
24
+ head.dense.weight | UNEXPECTED | |
25
  decoder.bias | UNEXPECTED | |
26
 
27
  Notes:
28
  - UNEXPECTED :can be ignored when loading from different task/architecture; not ok if you expect identical arch.
29
+ Loading FinancialModernBERT from /tmp/_test_cls_weights.pt...
30
  Loading FinancialModernBERT from /tmp/_test_jepa_weights.pt...
31
 
32
  ============================================================================================================================================
 
36
  --- BGE-base --- --- ModernBERT --- - CLS (enc/dec) - --- CLS (JEPA) ---
37
  l→m m→h l→h l→m m→h l→h l→m m→h l→h l→m m→h l→h
38
  --------------------------------------------------------------------------------------------------------------------------------------------
39
+ Revenue 0.0003 0.0004 0.0004 soft 0.0022 0.0072 0.0045 - 0.0521 0.0482 0.0581 HARD 0.0540 0.0703 0.1111 HARD
40
+ EBITDA 0.0003 0.0004 0.0003 - 0.0015 0.0019 0.0015 - 0.0546 0.0349 0.0515 soft 0.1959 0.1967 0.1216 -
41
+ Total debt 0.0003 0.0006 0.0004 soft 0.0018 0.0016 0.0024 HARD 0.0478 0.0489 0.0584 HARD 0.0847 0.0978 0.0992 HARD
42
+ Liquidity 0.0005 0.0003 0.0003 - 0.0036 0.0043 0.0018 - 0.0433 0.0363 0.0445 HARD 0.1650 0.1431 0.1102 -
43
+ Interest expense 0.0004 0.0004 0.0003 - 0.0023 0.0019 0.0031 HARD 0.0589 0.0462 0.0541 soft 0.6354 0.7224 0.9765 HARD
44
+ R&D spend 0.0003 0.0003 0.0002 - 0.0011 0.0010 0.0007 - 0.0467 0.0322 0.0417 soft 0.0689 0.0847 0.0482 -
45
+ Operating cash flow 0.0003 0.0003 0.0003 - 0.0018 0.0010 0.0016 soft 0.0465 0.0528 0.0632 HARD 0.1011 0.1623 0.1138 -
46
+ Total assets 0.0004 0.0003 0.0004 HARD 0.0025 0.0040 0.0050 HARD 0.0547 0.0559 0.0671 HARD 0.0940 0.0653 0.1226 HARD
47
+ Capital returned 0.0004 0.0004 0.0004 HARD 0.0011 0.0024 0.0051 HARD 0.0513 0.0472 0.0554 HARD 1.1054 0.9924 0.8605 -
48
+ Gross profit 0.0002 0.0002 0.0004 HARD 0.0021 0.0018 0.0013 - 0.0452 0.0400 0.0448 soft 0.3321 0.0652 0.4545 HARD
49
+ Capex 0.0004 0.0002 0.0003 soft 0.0011 0.0015 0.0010 - 0.0567 0.0386 0.0549 soft 0.1793 0.0599 0.1995 HARD
50
+ Goodwill 0.0003 0.0003 0.0004 HARD 0.0038 0.0017 0.0076 HARD 0.0516 0.0509 0.0644 HARD 0.0859 0.0555 0.0406 -
51
+ SGA expense 0.0003 0.0003 0.0002 - 0.0015 0.0013 0.0011 - 0.0371 0.0377 0.0462 HARD 0.1134 0.1141 0.0419 -
52
+ Net income 0.0003 0.0003 0.0004 HARD 0.0018 0.0055 0.0111 HARD 0.0539 0.0558 0.0763 HARD 0.0497 0.0953 0.1585 HARD
53
+ EBITDA margin 0.0003 0.0003 0.0003 - 0.0018 0.0024 0.0010 - 0.0428 0.0364 0.0366 - 0.2232 0.2604 0.3416 HARD
54
+ Net margin 0.0006 0.0005 0.0005 - 0.0044 0.0009 0.0043 soft 0.0493 0.0487 0.0468 - 0.2753 0.1836 0.0372 -
55
+ Revenue growth % 0.0004 0.0005 0.0004 - 0.0013 0.0009 0.0021 HARD 0.0568 0.0401 0.0497 soft 0.0201 0.0219 0.0109 -
56
+ Revenue decline % 0.0003 0.0003 0.0002 - 0.0007 0.0013 0.0009 - 0.0579 0.0494 0.0510 - 0.0424 0.0513 0.0399 -
57
+ Dividend yield 0.0003 0.0005 0.0005 soft 0.0008 0.0020 0.0027 HARD 0.0528 0.0451 0.0424 - 0.0300 0.0397 0.0769 HARD
58
+ Debt-to-equity 0.0003 0.0004 0.0003 soft 0.0024 0.0031 0.0022 - 0.0384 0.0309 0.0384 soft 0.2764 0.4529 0.2267 -
59
+ P/E ratio 0.0003 0.0003 0.0004 HARD 0.0019 0.0013 0.0011 - 0.0349 0.0321 0.0330 - 0.1095 0.0816 0.2450 HARD
60
+ Current ratio 0.0003 0.0003 0.0004 HARD 0.0018 0.0021 0.0019 - 0.0511 0.0452 0.0510 soft 1.3401 1.2263 0.0962 -
61
+ EPS 0.0002 0.0003 0.0002 - 0.0062 0.0036 0.0066 HARD 0.0481 0.0362 0.0501 HARD 0.2087 0.6721 0.7372 HARD
62
+ Book value/share 0.0002 0.0003 0.0003 HARD 0.0016 0.0024 0.0050 HARD 0.0410 0.0317 0.0389 soft 0.9521 0.0479 0.9496 soft
63
+ Headcount 0.0004 0.0003 0.0003 - 0.0031 0.0029 0.0013 - 0.0693 0.0506 0.0651 soft 0.1263 0.0855 0.1784 HARD
64
+ Tbl: income stmt 0.0000 0.0001 0.0000 - 0.0070 0.0072 0.0017 - 0.0821 0.0811 0.1180 HARD 0.2581 0.3589 0.2519 -
65
+ Tbl: balance sheet 0.0000 0.0000 0.0000 HARD 0.0022 0.0031 0.0016 - 0.0920 0.0828 0.1067 HARD 0.0854 0.0237 0.0986 HARD
66
+ Tbl: cash flow 0.0000 0.0000 0.0000 - 0.0013 0.0023 0.0035 HARD 0.0758 0.0712 0.0804 HARD 0.6762 0.0641 0.5351 soft
67
+ Tbl: per share 0.0000 0.0000 0.0000 HARD 0.0038 0.0119 0.0078 - 0.1030 0.0754 0.0773 - 0.7461 0.6553 0.2032 -
68
+ Depreciation 0.0003 0.0003 0.0004 HARD 0.0015 0.0070 0.0041 - 0.0689 0.0452 0.0957 HARD 0.2436 0.0857 0.0789 -
69
+ Amortization 0.0002 0.0003 0.0003 soft 0.0010 0.0005 0.0006 - 0.0413 0.0434 0.0571 HARD 0.0056 0.0063 0.0100 HARD
70
+ Deferred revenue 0.0004 0.0003 0.0002 - 0.0050 0.0029 0.0025 - 0.0475 0.0295 0.0439 soft 0.0623 0.1051 0.1000 soft
71
+ Accounts receivable 0.0005 0.0005 0.0004 - 0.0027 0.0026 0.0022 - 0.0448 0.0493 0.0558 HARD 0.0296 0.0489 0.0415 soft
72
+ Accounts payable 0.0004 0.0004 0.0005 HARD 0.0057 0.0020 0.0050 soft 0.0621 0.0314 0.0735 HARD 0.0383 0.0318 0.0477 HARD
73
+ Inventory 0.0003 0.0003 0.0004 HARD 0.0029 0.0025 0.0059 HARD 0.0444 0.0415 0.0456 HARD 0.1213 0.0809 0.0465 -
74
+ Lease obligations 0.0005 0.0005 0.0003 - 0.0008 0.0009 0.0007 - 0.0482 0.0440 0.0684 HARD 0.0641 0.0871 0.0761 soft
75
+ Pension liabilities 0.0003 0.0003 0.0003 - 0.0018 0.0019 0.0008 - 0.0483 0.0526 0.0597 HARD 0.0952 0.1911 0.0612 -
76
+ Impairment charges 0.0003 0.0002 0.0004 HARD 0.0010 0.0009 0.0010 HARD 0.0429 0.0369 0.0581 HARD 0.0468 0.0410 0.0992 HARD
77
+ Tax expense 0.0005 0.0004 0.0004 soft 0.0014 0.0007 0.0009 - 0.0576 0.0479 0.0717 HARD 0.0374 0.1584 0.2467 HARD
78
+ Cash from financing 0.0003 0.0003 0.0003 - 0.0010 0.0011 0.0014 HARD 0.0623 0.0400 0.0591 soft 0.1822 0.3322 0.2348 -
79
+ Cash from investing 0.0002 0.0003 0.0002 soft 0.0021 0.0010 0.0012 - 0.0653 0.0385 0.0606 soft 0.0739 0.0704 0.0768 HARD
80
+ SBC expense 0.0004 0.0003 0.0003 - 0.0010 0.0005 0.0013 HARD 0.0518 0.0414 0.0842 HARD 0.1861 0.1256 0.0908 -
81
+ Restructuring 0.0004 0.0004 0.0004 soft 0.0016 0.0006 0.0017 HARD 0.0544 0.0365 0.0549 HARD 0.0494 0.0575 0.0354 -
82
+ Working capital 0.0004 0.0004 0.0005 HARD 0.0077 0.0070 0.0013 - 0.0515 0.0373 0.0630 HARD 0.2103 0.0875 0.0903 -
83
+ Intangible assets 0.0004 0.0002 0.0004 HARD 0.0013 0.0013 0.0016 HARD 0.0467 0.0318 0.0458 soft 0.0559 0.0315 0.0287 -
84
+ Total equity 0.0003 0.0003 0.0004 HARD 0.0025 0.0029 0.0019 - 0.0427 0.0452 0.0557 HARD 0.4757 0.6152 0.1298 -
85
+ Retained earnings 0.0003 0.0003 0.0002 - 0.0010 0.0046 0.0027 - 0.0533 0.0533 0.0702 HARD 0.0591 0.0871 0.0769 soft
86
+ Cost of revenue 0.0003 0.0003 0.0003 soft 0.0033 0.0024 0.0007 - 0.0446 0.0434 0.0574 HARD 0.1603 0.0266 0.1221 soft
87
+ Pretax income 0.0002 0.0002 0.0001 - 0.0012 0.0017 0.0022 HARD 0.0562 0.0443 0.0753 HARD 0.0815 0.0194 0.0588 soft
88
+ Loan loss provision 0.0003 0.0004 0.0004 HARD 0.0009 0.0011 0.0006 - 0.0514 0.0345 0.0545 HARD 0.0101 0.0100 0.0078 -
89
+ ROE 0.0003 0.0003 0.0003 soft 0.0022 0.0044 0.0026 - 0.0529 0.0344 0.0512 soft 0.0467 0.0422 0.0148 -
90
+ ROA 0.0004 0.0003 0.0003 - 0.0035 0.0012 0.0037 HARD 0.0501 0.0548 0.0509 - 0.0263 0.1020 0.1006 soft
91
+ Gross margin 0.0003 0.0003 0.0004 HARD 0.0016 0.0009 0.0030 HARD 0.0408 0.0280 0.0404 soft 0.1060 0.0542 0.0475 -
92
+ Interest coverage 0.0002 0.0003 0.0001 - 0.0021 0.0015 0.0019 soft 0.0513 0.0466 0.0413 - 0.1179 0.0591 0.0784 -
93
+ Asset turnover 0.0002 0.0002 0.0003 HARD 0.0007 0.0020 0.0016 soft 0.0425 0.0370 0.0478 HARD 0.0624 0.4225 0.5777 HARD
94
+ Payout ratio 0.0003 0.0003 0.0004 HARD 0.0008 0.0018 0.0015 soft 0.0398 0.0330 0.0355 - 0.0543 0.0571 0.0312 -
95
+ Tax rate 0.0003 0.0002 0.0003 HARD 0.0011 0.0009 0.0006 - 0.0410 0.0243 0.0328 soft 0.2419 0.0693 0.0739 -
96
+ NPL ratio 0.0003 0.0004 0.0003 - 0.0016 0.0009 0.0015 soft 0.0572 0.0445 0.0530 soft 0.0229 0.0264 0.0027 -
97
+ FCF per share 0.0002 0.0002 0.0002 - 0.0033 0.0017 0.0037 HARD 0.0456 0.0321 0.0441 soft 0.3069 0.1253 0.2382 soft
98
+ TBV per share 0.0002 0.0003 0.0003 - 0.0025 0.0015 0.0023 soft 0.0447 0.0365 0.0392 - 0.4537 0.1994 0.1249 -
99
+ Revenue per share 0.0002 0.0003 0.0003 soft 0.0027 0.0034 0.0063 HARD 0.0531 0.0338 0.0516 soft 0.8555 0.8922 0.0835 -
100
+ Shares outstanding 0.0004 0.0004 0.0005 HARD 0.0021 0.0021 0.0017 - 0.0370 0.0379 0.0365 - 0.2164 0.2887 0.1545 -
101
+ Tbl: segment rev 0.0000 0.0000 0.0000 soft 0.0036 0.0028 0.0031 - 0.0666 0.0586 0.0932 HARD 0.1748 0.2573 0.5099 HARD
102
+ Tbl: quarterly 0.0000 0.0000 0.0000 HARD 0.0057 0.0069 0.0135 HARD 0.0578 0.0553 0.0790 HARD 0.4234 0.1566 0.3564 soft
103
+ Tbl: debt maturity 0.0000 0.0000 0.0000 HARD 0.0014 0.0048 0.0043 soft 0.0919 0.0726 0.1154 HARD 0.1246 0.0562 0.1795 HARD
104
  --------------------------------------------------------------------------------------------------------------------------------------------
105
+ HARD 25/65 23/65 34/65 21/65
106
+ SOFT 38/65 32/65 54/65 32/65
107
  ============================================================================================================================================
108
  Shell cwd was reset to /Users/eloireynal/Documents/My projects/website_based_financial_prediction
tests/test_cls_retrieval.py CHANGED
@@ -125,6 +125,242 @@ TEST_PAIRS = [
125
  "query": "Unfavorable currency translation reduced reported revenue by $620 million and operating income by $185 million, primarily from a 12% decline in the euro and an 8% drop in the yen.",
126
  "match": "Foreign exchange headwinds cost the company over $600 million in top-line revenue and close to $200 million in operating profit as the euro and yen each dropped roughly 10% against the dollar.",
127
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  ]
129
 
130
 
@@ -223,7 +459,7 @@ def resolve_cls_checkpoint():
223
  ckpt_src = os.path.join(
224
  os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
225
  "website_based_financial_prediction",
226
- "checkpoints", "cls", "checkpoint_epoch5", "full_model.pt",
227
  )
228
  if not os.path.exists(ckpt_src):
229
  from huggingface_hub import hf_hub_download
@@ -246,6 +482,28 @@ def resolve_cls_checkpoint():
246
  return ckpt_src
247
 
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  def resolve_jepa_checkpoint():
250
  import os
251
  local = os.path.join(
@@ -293,17 +551,20 @@ def main():
293
  print(f"Device: {device}\n")
294
 
295
  cls_path = resolve_cls_checkpoint()
 
296
  jepa_path = resolve_jepa_checkpoint()
297
 
298
  em_model = load_embed_model(device)
299
  mb_tok, mb_model = load_modernbert(device)
300
  fb_tok, fb_model = load_financial_bert(device, cls_path)
 
301
  jp_tok, jp_model = load_financial_bert(device, jepa_path, strict=False)
302
  print()
303
 
304
  em_hits, _, em_det = run_retrieval(encode_embed_model, None, em_model, device)
305
  mb_hits, _, mb_det = run_retrieval(encode_modernbert, mb_tok, mb_model, device)
306
  fb_hits, _, fb_det = run_retrieval(encode_financial_bert, fb_tok, fb_model, device)
 
307
  jp_hits, _, jp_det = run_retrieval(encode_financial_bert, jp_tok, jp_model, device)
308
 
309
  def stats(det):
@@ -316,22 +577,24 @@ def main():
316
  em_avg_rank, em_mrr = stats(em_det)
317
  mb_avg_rank, mb_mrr = stats(mb_det)
318
  fb_avg_rank, fb_mrr = stats(fb_det)
 
319
  jp_avg_rank, jp_mrr = stats(jp_det)
320
 
321
- W = 122
322
  print("=" * W)
323
  print(f"{'CLS RETRIEVAL BENCHMARK (Financial)':^{W}}")
324
- print(f"{'20 queries, 20 candidates':^{W}}")
325
  print("=" * W)
326
- print(f"{'':20s} {'BGE-base':^22s} {'ModernBERT':^22s} {'CLS (enc/dec)':^22s} {'CLS (JEPA)':^22s}")
327
- print(f"{'':20s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s}")
328
  print("-" * W)
329
 
330
- for em_d, mb_d, fb_d, jp_d in zip(em_det, mb_det, fb_det, jp_det):
331
  cat = mb_d["category"][:18]
332
  em_mark = "HIT" if em_d["hit"] else ""
333
  mb_mark = "HIT" if mb_d["hit"] else ""
334
  fb_mark = "HIT" if fb_d["hit"] else ""
 
335
  jp_mark = "HIT" if jp_d["hit"] else ""
336
 
337
  print(
@@ -339,13 +602,15 @@ def main():
339
  f" {em_d['sim_correct']:6.3f} {em_d['rank']:5d} {em_mark:>5s}"
340
  f" {mb_d['sim_correct']:6.3f} {mb_d['rank']:5d} {mb_mark:>5s}"
341
  f" {fb_d['sim_correct']:6.3f} {fb_d['rank']:5d} {fb_mark:>5s}"
 
342
  f" {jp_d['sim_correct']:6.3f} {jp_d['rank']:5d} {jp_mark:>5s}"
343
  )
344
 
345
  print("-" * W)
346
- print(f" {'Recall@1':18s} {em_hits:>5d}/20 {mb_hits:>5d}/20 {fb_hits:>5d}/20 {jp_hits:>5d}/20")
347
- print(f" {'Mean rank':18s} {em_avg_rank:>8.1f} {mb_avg_rank:>8.1f} {fb_avg_rank:>8.1f} {jp_avg_rank:>8.1f}")
348
- print(f" {'MRR':18s} {em_mrr:>8.3f} {mb_mrr:>8.3f} {fb_mrr:>8.3f} {jp_mrr:>8.3f}")
 
349
  print("=" * W)
350
 
351
 
 
125
  "query": "Unfavorable currency translation reduced reported revenue by $620 million and operating income by $185 million, primarily from a 12% decline in the euro and an 8% drop in the yen.",
126
  "match": "Foreign exchange headwinds cost the company over $600 million in top-line revenue and close to $200 million in operating profit as the euro and yen each dropped roughly 10% against the dollar.",
127
  },
128
+ # --- 40 new entries ---
129
+ {
130
+ "category": "Merger terms",
131
+ "query": "The all-stock merger assigns an exchange ratio of 0.62 shares of the acquirer for each target share, implying a deal value of $7.4 billion at the acquirer's 30-day VWAP of $54.80 per share.",
132
+ "match": "Under the agreed share-for-share transaction, each target shareholder receives roughly six-tenths of an acquirer share, valuing the deal at about $7.4 billion based on a trailing average stock price near $55.",
133
+ },
134
+ {
135
+ "category": "Spinoff",
136
+ "query": "The company announced it will spin off its industrial division into a separate publicly traded entity in Q4 2025, with the unit generating $3.1 billion in revenue and $480 million in EBITDA over the last twelve months.",
137
+ "match": "The firm plans to separate its industrial operations into a standalone listed company later this year; the division produced over $3 billion in annual sales and nearly half a billion in earnings before interest, taxes, depreciation, and amortization.",
138
+ },
139
+ {
140
+ "category": "Divestiture",
141
+ "query": "The company agreed to sell its European packaging assets to a private equity consortium for €2.2 billion, representing a multiple of 11.4x trailing EBITDA, with proceeds earmarked for debt reduction.",
142
+ "match": "A sale of European packaging operations to a buyout group for about €2.2 billion — implying roughly eleven times EBITDA — was announced, with the cash expected to pay down existing borrowings.",
143
+ },
144
+ {
145
+ "category": "Joint venture",
146
+ "query": "The two companies formed a 50/50 joint venture combining their logistics operations, which together processed 840 million parcels in 2024 and are projected to generate $1.6 billion in revenue in year one.",
147
+ "match": "An equally owned logistics venture was created by pooling both companies' networks, which handled close to a billion packages last year and is expected to bring in around $1.6 billion in first-year revenues.",
148
+ },
149
+ {
150
+ "category": "Hostile bid",
151
+ "query": "The unsolicited offer of $48 per share in cash represents a premium of 32% to the target's 60-day average closing price of $36.38 and values the company at approximately $8.9 billion on a fully diluted basis.",
152
+ "match": "The unwanted takeover approach of $48 a share, a premium of about a third above the two-month average trading price, puts the target's enterprise value at nearly $9 billion including all diluted shares.",
153
+ },
154
+ {
155
+ "category": "Convertible bonds",
156
+ "query": "The $1.15 billion convertible note offering carries a coupon of 1.75% and a conversion premium of 35% above the reference stock price of $62.40, giving a conversion price of $84.24 per share.",
157
+ "match": "The company raised over a billion dollars via converts paying under 2% annually, with investors able to convert to equity at roughly $84 per share, a 35% premium to the stock at the time of pricing.",
158
+ },
159
+ {
160
+ "category": "Preferred stock",
161
+ "query": "The company issued 20 million shares of Series B Mandatory Convertible Preferred Stock at a liquidation preference of $50 per share, raising $1.0 billion and paying an annual dividend of 6.50%.",
162
+ "match": "A billion-dollar preferred equity raise was completed through 20 million Series B mandatory convertible shares at $50 each, carrying an annual dividend yield of 6.5% until mandatory conversion.",
163
+ },
164
+ {
165
+ "category": "Rights offering",
166
+ "query": "The rights offering allows existing shareholders to subscribe for 1 new share for every 4 held at a price of $18.50, a 22% discount to the market price, targeting aggregate gross proceeds of $740 million.",
167
+ "match": "Current shareholders were given the right to buy one new share for every four they own at $18.50, roughly 20% below market, with the company seeking to raise around $740 million in fresh equity.",
168
+ },
169
+ {
170
+ "category": "Warrant exercise",
171
+ "query": "The exercise of 14.2 million warrants at a strike price of $11.50 generated $163 million in proceeds and increased total shares outstanding by approximately 4.8% to 310.4 million.",
172
+ "match": "Warrant holders exercised over 14 million rights at $11.50 each, delivering roughly $163 million in cash to the company and lifting the share count by nearly 5% to around 310 million.",
173
+ },
174
+ {
175
+ "category": "Same-store sales",
176
+ "query": "Comparable store sales increased 4.7% globally, with North America up 5.3% and international markets up 3.6%, driven by a 3.1% rise in average transaction value and a 1.6% gain in traffic.",
177
+ "match": "Like-for-like sales grew close to 5% worldwide, led by mid-single-digit gains in the home market and slightly lower growth overseas, with both higher ticket sizes and modestly more customer visits contributing.",
178
+ },
179
+ {
180
+ "category": "Subscriber growth",
181
+ "query": "The streaming platform added 9.8 million net new subscribers in Q2, bringing total paid subscribers to 247 million globally, and average revenue per user increased to $14.20 from $13.50 a year ago.",
182
+ "match": "Nearly 10 million new paying members joined the video service in the second quarter, lifting the global count to almost 250 million, while the monthly revenue per subscriber ticked up by about 70 cents year-over-year.",
183
+ },
184
+ {
185
+ "category": "Load factor",
186
+ "query": "System-wide passenger load factor improved 2.1 percentage points to 87.4% in Q3 as available seat miles grew 8.2% to 68.4 billion while revenue passenger miles rose 10.7% to 59.8 billion.",
187
+ "match": "The airline filled nearly 87.5% of its available seats during the quarter, up about 2 points, as passenger miles flown outpaced capacity growth of roughly 8% with volume rising more than 10%.",
188
+ },
189
+ {
190
+ "category": "Occupancy rate",
191
+ "query": "Hotel occupancy increased to 74.8% in the period from 68.3% a year ago, with RevPAR rising 14.2% to $142.50 driven by a $12 gain in ADR to $190.40 and the occupancy recovery.",
192
+ "match": "Room utilization climbed more than six points to nearly 75%, fueling a 14% jump in revenue per available room to roughly $143 as nightly room rates also moved up by about $12.",
193
+ },
194
+ {
195
+ "category": "ARPU",
196
+ "query": "Mobile average revenue per user rose to $52.30 from $49.80 year-over-year, while postpaid phone net additions reached 1.02 million and total wireless service revenue grew 6.4% to $4.8 billion.",
197
+ "match": "Each mobile customer generated an average of just over $52 monthly, up about $2.50 from a year ago, as the carrier added more than a million postpaid handset subscribers and wireless service revenue approached $5 billion.",
198
+ },
199
+ {
200
+ "category": "DAU/MAU ratio",
201
+ "query": "Daily active users reached 2.11 billion while monthly active users hit 3.27 billion, yielding a DAU/MAU ratio of 64.5%, up from 62.0% a year ago, reflecting stronger daily engagement.",
202
+ "match": "The platform's roughly 2.1 billion daily users represent about 64.5% of its 3.3 billion monthly active users, a ratio that improved by two and a half points versus the year-ago period.",
203
+ },
204
+ {
205
+ "category": "Provision/credit loss",
206
+ "query": "The bank recorded a $1.2 billion provision for credit losses in Q3, up from $680 million a year ago, as net charge-offs climbed to 0.84% of average loans from 0.47%.",
207
+ "match": "Loan loss reserves were bolstered by a provision of about $1.2 billion, nearly double the year-earlier figure, as actual charge-offs as a share of the loan book roughly doubled to below 1%.",
208
+ },
209
+ {
210
+ "category": "NIM",
211
+ "query": "Net interest margin compressed 18 basis points sequentially to 3.12% as deposit repricing lagged the 50-basis-point Fed rate cut, while average earning assets grew 4.1% to $820 billion.",
212
+ "match": "The bank's spread between lending and funding costs narrowed by almost 20 basis points to just over 3%, squeezed by slow deposit repricing after the half-point rate reduction, even as the interest-earning balance sheet expanded about 4%.",
213
+ },
214
+ {
215
+ "category": "CET1 ratio",
216
+ "query": "The Common Equity Tier 1 ratio stood at 13.8% at quarter end, 480 basis points above the regulatory minimum of 9.0%, providing $36 billion of excess capital over the minimum threshold.",
217
+ "match": "The bank's core capital buffer came in at nearly 14%, roughly 5 percentage points clear of the 9% regulatory floor, giving it around $36 billion of capital headroom.",
218
+ },
219
+ {
220
+ "category": "Combined ratio",
221
+ "query": "The property & casualty insurer reported a combined ratio of 97.4% for the year, composed of a 64.8% loss ratio and a 32.6% expense ratio, generating an underwriting gain of $148 million.",
222
+ "match": "The P&C segment ran a combined ratio below 100%, with losses consuming about 65 cents and expenses another 33 cents for each dollar of premium, leaving a modest underwriting profit of around $150 million.",
223
+ },
224
+ {
225
+ "category": "Premium growth",
226
+ "query": "Gross written premiums grew 18.3% to $9.6 billion in the fiscal year, led by commercial lines up 22.4% and personal lines up 13.7%, as rate increases averaged 11.5% across the portfolio.",
227
+ "match": "The insurer's total premiums written expanded by more than 18% to nearly $10 billion, with commercial segments growing faster than personal lines, supported by double-digit average rate increases across the book.",
228
+ },
229
+ {
230
+ "category": "NOI",
231
+ "query": "Net operating income for the commercial portfolio increased 5.8% to $1.34 billion, with same-property NOI growth of 4.1% and $185 million contributed by acquisitions completed in the prior twelve months.",
232
+ "match": "The REIT's core portfolio threw off about $1.34 billion in net operating income, up nearly 6%, blending 4% organic growth at existing properties with around $185 million from recently acquired assets.",
233
+ },
234
+ {
235
+ "category": "FFO",
236
+ "query": "Funds from operations per diluted share rose 7.3% to $4.72 for the full year, exceeding the midpoint of guidance of $4.55-$4.65, as total FFO reached $1.87 billion on 396 million diluted shares.",
237
+ "match": "The REIT generated nearly $1.9 billion in FFO across roughly 400 million diluted shares, translating to about $4.72 per share — ahead of the company's own guidance range — representing 7% growth.",
238
+ },
239
+ {
240
+ "category": "Cap rate",
241
+ "query": "The company acquired a 12-property industrial portfolio for $1.85 billion at a going-in cap rate of 5.2%, with in-place rents approximately 18% below estimated market, providing a value-add opportunity.",
242
+ "match": "A dozen industrial properties were purchased for $1.85 billion, implying a capitalization rate just above 5% on current rents that sit nearly 20% beneath prevailing market levels, offering room for future income growth.",
243
+ },
244
+ {
245
+ "category": "ARR",
246
+ "query": "Annual recurring revenue reached $2.14 billion at the end of Q4, up 34% year-over-year, with enterprise customers — those paying more than $100,000 annually — now representing 68% of total ARR.",
247
+ "match": "The SaaS company's annualized subscription base surpassed $2 billion, growing more than a third from a year earlier, with large enterprise accounts paying six figures or more accounting for roughly two-thirds of the total.",
248
+ },
249
+ {
250
+ "category": "NRR",
251
+ "query": "Net revenue retention came in at 118% for the trailing four quarters, driven by 22% expansion revenue from existing customers and partially offset by a 4% gross churn rate.",
252
+ "match": "Existing customers collectively spent 18% more than the prior year after accounting for upgrades and losses, yielding a dollar-based net retention above 115%, as upsell activity outpaced a roughly 4% loss rate.",
253
+ },
254
+ {
255
+ "category": "RPO",
256
+ "query": "Remaining performance obligations totaled $6.8 billion at fiscal year-end, up 29% from $5.3 billion a year ago, with $3.4 billion expected to be recognized as revenue in the next twelve months.",
257
+ "match": "The company's contracted but not yet recognized revenue backlog grew by nearly 30% to almost $7 billion, with half of that expected to be earned within the coming year.",
258
+ },
259
+ {
260
+ "category": "Billings",
261
+ "query": "Total billings for Q2 were $1.42 billion, up 31% from $1.08 billion in Q2 of last year, outpacing reported revenue growth of 24% and implying continued strong deferred revenue build.",
262
+ "match": "The company invoiced customers for about $1.4 billion in the second quarter, a 31% year-over-year jump that exceeded the 24% revenue growth rate and pointed to a growing pool of future revenue.",
263
+ },
264
+ {
265
+ "category": "Customer count",
266
+ "query": "The company ended the quarter with 21,400 paying customers, adding 1,850 net new logos in Q3 alone, with customers having more than $1 million in annual spend now numbering 620, up 40% from 443 a year ago.",
267
+ "match": "The customer base grew to over 21,000, with nearly 1,900 added just this quarter; the cohort of million-dollar-plus accounts expanded by 40% to more than 600.",
268
+ },
269
+ {
270
+ "category": "Production volume",
271
+ "query": "Oil and gas production averaged 620 thousand barrels of oil equivalent per day in Q3, up 9% from 570 MBoe/d a year ago, with liquids comprising 68% of the mix at 422 MBoe/d.",
272
+ "match": "The energy company produced about 620 thousand barrels equivalent daily, nearly 10% more than the same period last year, with crude and NGL making up more than two-thirds of output.",
273
+ },
274
+ {
275
+ "category": "Proved reserves",
276
+ "query": "Year-end proved reserves were 2.8 billion barrels of oil equivalent, a 6% increase from 2.64 billion Boe the prior year, with a reserve replacement ratio of 148% and a reserve life index of 12.4 years.",
277
+ "match": "The company's audited reserves grew by roughly 160 million barrels equivalent to 2.8 billion Boe at year end, replacing nearly half again as much as it produced and extending the reserve life to over 12 years.",
278
+ },
279
+ {
280
+ "category": "Realized price",
281
+ "query": "Average realized oil price was $78.40 per barrel for the year, a decline of $9.60 per barrel from the prior year, while realized natural gas prices fell to $2.85 per Mcf from $4.10.",
282
+ "match": "The company received about $78 per barrel on average for its crude, down roughly $10 from the year before, while gas realizations also dropped sharply from over $4 to below $3 per thousand cubic feet.",
283
+ },
284
+ {
285
+ "category": "Finding cost",
286
+ "query": "Three-year average finding and development cost was $9.80 per barrel of oil equivalent, comprising $6.50 in drilling and completion costs and $3.30 in geological and geophysical expenses.",
287
+ "match": "The three-year average cost to find and develop each barrel of oil equivalent came in just below $10, with most of that attributable to drilling and well completion and the remainder to exploration costs.",
288
+ },
289
+ {
290
+ "category": "AISC",
291
+ "query": "All-in sustaining cost at the flagship gold mine was $1,148 per ounce for the half year, below the prior-year level of $1,236 per ounce, supported by a 14% increase in mill throughput to 8.9 million tonnes.",
292
+ "match": "The cost of producing an ounce of gold at the main mine fell by nearly $90 to just under $1,150, helped by processing about 9 million tonnes of ore, 14% more than the previous year.",
293
+ },
294
+ {
295
+ "category": "Bond yield move",
296
+ "query": "The 10-year U.S. Treasury yield climbed 65 basis points during Q4 to close the year at 4.58%, its highest level since 2007, pressuring the company's mark-to-market bond portfolio by $1.4 billion.",
297
+ "match": "Long-term government yields rose by about two-thirds of a percentage point over the quarter to end at roughly 4.6%, a level not seen in nearly two decades, inflicting over a billion dollars in unrealized losses on the bond book.",
298
+ },
299
+ {
300
+ "category": "Spread tightening",
301
+ "query": "Investment-grade credit spreads tightened 28 basis points to 92 basis points over Treasuries in Q1, while high-yield spreads narrowed 85 basis points to 340 basis points, boosting the bond portfolio by $520 million.",
302
+ "match": "Corporate borrowing premiums over government bonds compressed during the first quarter — by roughly 30 basis points for investment-grade and about 85 basis points for junk — lifting the debt portfolio value by over half a billion dollars.",
303
+ },
304
+ {
305
+ "category": "Rate hike impact",
306
+ "query": "The 250-basis-point increase in the benchmark rate over the prior 18 months added $680 million in annual interest income on the floating-rate loan book of $27 billion but raised deposit costs by $410 million.",
307
+ "match": "Rate hikes totaling two and a half percentage points over a year and a half generated nearly $700 million in extra loan income on the variable-rate portfolio while lifting the funding cost bill by about $410 million.",
308
+ },
309
+ {
310
+ "category": "Inflation impact",
311
+ "query": "Input cost inflation of 8.4% added approximately $390 million to cost of goods sold in the year, of which $260 million was related to energy and raw materials and $130 million to freight and logistics.",
312
+ "match": "Costs ran roughly 8% higher on an inflationary basis, adding close to $400 million to the production cost line, weighted toward energy and materials with the rest driven by elevated shipping costs.",
313
+ },
314
+ {
315
+ "category": "Revenue beat",
316
+ "query": "Q1 revenue of $12.7 billion surpassed the consensus estimate of $12.1 billion by $600 million, or 5.0%, while adjusted EPS of $2.38 beat the $2.19 consensus by $0.19 cents.",
317
+ "match": "First-quarter sales of nearly $12.7 billion topped analyst expectations by about $600 million, and per-share earnings of $2.38 also exceeded the Street's forecast by about 20 cents.",
318
+ },
319
+ {
320
+ "category": "Guidance cut",
321
+ "query": "The company lowered its full-year revenue guidance by $1.8 billion to a range of $16.5-$17.0 billion, citing order cancellations of $1.2 billion and volume softness in the European market.",
322
+ "match": "Management pulled down its annual sales outlook by nearly $2 billion to a range centered around $16.75 billion, pointing to over a billion in cancelled orders and weaker European demand.",
323
+ },
324
+ {
325
+ "category": "Segment breakdown",
326
+ "query": "The software segment contributed $5.2 billion of revenue and $1.8 billion of operating income (34.6% margin), while the hardware segment delivered $3.4 billion of revenue and $340 million of operating income (10.0% margin).",
327
+ "match": "Software generated $5.2 billion in sales with a margin above 34%, compared to hardware's $3.4 billion in revenue at a much thinner 10% operating margin, highlighting the profitability gap between the two divisions.",
328
+ },
329
+ {
330
+ "category": "One-time charges",
331
+ "query": "The quarter included $215 million in non-recurring charges: a $125 million litigation settlement, a $55 million accelerated amortization of deferred financing costs, and a $35 million write-off of in-process R&D.",
332
+ "match": "Results were burdened by roughly $215 million in one-off items — mostly a legal settlement exceeding $125 million, plus smaller charges for financing cost write-offs and abandoned research assets.",
333
+ },
334
+ {
335
+ "category": "Restatement",
336
+ "query": "The company restated three years of financial results to correct $285 million in revenue that had been recognized prematurely, reducing cumulative net income by $198 million after a 30% tax effect.",
337
+ "match": "A multi-year correction reversed nearly $285 million of prematurely booked revenue, lowering previously reported after-tax earnings by about $200 million across the restated periods.",
338
+ },
339
+ {
340
+ "category": "Pension funding",
341
+ "query": "The defined benefit pension plan had a funding status of 91.3%, with plan assets of $8.4 billion against a projected benefit obligation of $9.2 billion, leaving an underfunded status of $800 million.",
342
+ "match": "The company's pension plan assets of $8.4 billion fell short of the $9.2 billion in projected liabilities by roughly $800 million, equating to a funded ratio just above 91%.",
343
+ },
344
+ {
345
+ "category": "Litigation settlement",
346
+ "query": "The company agreed to pay $1.75 billion to settle antitrust litigation spanning 14 years, with $1.1 billion allocated to direct plaintiff payments and $650 million to attorneys' fees and administrative costs.",
347
+ "match": "A nearly $1.75 billion antitrust settlement was reached covering more than a decade of claims, with the bulk going directly to plaintiffs and the remainder covering legal fees and related expenses.",
348
+ },
349
+ {
350
+ "category": "Regulatory fine",
351
+ "query": "The financial regulator imposed a $390 million penalty for anti-money-laundering compliance failures spanning 2018-2022, including inadequate transaction monitoring on $23 billion in flagged transfers.",
352
+ "match": "The bank was fined close to $400 million by regulators for multi-year failings in money-laundering controls, with examiners pointing to tens of billions of dollars in transactions that escaped proper oversight.",
353
+ },
354
+ {
355
+ "category": "CEO compensation",
356
+ "query": "Total CEO compensation for the fiscal year was $42.3 million, composed of a $1.5 million base salary, a $4.8 million annual bonus, $24.0 million in performance share units, and $12.0 million in stock options.",
357
+ "match": "The chief executive earned about $42 million in total pay, with the majority in long-term equity awards split between performance shares and options, supplemented by a $1.5 million salary and nearly $5 million cash bonus.",
358
+ },
359
+ {
360
+ "category": "Store openings",
361
+ "query": "The retailer opened 134 new stores and closed 47 during the fiscal year, ending with 2,318 locations globally, and plans to open a net 100 additional stores in the coming year.",
362
+ "match": "After opening 134 stores and shutting 47 others, the chain had about 2,300 locations at year end and targeted a net addition of 100 more the following year.",
363
+ },
364
  ]
365
 
366
 
 
459
  ckpt_src = os.path.join(
460
  os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
461
  "website_based_financial_prediction",
462
+ "checkpoints", "t5_cls", "full_model_0511.pt",
463
  )
464
  if not os.path.exists(ckpt_src):
465
  from huggingface_hub import hf_hub_download
 
482
  return ckpt_src
483
 
484
 
485
+ def resolve_mlm_checkpoint():
486
+ import os
487
+ local = os.path.join(
488
+ os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
489
+ "website_based_financial_prediction",
490
+ "checkpoints", "mlm_full", "checkpoint_epoch3", "full_model.pt",
491
+ )
492
+ if not os.path.exists(local):
493
+ raise FileNotFoundError(f"MLM checkpoint not found: {local}")
494
+ state = torch.load(local, map_location="cpu", weights_only=False)
495
+ if "model_state_dict" in state:
496
+ ckpt_state = {k.removeprefix("_orig_mod."): v
497
+ for k, v in state["model_state_dict"].items()}
498
+ ckpt_path = "/tmp/_test_mlm_weights.pt"
499
+ torch.save(ckpt_state, ckpt_path)
500
+ del state, ckpt_state
501
+ return ckpt_path
502
+ else:
503
+ del state
504
+ return local
505
+
506
+
507
  def resolve_jepa_checkpoint():
508
  import os
509
  local = os.path.join(
 
551
  print(f"Device: {device}\n")
552
 
553
  cls_path = resolve_cls_checkpoint()
554
+ mlm_path = resolve_mlm_checkpoint()
555
  jepa_path = resolve_jepa_checkpoint()
556
 
557
  em_model = load_embed_model(device)
558
  mb_tok, mb_model = load_modernbert(device)
559
  fb_tok, fb_model = load_financial_bert(device, cls_path)
560
+ ml_tok, ml_model = load_financial_bert(device, mlm_path, strict=False)
561
  jp_tok, jp_model = load_financial_bert(device, jepa_path, strict=False)
562
  print()
563
 
564
  em_hits, _, em_det = run_retrieval(encode_embed_model, None, em_model, device)
565
  mb_hits, _, mb_det = run_retrieval(encode_modernbert, mb_tok, mb_model, device)
566
  fb_hits, _, fb_det = run_retrieval(encode_financial_bert, fb_tok, fb_model, device)
567
+ ml_hits, _, ml_det = run_retrieval(encode_financial_bert, ml_tok, ml_model, device)
568
  jp_hits, _, jp_det = run_retrieval(encode_financial_bert, jp_tok, jp_model, device)
569
 
570
  def stats(det):
 
577
  em_avg_rank, em_mrr = stats(em_det)
578
  mb_avg_rank, mb_mrr = stats(mb_det)
579
  fb_avg_rank, fb_mrr = stats(fb_det)
580
+ ml_avg_rank, ml_mrr = stats(ml_det)
581
  jp_avg_rank, jp_mrr = stats(jp_det)
582
 
583
+ W = 148
584
  print("=" * W)
585
  print(f"{'CLS RETRIEVAL BENCHMARK (Financial)':^{W}}")
586
+ print(f"{f'{len(TEST_PAIRS)} queries, {len(TEST_PAIRS)} candidates':^{W}}")
587
  print("=" * W)
588
+ print(f"{'':20s} {'BGE-base':^22s} {'ModernBERT':^22s} {'CLS (enc/dec)':^22s} {'MLM-pretrained':^22s} {'CLS (JEPA)':^22s}")
589
+ print(f"{'':20s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s} {'sim':>6s} {'rank':>5s} {'':>5s}")
590
  print("-" * W)
591
 
592
+ for em_d, mb_d, fb_d, ml_d, jp_d in zip(em_det, mb_det, fb_det, ml_det, jp_det):
593
  cat = mb_d["category"][:18]
594
  em_mark = "HIT" if em_d["hit"] else ""
595
  mb_mark = "HIT" if mb_d["hit"] else ""
596
  fb_mark = "HIT" if fb_d["hit"] else ""
597
+ ml_mark = "HIT" if ml_d["hit"] else ""
598
  jp_mark = "HIT" if jp_d["hit"] else ""
599
 
600
  print(
 
602
  f" {em_d['sim_correct']:6.3f} {em_d['rank']:5d} {em_mark:>5s}"
603
  f" {mb_d['sim_correct']:6.3f} {mb_d['rank']:5d} {mb_mark:>5s}"
604
  f" {fb_d['sim_correct']:6.3f} {fb_d['rank']:5d} {fb_mark:>5s}"
605
+ f" {ml_d['sim_correct']:6.3f} {ml_d['rank']:5d} {ml_mark:>5s}"
606
  f" {jp_d['sim_correct']:6.3f} {jp_d['rank']:5d} {jp_mark:>5s}"
607
  )
608
 
609
  print("-" * W)
610
+ N = len(TEST_PAIRS)
611
+ print(f" {'Recall@1':18s} {em_hits:>5d}/{N} {mb_hits:>5d}/{N} {fb_hits:>5d}/{N} {ml_hits:>5d}/{N} {jp_hits:>5d}/{N}")
612
+ print(f" {'Mean rank':18s} {em_avg_rank:>8.1f} {mb_avg_rank:>8.1f} {fb_avg_rank:>8.1f} {ml_avg_rank:>8.1f} {jp_avg_rank:>8.1f}")
613
+ print(f" {'MRR':18s} {em_mrr:>8.3f} {mb_mrr:>8.3f} {fb_mrr:>8.3f} {ml_mrr:>8.3f} {jp_mrr:>8.3f}")
614
  print("=" * W)
615
 
616
 
tests/test_financial_numeracy.py CHANGED
@@ -203,6 +203,226 @@ TEST_GROUPS = [
203
  "mid": '<table><tr><th></th><th>Q4 2024</th></tr><tr><td>EPS (diluted)</td><td>$1.92</td></tr><tr><td>Book value</td><td>$36.10</td></tr><tr><td>Dividend</td><td>$0.47</td></tr></table>',
204
  "high": '<table><tr><th></th><th>Q4 2024</th></tr><tr><td>EPS (diluted)</td><td>$3.68</td></tr><tr><td>Book value</td><td>$67.40</td></tr><tr><td>Dividend</td><td>$0.91</td></tr></table>',
205
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  ]
207
 
208
 
@@ -305,7 +525,7 @@ def resolve_cls_checkpoint():
305
  ckpt_src = os.path.join(
306
  os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
307
  "website_based_financial_prediction",
308
- "checkpoints", "cls", "checkpoint_epoch5", "full_model.pt",
309
  )
310
 
311
  if not os.path.exists(ckpt_src):
@@ -329,6 +549,29 @@ def resolve_cls_checkpoint():
329
  return ckpt_src, True
330
 
331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  def resolve_jepa_checkpoint():
333
  """Resolve JEPA checkpoint: local or HuggingFace dataset repo."""
334
  import os
@@ -377,29 +620,32 @@ def main():
377
  print(f"Device: {device}\n")
378
 
379
  cls_path, _ = resolve_cls_checkpoint()
 
380
  jepa_path, _ = resolve_jepa_checkpoint()
381
 
382
  em_model = load_embed_model(device)
383
  mb_tok, mb_model = load_modernbert(device)
384
  fb_tok, fb_model = load_financial_bert(device, cls_path)
 
385
  jp_tok, jp_model = load_financial_bert(device, jepa_path, strict=False)
386
  print()
387
 
388
  em_h, em_s, em_t, em_det = run_benchmark(encode_embed_model, None, em_model, device)
389
  mb_h, mb_s, mb_t, mb_det = run_benchmark(encode_modernbert, mb_tok, mb_model, device)
390
  fb_h, fb_s, fb_t, fb_det = run_benchmark(encode_financial_bert, fb_tok, fb_model, device)
 
391
  jp_h, jp_s, jp_t, jp_det = run_benchmark(encode_financial_bert, jp_tok, jp_model, device)
392
 
393
- W = 140
394
  print("=" * W)
395
  print(f"{'FINANCIAL NUMERACY ORDERING TEST':^{W}}")
396
  print(f"{'Hard: d(l,m) < d(l,h) AND d(m,h) < d(l,h) | Soft: avg(d(l,m),d(m,h)) < d(l,h)':^{W}}")
397
  print("=" * W)
398
- print(f"{'':22s} {'--- BGE-base ---':^27s} {'--- ModernBERT ---':^27s} {'- CLS (enc/dec) -':^27s} {'--- CLS (JEPA) ---':^27s}")
399
- print(f"{'':22s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s}")
400
  print("-" * W)
401
 
402
- for em_d, mb_d, fb_d, jp_d in zip(em_det, mb_det, fb_det, jp_det):
403
  cat = mb_d['category'][:20]
404
 
405
  def mark(d):
@@ -414,6 +660,7 @@ def main():
414
  f" {em_d['d_lm']:8.4f} {em_d['d_mh']:8.4f} {em_d['d_lh']:8.4f} {mark(em_d):>4s}"
415
  f" {mb_d['d_lm']:8.4f} {mb_d['d_mh']:8.4f} {mb_d['d_lh']:8.4f} {mark(mb_d):>4s}"
416
  f" {fb_d['d_lm']:8.4f} {fb_d['d_mh']:8.4f} {fb_d['d_lh']:8.4f} {mark(fb_d):>4s}"
 
417
  f" {jp_d['d_lm']:8.4f} {jp_d['d_mh']:8.4f} {jp_d['d_lh']:8.4f} {mark(jp_d):>4s}"
418
  )
419
 
@@ -423,6 +670,7 @@ def main():
423
  f" {em_h:>17d}/{em_t:<4d} "
424
  f" {mb_h:>17d}/{mb_t:<4d} "
425
  f" {fb_h:>17d}/{fb_t:<4d} "
 
426
  f" {jp_h:>17d}/{jp_t:<4d}"
427
  )
428
  print(
@@ -430,6 +678,7 @@ def main():
430
  f" {em_s:>17d}/{em_t:<4d} "
431
  f" {mb_s:>17d}/{mb_t:<4d} "
432
  f" {fb_s:>17d}/{fb_t:<4d} "
 
433
  f" {jp_s:>17d}/{jp_t:<4d}"
434
  )
435
  print("=" * W)
 
203
  "mid": '<table><tr><th></th><th>Q4 2024</th></tr><tr><td>EPS (diluted)</td><td>$1.92</td></tr><tr><td>Book value</td><td>$36.10</td></tr><tr><td>Dividend</td><td>$0.47</td></tr></table>',
204
  "high": '<table><tr><th></th><th>Q4 2024</th></tr><tr><td>EPS (diluted)</td><td>$3.68</td></tr><tr><td>Book value</td><td>$67.40</td></tr><tr><td>Dividend</td><td>$0.91</td></tr></table>',
205
  },
206
+ # --- NEW: Prose: more dollar amounts (~5x spread, all in millions) ---
207
+ {
208
+ "category": "Depreciation",
209
+ "low": "Depreciation expense was $13.7 million for the year ended December 31, 2024.",
210
+ "mid": "Depreciation expense was $41.2 million for the year ended December 31, 2024.",
211
+ "high": "Depreciation expense was $68.9 million for the year ended December 31, 2024.",
212
+ },
213
+ {
214
+ "category": "Amortization",
215
+ "low": "Amortization of intangible assets was $8.4 million for the year ended December 31, 2024.",
216
+ "mid": "Amortization of intangible assets was $22.7 million for the year ended December 31, 2024.",
217
+ "high": "Amortization of intangible assets was $41.6 million for the year ended December 31, 2024.",
218
+ },
219
+ {
220
+ "category": "Deferred revenue",
221
+ "low": "Deferred revenue was $19.3 million as of December 31, 2024.",
222
+ "mid": "Deferred revenue was $53.8 million as of December 31, 2024.",
223
+ "high": "Deferred revenue was $97.4 million as of December 31, 2024.",
224
+ },
225
+ {
226
+ "category": "Accounts receivable",
227
+ "low": "Accounts receivable, net, were $37.6 million as of December 31, 2024.",
228
+ "mid": "Accounts receivable, net, were $89.1 million as of December 31, 2024.",
229
+ "high": "Accounts receivable, net, were $183.7 million as of December 31, 2024.",
230
+ },
231
+ {
232
+ "category": "Accounts payable",
233
+ "low": "Accounts payable were $24.8 million as of December 31, 2024.",
234
+ "mid": "Accounts payable were $71.3 million as of December 31, 2024.",
235
+ "high": "Accounts payable were $126.9 million as of December 31, 2024.",
236
+ },
237
+ {
238
+ "category": "Inventory",
239
+ "low": "Inventories were $46.2 million as of December 31, 2024.",
240
+ "mid": "Inventories were $119.4 million as of December 31, 2024.",
241
+ "high": "Inventories were $231.7 million as of December 31, 2024.",
242
+ },
243
+ {
244
+ "category": "Lease obligations",
245
+ "low": "Total operating lease obligations were $28.9 million as of December 31, 2024.",
246
+ "mid": "Total operating lease obligations were $76.4 million as of December 31, 2024.",
247
+ "high": "Total operating lease obligations were $143.8 million as of December 31, 2024.",
248
+ },
249
+ {
250
+ "category": "Pension liabilities",
251
+ "low": "Net pension liabilities were $31.4 million as of December 31, 2024.",
252
+ "mid": "Net pension liabilities were $84.7 million as of December 31, 2024.",
253
+ "high": "Net pension liabilities were $157.3 million as of December 31, 2024.",
254
+ },
255
+ {
256
+ "category": "Impairment charges",
257
+ "low": "Impairment charges were $7.8 million for the year ended December 31, 2024.",
258
+ "mid": "Impairment charges were $23.6 million for the year ended December 31, 2024.",
259
+ "high": "Impairment charges were $38.9 million for the year ended December 31, 2024.",
260
+ },
261
+ {
262
+ "category": "Tax expense",
263
+ "low": "Income tax expense was $5.1 million for the year ended December 31, 2024.",
264
+ "mid": "Income tax expense was $14.8 million for the year ended December 31, 2024.",
265
+ "high": "Income tax expense was $26.3 million for the year ended December 31, 2024.",
266
+ },
267
+ {
268
+ "category": "Cash from financing",
269
+ "low": "Net cash used in financing activities was $18.6 million for the year ended December 31, 2024.",
270
+ "mid": "Net cash used in financing activities was $47.9 million for the year ended December 31, 2024.",
271
+ "high": "Net cash used in financing activities was $92.4 million for the year ended December 31, 2024.",
272
+ },
273
+ {
274
+ "category": "Cash from investing",
275
+ "low": "Net cash used in investing activities was $22.3 million for the year ended December 31, 2024.",
276
+ "mid": "Net cash used in investing activities was $61.7 million for the year ended December 31, 2024.",
277
+ "high": "Net cash used in investing activities was $108.4 million for the year ended December 31, 2024.",
278
+ },
279
+ {
280
+ "category": "SBC expense",
281
+ "low": "Share-based compensation expense was $9.2 million for the year ended December 31, 2024.",
282
+ "mid": "Share-based compensation expense was $27.4 million for the year ended December 31, 2024.",
283
+ "high": "Share-based compensation expense was $46.8 million for the year ended December 31, 2024.",
284
+ },
285
+ {
286
+ "category": "Restructuring",
287
+ "low": "Restructuring charges were $4.7 million for the year ended December 31, 2024.",
288
+ "mid": "Restructuring charges were $13.9 million for the year ended December 31, 2024.",
289
+ "high": "Restructuring charges were $23.6 million for the year ended December 31, 2024.",
290
+ },
291
+ {
292
+ "category": "Working capital",
293
+ "low": "Net working capital was $41.3 million as of December 31, 2024.",
294
+ "mid": "Net working capital was $107.6 million as of December 31, 2024.",
295
+ "high": "Net working capital was $198.4 million as of December 31, 2024.",
296
+ },
297
+ {
298
+ "category": "Intangible assets",
299
+ "low": "Intangible assets, net, were $63.8 million as of December 31, 2024.",
300
+ "mid": "Intangible assets, net, were $172.4 million as of December 31, 2024.",
301
+ "high": "Intangible assets, net, were $314.7 million as of December 31, 2024.",
302
+ },
303
+ {
304
+ "category": "Total equity",
305
+ "low": "Total stockholders' equity was $88.6 million as of December 31, 2024.",
306
+ "mid": "Total stockholders' equity was $234.1 million as of December 31, 2024.",
307
+ "high": "Total stockholders' equity was $437.9 million as of December 31, 2024.",
308
+ },
309
+ {
310
+ "category": "Retained earnings",
311
+ "low": "Retained earnings were $33.7 million as of December 31, 2024.",
312
+ "mid": "Retained earnings were $96.4 million as of December 31, 2024.",
313
+ "high": "Retained earnings were $167.8 million as of December 31, 2024.",
314
+ },
315
+ {
316
+ "category": "Cost of revenue",
317
+ "low": "Cost of revenue was $79.4 million for the year ended December 31, 2024.",
318
+ "mid": "Cost of revenue was $213.6 million for the year ended December 31, 2024.",
319
+ "high": "Cost of revenue was $388.2 million for the year ended December 31, 2024.",
320
+ },
321
+ {
322
+ "category": "Pretax income",
323
+ "low": "Income before income taxes was $12.6 million for the year ended December 31, 2024.",
324
+ "mid": "Income before income taxes was $36.9 million for the year ended December 31, 2024.",
325
+ "high": "Income before income taxes was $63.4 million for the year ended December 31, 2024.",
326
+ },
327
+ {
328
+ "category": "Loan loss provision",
329
+ "low": "Provision for loan losses was $11.8 million for the year ended December 31, 2024.",
330
+ "mid": "Provision for loan losses was $34.2 million for the year ended December 31, 2024.",
331
+ "high": "Provision for loan losses was $58.7 million for the year ended December 31, 2024.",
332
+ },
333
+ # --- NEW: Prose: percentages and ratios (~5x spread) ---
334
+ {
335
+ "category": "ROE",
336
+ "low": "Return on equity was 4.7% for the year ended December 31, 2024.",
337
+ "mid": "Return on equity was 13.2% for the year ended December 31, 2024.",
338
+ "high": "Return on equity was 23.8% for the year ended December 31, 2024.",
339
+ },
340
+ {
341
+ "category": "ROA",
342
+ "low": "Return on assets was 0.9% for the year ended December 31, 2024.",
343
+ "mid": "Return on assets was 2.6% for the year ended December 31, 2024.",
344
+ "high": "Return on assets was 4.8% for the year ended December 31, 2024.",
345
+ },
346
+ {
347
+ "category": "Gross margin",
348
+ "low": "Gross margin was 22.4% for the year ended December 31, 2024.",
349
+ "mid": "Gross margin was 41.7% for the year ended December 31, 2024.",
350
+ "high": "Gross margin was 63.9% for the year ended December 31, 2024.",
351
+ },
352
+ {
353
+ "category": "Interest coverage",
354
+ "low": "The interest coverage ratio was 1.9x for the year ended December 31, 2024.",
355
+ "mid": "The interest coverage ratio was 4.7x for the year ended December 31, 2024.",
356
+ "high": "The interest coverage ratio was 9.3x for the year ended December 31, 2024.",
357
+ },
358
+ {
359
+ "category": "Asset turnover",
360
+ "low": "The asset turnover ratio was 0.38x for the year ended December 31, 2024.",
361
+ "mid": "The asset turnover ratio was 0.87x for the year ended December 31, 2024.",
362
+ "high": "The asset turnover ratio was 1.74x for the year ended December 31, 2024.",
363
+ },
364
+ {
365
+ "category": "Payout ratio",
366
+ "low": "The dividend payout ratio was 14.3% for the year ended December 31, 2024.",
367
+ "mid": "The dividend payout ratio was 38.7% for the year ended December 31, 2024.",
368
+ "high": "The dividend payout ratio was 71.2% for the year ended December 31, 2024.",
369
+ },
370
+ {
371
+ "category": "Tax rate",
372
+ "low": "The effective tax rate was 8.6% for the year ended December 31, 2024.",
373
+ "mid": "The effective tax rate was 19.4% for the year ended December 31, 2024.",
374
+ "high": "The effective tax rate was 29.7% for the year ended December 31, 2024.",
375
+ },
376
+ {
377
+ "category": "NPL ratio",
378
+ "low": "The non-performing loan ratio was 0.6% as of December 31, 2024.",
379
+ "mid": "The non-performing loan ratio was 1.8% as of December 31, 2024.",
380
+ "high": "The non-performing loan ratio was 3.4% as of December 31, 2024.",
381
+ },
382
+ # --- NEW: Prose: per-share and market metrics (~5x spread) ---
383
+ {
384
+ "category": "FCF per share",
385
+ "low": "Free cash flow per share was $0.63 for the year ended December 31, 2024.",
386
+ "mid": "Free cash flow per share was $1.87 for the year ended December 31, 2024.",
387
+ "high": "Free cash flow per share was $3.24 for the year ended December 31, 2024.",
388
+ },
389
+ {
390
+ "category": "TBV per share",
391
+ "low": "Tangible book value per share was $7.40 as of December 31, 2024.",
392
+ "mid": "Tangible book value per share was $19.80 as of December 31, 2024.",
393
+ "high": "Tangible book value per share was $37.60 as of December 31, 2024.",
394
+ },
395
+ {
396
+ "category": "Revenue per share",
397
+ "low": "Revenue per share was $4.82 for the year ended December 31, 2024.",
398
+ "mid": "Revenue per share was $13.47 for the year ended December 31, 2024.",
399
+ "high": "Revenue per share was $24.16 for the year ended December 31, 2024.",
400
+ },
401
+ {
402
+ "category": "Shares outstanding",
403
+ "low": "Weighted average diluted shares outstanding were 47.3 million for Q4 2024.",
404
+ "mid": "Weighted average diluted shares outstanding were 124.6 million for Q4 2024.",
405
+ "high": "Weighted average diluted shares outstanding were 238.9 million for Q4 2024.",
406
+ },
407
+ # --- NEW: HTML table test groups (~5x spread) ---
408
+ {
409
+ "category": "Tbl: segment rev",
410
+ "low": '<table><tr><th>Segment</th><th>FY 2024</th></tr><tr><td>North America</td><td>$83.7 million</td></tr><tr><td>Europe</td><td>$41.2 million</td></tr><tr><td>Asia-Pacific</td><td>$17.4 million</td></tr><tr><td>Total</td><td>$142.3 million</td></tr></table>',
411
+ "mid": '<table><tr><th>Segment</th><th>FY 2024</th></tr><tr><td>North America</td><td>$213.8 million</td></tr><tr><td>Europe</td><td>$104.9 million</td></tr><tr><td>Asia-Pacific</td><td>$43.1 million</td></tr><tr><td>Total</td><td>$361.8 million</td></tr></table>',
412
+ "high": '<table><tr><th>Segment</th><th>FY 2024</th></tr><tr><td>North America</td><td>$409.4 million</td></tr><tr><td>Europe</td><td>$201.3 million</td></tr><tr><td>Asia-Pacific</td><td>$83.4 million</td></tr><tr><td>Total</td><td>$694.1 million</td></tr></table>',
413
+ },
414
+ {
415
+ "category": "Tbl: quarterly",
416
+ "low": '<table><tr><th></th><th>Q1</th><th>Q2</th><th>Q3</th><th>Q4</th></tr><tr><td>Revenue</td><td>$31.4M</td><td>$33.8M</td><td>$35.2M</td><td>$28.0M</td></tr><tr><td>Gross profit</td><td>$12.7M</td><td>$13.9M</td><td>$14.1M</td><td>$10.8M</td></tr></table>',
417
+ "mid": '<table><tr><th></th><th>Q1</th><th>Q2</th><th>Q3</th><th>Q4</th></tr><tr><td>Revenue</td><td>$79.6M</td><td>$86.3M</td><td>$89.4M</td><td>$70.9M</td></tr><tr><td>Gross profit</td><td>$32.4M</td><td>$35.1M</td><td>$35.8M</td><td>$27.3M</td></tr></table>',
418
+ "high": '<table><tr><th></th><th>Q1</th><th>Q2</th><th>Q3</th><th>Q4</th></tr><tr><td>Revenue</td><td>$153.7M</td><td>$166.4M</td><td>$172.3M</td><td>$201.7M</td></tr><tr><td>Gross profit</td><td>$62.4M</td><td>$67.8M</td><td>$69.1M</td><td>$33.5M</td></tr></table>',
419
+ },
420
+ {
421
+ "category": "Tbl: debt maturity",
422
+ "low": '<table><tr><th>Maturity</th><th>Amount</th></tr><tr><td>2025</td><td>$8.3 million</td></tr><tr><td>2026</td><td>$12.6 million</td></tr><tr><td>2027</td><td>$18.4 million</td></tr><tr><td>Thereafter</td><td>$34.8 million</td></tr></table>',
423
+ "mid": '<table><tr><th>Maturity</th><th>Amount</th></tr><tr><td>2025</td><td>$21.4 million</td></tr><tr><td>2026</td><td>$32.7 million</td></tr><tr><td>2027</td><td>$47.9 million</td></tr><tr><td>Thereafter</td><td>$82.6 million</td></tr></table>',
424
+ "high": '<table><tr><th>Maturity</th><th>Amount</th></tr><tr><td>2025</td><td>$41.2 million</td></tr><tr><td>2026</td><td>$62.8 million</td></tr><tr><td>2027</td><td>$91.4 million</td></tr><tr><td>Thereafter</td><td>$147.1 million</td></tr></table>',
425
+ },
426
  ]
427
 
428
 
 
525
  ckpt_src = os.path.join(
526
  os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
527
  "website_based_financial_prediction",
528
+ "checkpoints", "t5_cls", "full_model_0511.pt",
529
  )
530
 
531
  if not os.path.exists(ckpt_src):
 
549
  return ckpt_src, True
550
 
551
 
552
+ def resolve_mlm_checkpoint():
553
+ """Resolve MLM-pretrained checkpoint: local path."""
554
+ import os
555
+ local = os.path.join(
556
+ os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
557
+ "website_based_financial_prediction",
558
+ "checkpoints", "mlm_full", "checkpoint_epoch3", "full_model.pt",
559
+ )
560
+ if not os.path.exists(local):
561
+ raise FileNotFoundError(f"MLM checkpoint not found: {local}")
562
+ state = torch.load(local, map_location="cpu", weights_only=False)
563
+ if "model_state_dict" in state:
564
+ ckpt_state = {k.removeprefix("_orig_mod."): v
565
+ for k, v in state["model_state_dict"].items()}
566
+ ckpt_path = "/tmp/_test_mlm_weights.pt"
567
+ torch.save(ckpt_state, ckpt_path)
568
+ del state, ckpt_state
569
+ return ckpt_path, True
570
+ else:
571
+ del state
572
+ return local, True
573
+
574
+
575
  def resolve_jepa_checkpoint():
576
  """Resolve JEPA checkpoint: local or HuggingFace dataset repo."""
577
  import os
 
620
  print(f"Device: {device}\n")
621
 
622
  cls_path, _ = resolve_cls_checkpoint()
623
+ mlm_path, _ = resolve_mlm_checkpoint()
624
  jepa_path, _ = resolve_jepa_checkpoint()
625
 
626
  em_model = load_embed_model(device)
627
  mb_tok, mb_model = load_modernbert(device)
628
  fb_tok, fb_model = load_financial_bert(device, cls_path)
629
+ ml_tok, ml_model = load_financial_bert(device, mlm_path, strict=False)
630
  jp_tok, jp_model = load_financial_bert(device, jepa_path, strict=False)
631
  print()
632
 
633
  em_h, em_s, em_t, em_det = run_benchmark(encode_embed_model, None, em_model, device)
634
  mb_h, mb_s, mb_t, mb_det = run_benchmark(encode_modernbert, mb_tok, mb_model, device)
635
  fb_h, fb_s, fb_t, fb_det = run_benchmark(encode_financial_bert, fb_tok, fb_model, device)
636
+ ml_h, ml_s, ml_t, ml_det = run_benchmark(encode_financial_bert, ml_tok, ml_model, device)
637
  jp_h, jp_s, jp_t, jp_det = run_benchmark(encode_financial_bert, jp_tok, jp_model, device)
638
 
639
+ W = 170
640
  print("=" * W)
641
  print(f"{'FINANCIAL NUMERACY ORDERING TEST':^{W}}")
642
  print(f"{'Hard: d(l,m) < d(l,h) AND d(m,h) < d(l,h) | Soft: avg(d(l,m),d(m,h)) < d(l,h)':^{W}}")
643
  print("=" * W)
644
+ print(f"{'':22s} {'--- BGE-base ---':^27s} {'--- ModernBERT ---':^27s} {'- CLS (enc/dec) -':^27s} {'--- MLM-pretrained ---':^27s} {'--- CLS (JEPA) ---':^27s}")
645
+ print(f"{'':22s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s} {'l→m':>8s} {'m→h':>8s} {'l→h':>8s} {'':>2s}")
646
  print("-" * W)
647
 
648
+ for em_d, mb_d, fb_d, ml_d, jp_d in zip(em_det, mb_det, fb_det, ml_det, jp_det):
649
  cat = mb_d['category'][:20]
650
 
651
  def mark(d):
 
660
  f" {em_d['d_lm']:8.4f} {em_d['d_mh']:8.4f} {em_d['d_lh']:8.4f} {mark(em_d):>4s}"
661
  f" {mb_d['d_lm']:8.4f} {mb_d['d_mh']:8.4f} {mb_d['d_lh']:8.4f} {mark(mb_d):>4s}"
662
  f" {fb_d['d_lm']:8.4f} {fb_d['d_mh']:8.4f} {fb_d['d_lh']:8.4f} {mark(fb_d):>4s}"
663
+ f" {ml_d['d_lm']:8.4f} {ml_d['d_mh']:8.4f} {ml_d['d_lh']:8.4f} {mark(ml_d):>4s}"
664
  f" {jp_d['d_lm']:8.4f} {jp_d['d_mh']:8.4f} {jp_d['d_lh']:8.4f} {mark(jp_d):>4s}"
665
  )
666
 
 
670
  f" {em_h:>17d}/{em_t:<4d} "
671
  f" {mb_h:>17d}/{mb_t:<4d} "
672
  f" {fb_h:>17d}/{fb_t:<4d} "
673
+ f" {ml_h:>17d}/{ml_t:<4d} "
674
  f" {jp_h:>17d}/{jp_t:<4d}"
675
  )
676
  print(
 
678
  f" {em_s:>17d}/{em_t:<4d} "
679
  f" {mb_s:>17d}/{mb_t:<4d} "
680
  f" {fb_s:>17d}/{fb_t:<4d} "
681
+ f" {ml_s:>17d}/{ml_t:<4d} "
682
  f" {jp_s:>17d}/{jp_t:<4d}"
683
  )
684
  print("=" * W)