diff --git a/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/README.md b/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/README.md new file mode 100644 index 0000000000..3d0e05b0c3 --- /dev/null +++ b/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/README.md @@ -0,0 +1,91 @@ +# Record: SP8192 + Adaptive Hessian-Sensitivity GPTQ Clipping + +**val_bpb = 1.0822** (3-seed mean, std 0.0009) | **~15.91 MB** | 8xH100 SXM + +## 3-Seed Results + +| Seed | Sliding BPB | Artifact | +|----------|-------------|----------------| +| 1337 | **1.0811** | 15,906,928 | +| 42 | **1.0826** | 15,909,023 | +| 999 | **1.0828** | 15,911,535 | +| **Mean** | **1.0822** | **15,909,162** | +| **Std** | **0.0009** | | + +Merged SOTA (PR #1019): **1.1147 BPB**. Delta: **-0.0325 BPP**. Clears the 0.005-nat threshold. + +## Novel Contribution: Adaptive Hessian-Sensitivity GPTQ Clipping + +Standard GPTQ uses a global `clip_sigmas` parameter (e.g., 12.85) for all weight matrices. This submission replaces that with **per-tensor adaptive clipping** derived from Hessian sensitivity analysis. + +**Key insight:** Weight matrices with higher Hessian sensitivity (measured as `H_diag.mean() * row_variance`) suffer more from quantization error. These layers should use wider clipping windows (higher clip_sigmas) to preserve precision, while less-sensitive layers can tolerate tighter clipping for better compression. + +**Algorithm:** +1. Collect full Hessian matrices from calibration data (same as baseline GPTQ) +2. For each weight matrix, compute sensitivity: `sens = mean(diag(H)) * mean(var(W, dim=1))` +3. Compute log-space raw clip_sigmas: `log_cs = -0.15 * log(sens)` (conservative exponent) +4. Binary search for an additive offset in log-space such that the numel-weighted mean of `log(clamp(exp(log_cs + offset), 6.0, 24.0))` equals `log(12.85) + 0.012` (baseline budget + compression margin) +5. Final per-tensor clip_sigmas: `clamp(exp(log_cs + offset), 6.0, 24.0)` + +**Result:** Clip_sigmas range from ~8.5 (early layers, high sensitivity) to ~19.0 (deep decoder layers, low sensitivity), while the numel-weighted geometric mean preserves the compression budget of the global baseline. + +Example per-tensor clip_sigmas from seed 1337: +- `blocks.0.mlp.proj.weight`: 8.46 (high sensitivity, tight clipping) +- `blocks.2.attn.proj.weight`: 14.05 +- `blocks.8.attn.proj.weight`: 19.02 (low sensitivity, wide clipping) + +## Other Techniques + +1. **SP8192 + GPTQ SDClip** -- int6 matrices, int8 embeddings, zero selective pruning (PR #1394 @clarkkev) +2. **3-Layer Depth Recurrence** (layers 3,4,5, activate at frac=0.35) -- 17 virtual layers from 11 physical (PR #1331 @dexhunter, PR #1437 @dexhunter) +3. **Parallel Residuals** (layers 7+) -- GPT-J style, attention and MLP read from same input (PR #1412 @Robby955, PR #1204 @msisovic) +4. **QK-Gain 5.25** -- learnable per-head query scaling +5. **Tuned Hyperparameters** -- WD=0.095, MLR=0.022, EMA=0.9965, warmdown=0.72 (PR #1445 @X-Abhishek-X) +6. **zlib+base85 code wrapper** -- 61KB source compressed to ~19.8KB + +## Architecture + +11L x 512d x 8H / 4KV, MLP 4x, LeakyReLU(0.5)^2, Partial RoPE (16/64 dims), layerwise LN scale, tied embeddings, logit softcap=30.0. Depth recurrence: encoder [0,1,2,3,4,5,3,4] decoder [5,3,4,5,6,7,8,9,10] (loops layers 3-5, activated at step ~2038). Parallel residuals from layer 7: attention and MLP operate on same pre-residual input. Skip gates (sigmoid-gated U-Net connections). + +## Training + +MuonEq-R optimizer (row-normalized Muon, Newton-Schulz 5 steps), AdamW for embeddings/scalars. ~4612 steps in 588s on 8xH100 SXM. Linear warmdown to LR=0 over final 72% of training. EMA decay 0.9965. + +## Quantization + +Full-Hessian GPTQ with **adaptive per-tensor SDClip**: clip_sigmas derived from Hessian sensitivity (see above). int6 for attention/MLP matrices, int8 for token embeddings. Byte-shuffle + Brotli-11 compression. + +## Compliance + +- **Training under 600s:** ~588s on all seeds +- **Artifact under 16MB:** All seeds under 15,912,000 bytes (15.91 MB) +- **Eval under 600s:** Sliding window eval ~91s per seed +- **No SLOT, no ETLB, no n-gram cache** +- **Three seeds:** 1337, 42, 999 + +## Reproduction + +```bash +pip install brotli sentencepiece +pip install flash_attn_3 --no-deps --find-links https://windreamer.github.io/flash-attention3-wheels/cu128_torch291/ +MATCHED_FINEWEB_REPO_ID=kevclark/parameter-golf python3 data/cached_challenge_fineweb.py --variant sp8192 + +SEED=1337 torchrun --standalone --nproc_per_node=8 train_gpt.py +``` + +## Credits + +- **@clarkkev** -- SP8192 + GPTQ Embeddings + SDClip + MuonEq-R + depth recurrence (PR #1394) +- **@dexhunter** -- 3-layer depth recurrence (PR #1331, #1437) +- **@Robby955** -- Parallel residuals on SP8192 (PR #1412) +- **@msisovic** -- Parallel residuals concept (PR #1204) +- **@X-Abhishek-X** -- Hyperparameter tuning: WD=0.095, MLR=0.022, EMA=0.9965 (PR #1445) + +## Included Files + +- `README.md` (this file) +- `submission.json` +- `train_gpt.py` (zlib+base85 compressed wrapper, 19,846 bytes) +- `train_seed1337.log` +- `train_seed42.log` +- `train_seed999.log` diff --git a/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/submission.json b/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/submission.json new file mode 100644 index 0000000000..cf829fd352 --- /dev/null +++ b/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/submission.json @@ -0,0 +1,35 @@ +{ + "author": "chris-colinsky", + "github_id": "chris-colinsky", + "name": "SP8192 + Adaptive Hessian-Sensitivity GPTQ Clipping + 3-Layer Recurrence + Parallel Residuals + QK-Gain 5.25", + "date": "2026-04-17", + "track": "10min_16mb", + "val_bpb": 1.08218, + "val_bpb_std": 0.00090, + "seeds": [1337, 42, 999], + "seed_results": { + "1337": {"val_bpb": 1.08114, "artifact_bytes": 15906928}, + "42": {"val_bpb": 1.08265, "artifact_bytes": 15909023}, + "999": {"val_bpb": 1.08275, "artifact_bytes": 15911535} + }, + "hardware": "8xH100 80GB SXM", + "pytorch_version": "2.9.1+cu128", + "technique_summary": "SP8192 + Hessian-Sensitivity Adaptive GPTQ Clipping (per-tensor clip_sigmas from H_diag * row_var, exponent -0.15, binary-search offset) + 3-Layer Depth Recurrence (L3-5) + Parallel Residuals (L7+) + QK-Gain 5.25 + EMA 0.9965 + WD 0.095 + Sliding Window Eval + GPTQ SDClip + Brotli", + "compliance": { + "train_under_600s": true, + "artifact_under_16mb": true, + "eval_under_600s": true, + "no_slot": true, + "no_pre_quant_ttt": true, + "no_etlb": true, + "no_ngram_cache": true, + "three_seeds": true + }, + "attribution": { + "sp8192_gptq_sdclip": "@clarkkev (PR #1394)", + "depth_recurrence": "@dexhunter (PR #1331, #1437)", + "parallel_residuals": "@Robby955 (PR #1412), @msisovic (PR #1204)", + "hyperparameter_tuning": "@X-Abhishek-X (PR #1445)", + "adaptive_hessian_clip": "Novel contribution (this submission)" + } +} diff --git a/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/train_gpt.py b/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/train_gpt.py new file mode 100644 index 0000000000..4bfa51a5aa --- /dev/null +++ b/records/track_10min_16mb/2026-04-17_SP8192_AdaptiveHessianClip/train_gpt.py @@ -0,0 +1 @@ +import zlib,base64;exec(zlib.decompress(base64.b85decode(b'c-qZ<+j8SZvf#VE0>fFK2GkIA>5JQ3(=qIp+}&Z_Mv}*#!%-k05)@&P02=^xv5q!ke_}syzhpDB?u7zLwLKfh5pID%RaRD3R#s+KR#rBf7iH}Yi|I5S)>)BP8<}`De-O{t)8a}zXN7p0CG|u+7uCkNEN0#u-c7SBkH0?Eij+w{DrWLmDxRtb*=C*1MI@RG{Q=dxOw*J(aX=UF;T@l!RI!0VzMPK+PXD68r+yIR!g2n*v+vp}9l<3&z1NTyiiN7f_xb)J+7P-!aqwyz-WCv|cvK10?0{Zp;7sBn?yRZ)gso^Nc#Kc64OKlWdFJ@3b4TBRFx`Ow|);6JK2o+i~KPU_zCkh_d-L@sDTy4*+2&di(ZU4Z>m`S9LmXYaOfqd>Wr$9GtTDdDR-b5?>|ta1z(WP1=h7#aaLJas0l2@!?Z^aq`mv@5bwQ-lj+YyfYwH>6aL&vlQ6*!QbP|*Joy+O{Nv#4p8(>Gq~|QTkMCf14yVQN1`rt*`KW58>rwyL_?Q0S;fKSM4?h7)A5M<``{MlFujI{bx8M*{$UH@UhQdwOA*|1x*Z@WC)u#>w5Y13RKwbbC+FvqXs;C)R?t6S>G&=K!F?B}d2%(S>2y^TQ{OqK4nOaIKK>a0^7$ATGd?)(zdxi|_G0&iHd&5}5z0vrjW9)q^#axcLbwNUhTe0pjuVOZM6OMybsmRFXCgp+6=J=Ni=Jzb#$_Sa0ue)2w8Af;F!*?(h-rfz2?Eu`-6QVpj{h#cyk+1(qy!(k3an*{&dhMW__*ITvbif5u7ud&g0o)TDQ-T!_)Za=fewZCz9-Plg;Dnq)w}~SmmeBr}4-B#ld-#O=!|*X)I}0ErWFN`5=~*J2#<#(8%hzD#rCNnYVTagvRHK`26I@ix2%%0Pt!@cB(AqDNN`pZLNHEa(V!B`5bw27iG9v7e>2{^i&f@nwavfUTGbHNwt?q%_#sFCew5o=?$9$7mJ{QV~wJ!t#$@n^*be10F|Tm;$|a~L}{L*e(*33_tE79u%z1ukGoS+`We3b1_j&n`56r&?(~T2|-a7@6&jn3=?^F-I4)sMbC+MkPdXlJ+lX(S4&jE_J{%t+LTVEDAz%WW8acss+E({u!)1AU~*IOlV;%L4fdgdZ4$`)C#?Cdv!72+Vw{1IDxq;P&k=`5)C4>WHT8T&a!93RCi8-)429~-UiylMhKW(E3=)&YY&3k2Th=)93y0_gMiOX=0WIQ#soL_=^Y&a7a9l%vG1XW|SRM{gK@B1G>+1QsV-y0Viu~Z$|%v%GeSgMk2E&_sk%R#R|vLseB*lFT#*&Od)V>T|>`Mp*|GL&b!&XIOrk=LdZhi#c;pXm5L7=d6GHQwRF0F@TqVUefvHfVA7j{db=H|BLS1eOIiZM7i2=Cy{w97s2I-6VhHRFl^Kklx1*$0G8}@W7b5XeKPjsROM6-t;b-^AcZ}go7#5UKTj#EmZiu^GxUA$7ykuOufV6`WiiEKXR|@vz&j$dEJdf85D+@4lq&6Cx@Rs0%KdY`o5czpkOw%r@Al%_1Ndmu8VhmWKl3}WSgK2bCEb>uOKCssC8(?A*=xUMS!m00cVYy0lI5bEvID!;aV9;bO{^Y?vyG8E`}A|Nfu<-9ZU~s$_AOGp6vW!mB4q?QwE%5xG4Y5DqjcQ;<)K9JRAyQI_ejo<2n0d765Yx}I0v?d@w2FN>=PwD)ZkGD)^AXWQ0wF&%GbfJ9ntzx(c6X696&R@cz8h>^A~V3qYd|61(5c?Y@{&J6gr$Zzm<5PJWTW81lqtUOy(wKqv_Q||?I?SLjtuE{?&P;D{4-uyd?O&|${vH94|4foI9RZxCG{QEtU5uFX+S%dr{U_78zSf}c;nEIk>-~k-=2}TRn-Q4|YQKcjG#gudiGs_pLYR%ERfv9{b_kA14;drz)Vhor8Y_Y?GY$F&iPH(hJp$js|^-$o*5{imN!v6#uy1}@5YC=PvToag!FV+PXNVU_sUcssjvMTT5J~gg0v{I4qCMnJ2F;_;pRWrZ{4SyccRGQ-)f+8RzeN=}d{6|0yf=i(j;*v}N6hp9u{zrIuT+}~e|JZsz?i?4qu`#}7?Fc*{`O{NJm;LEIsmAkco=(9K^6ttEMi2yi3XtwWevh-Vs<+Fr+XY-ACjOEEhQenAI6=!Gf(<^{nI*=pB=wgtDGf9jv@d$_r9aOQnJzBu>(gT0H7`X4`k5EN(dBU%{$!jK2*p$5Xf40bMQwcgv=d%g2!Z^!z&%f9X|9j%{pU|U$5(Ite$6rI9xdc?knVZp61BQ}7yvUkZHRUC|1#|_HA)T?jmG!}iurcij-WIM*9&j!?`9XTiLsopHBnC7iI(Up+AM+4>))3!RA<3ni`ErSZ2AO=-+EA)!-7$$O0?|2}(CjraRR5e$0i$$F!qvnvvnS!DLag8b7%vX&i6)`V7E%?HL;c-1$!b#nZ8QU>djNkwB;^2JsG~tzwSqw=0q5t92LDw5)!+Jmx9Gb!<@bPIQK04~3HVXjcSvs2~b6$*1>lk|(E4tY88o)AA-K6OL#-Jt=eav^A3@7AOa3M$DL8v8%gO_$%?3}8s$RC;K|Ltb5d*ZqXHUMJb*yK8&Y!vN*lEd3RTr=Dh(zv5BLQr7Y=*(uaOHQ`YT9MfBAw$whWMa~-xE(u251_M7SpNJ1uOldF;wL(%q9bIj0o>f6@}mwRb%rL%ec;QI~aLX-9l6J3Y)@TWq<4qa)JxdF_Y&UH~IxUnOt6jh6v9~fmwKgD9EZTEHZW4Ro$Oa1wS_neN;%i^li%Xr(Yo+%MCThI(A1rXgPMCi?X1TipMk%$X%U{3L9Ud%1LBtA^=*lseWJTRv;DK4`6Jjqr)sulM?&Np0vI`2aP*1SMJj6dQ#)a-ZN`db@wWxXc)GU1kx+TGue%f?zba~2fhYsI`1YLFR45UK&u+9*UvKe1l(TgiavnOJ#L-SM#6{W9xuR|4iEne?DW8hhQKK$F<;=>Tbq_PYFJ6L;(F`!3;t7jmw`XRL{9f2&rjmKsB1v?n+fN&+xwzs+I`CJaM6-8)(5?tu*nX4dC@zowEURFt4-!9W@(1Ota0%jM`t0Qpegc2PP)Sx9|F)-JeFT?~Qs1Qr9!j4s7SXBI@U}JN_+VHY`dGVG>qH~Gc3gl#xFB$i**4|+7e23nz`X%Bnj6%2|TOC?a&LkvmEm{m_6j#j)1N1Kq3)Ip#O1Z2`p0Jf0!Q($T7{95!h|>q6*0!TobJa}m#BmEX>wwJ}Fl2bZbDRF%!jl3`eWf{9B+SNqaVlIeiONyi#Ig5f0Dd{Lu)yitU4|En0N}q-+Hzo~!l{%DzOBhfW?>+(l;AAk&LWS}FKX|jSirRQYc-97<^0=Y^&@!Y2Loi$(CdaCf4Fp1)|gsUhF9xWwnawMPN8L{!RSawA_b#B*g(cE!QF7ld_H}MOIn!lFo7>uRP;nv>IXnlKO9Spz5X`jI);C$H{W|o8&K?WA7cqv)?+-D3vllTQ4|5KWJORD`8$P!BIG2Qj*Zm?%)LDYeHSWYKsRfKgT^`tReOi8G^p&8v3=&>@500c0)gs!kB1h4JOBe<`djcEi1$z=pyj*=9koYMhiCNMs=~XaD5mpjrPkzoP=G`4Q|Rpj|=NTWH*@XH5d9GL;V7WA%<1>rY#_#spL>0FPOkm?ksC|`1epUTW_6SquXwKeSl$1Im%ufGao8;>KjsE^ty}#ApBb+Z1bE9EX42GtNFk8G?0YM0wRv?Tm{vePqH2Tt+0=B3BMRTT@C~F08px}+OAgt-6(Fvl5~6K|o5(e4-mFuT#!|>~CbE=1D=_2=wxMQU8V>YErWnK<5P-=vByEPf_w1F63lwv`dJv?uq{;)pGyV1t?%_8^Sl8=u&iM~Y(>gjleV%3|QW!i#^O(76;b0MA^+M5V7<$Nq?CQqlRxXqqNBz>?{7!JXej5F?rlahk9#n`+@$MB!6_nHIvXR5&tSacvi&PMmrmJ4P21bL!|4a@p&M4Ds#)UNPcTSc&s%S#{-;+UqPVRVDIM-%6!NYzvbQ+rvaLI85mGEO`KF2=*vOX2BpC{Ps1%@noOni970XThQj4Dl?xcf+dc1en$W3@p!Hun=~969lXQ--a*vBOWKinhyFhZxbd(gGo}>zT_&}JV!|?Q*w}l7s{`k!0@=UbTYFJnmtzQLc`U6AJcjVg$6s9=4x>Xq7G5TZ@aEzB|`A#7v;$fQo-#TFj+Gh3~CkMJ==Agu1D*nT4{rQrN{da;h!bevpV*OH$^W&#}CmyT8$opfqct0YX%c~ND!8h~^Up$~vQTS)Hvm;MQIpsw5Q~Wj4JIF{Ec;bb{$E7R9tRbYdAMlSr(A_^j4c$0ougGS^uvLNHVsM=w*VMsFe|h~>Y>XjTpl*MMt}weL{u3?!bsfQ=Aic^!wtvBq-9sBQN?tKSiTUQ?3OpAL1NinZ{o72c#sF4W?!y?O&L8nlQY^{vW=GWRdZXHFs_LxEG^Mq>nUix)DqtoA*!XgYjAwnr=FX!2IfnSJF6RkX^DNRjw#yvb3cM(}X%t#x=wh$JD{i9;(b@jSjK|Vk!EVD56iy9+g-u^!Tro0&;e(jXVr+&GJ#kf*D(21kJe`H|8oKhz&GprZp0!_n_U6e1Ui?Hlm<`4ex_BNG1#}IQh9c4Ps!5W3>)&Da(uTxLJNML90LLa?p+~Jt5Lp!r&mZeW$k7$;8SWoR$?L2v%aY7Mxc4%JP&5k;U6oJYZKwxLKIPl#-t;WNgS5)HeIbiG`(GtYJQ>WRC8(n1%G!jj_4w$QY@jiZnsdl2%W7N8I`KCe9DK_}KBjUjpHKW29X|ILXs^mX_Bo1}hH@+=C1^}IdW_&2|iGZbua?}wiE_B9r8BH=l!?ec0XFfYn_Qe0y?a|?a2;6PRC?M6GzJ&c&Fr;6L2Sw3IXpr=+#oe_b~^@?nfgyCqa>nUN}*p`9?9wS4W-!t>20>=o#%n+RLYu9t1bl{q0v6%-U`A+uENaQyCftQ8f>8zu8OY9`t!NZC4{Jjggxr@)n+S7NUbar)hN-{~n9WKw=xIYbyZ{P=g*wooY`9v2_5z(UdU#S9N5;Yk2SgQoZqRm7^%SnP40GcI#S!;Pr83}4r(4g~DWruWX_nj%s+1wx?gC7;^(NL)zg7rf#_+1En{2sau#)Wi8jR!$qvjdtW`WRe(2*4pjE3)q`pekU;vS2Htk>@-plDjU_dwb4CybTY7tG#9NVdg3(EUzGMbEXk{k$_oddd)hQ~_+9lrP8sVs`W%@GKl#xbCRIkBp*yc>*Cm#<2&I0~sx2aDk|BSw%7|~Q~DhRTy3(ztJn5jd; knaHzt|6nYbo?!?hi(l=*K&-SKBBa`G4UkA4BDBT*H(opC^4;ElN0<}uXV@=ADF||d9!Y5CI3`@F%0#h!{AAAQ*WNZM22a(dTVlj-P@9@EqFB==^9by@oZn1;2HCj>}K5K=^H)gcxci1++dP(VGIape{*!!Rf8=-ad7}riwPtx+anK^m#_~hB?IRD0DYKz%Co2Ep5w43I|9cY`kSrX^zU0vkWaI%>G{>J~P1y#$lvUGaKIJ(utRM_7(xG@R6tI$Iymj5bx{rWXn*ITcnZ@+y5wfCZ(SG#W*7yb$*K1NprYxk`$UT*iiU&)^JF}xQKc=2?xc{ML83OWDC_-`lheh|;QDg}uwsm1}D`Zc=PaCiXO`CL`Bk43$|$>OvXfolZJ@ID|kq`!aj`Uda>-u?<--(yXEpaG1D6jPIbRiQJBA{P!K9NtLY5YWEm$g*m}WGrPMg~;J9Ul>{E+afFS6weS9w?=(o0h6`J@H_5uV?&P($AiFF#Fikf2`_b&-kUK5#vIg&$YaW@f0{`Yf5_y$ngOjPK#<$rakM-BVGq&+d`Pdg_T~Bc$J^MX18UqrX312Yk@=5%o8&^HvYn7cgby%O%Wi>MU-~pJq}_<{U2#CjLaNV6c+^b)(=?tx@w69T4-5cDCM=RioaVb?HI-)3t<&*Dq^RY-dWm$Ob|>T2Oajib7|}RNM`n}Ny0|*KB8->fKE#bpmu`?W*`sT(flBXR_fr-?fG#JtQpWO@3D{RDHxJijMW=y9QMwlQ3kr4fWJeIFr1OgRBKicX(m=6z$ZB2R;k{5y|uVytIyv$F0p|25#CopP_!!Q5?Eqb?z@*I-9ArLI5~yDff2-pHU)`_iO-Jk4%W-(jD#{Ip}rNaP08RwbG($Ro*$2T?K_#ceI%ToG$XYfq4x*9gW3=%JTP=aWQ=@>aOS&Me=(A#qpug>`vNb4X~YOs8;$mq)M^&*m}i1c64g^KG!aD|o0-w18&Sb(`rfYAn;WuDOn7u3>GkHd*3W=)kqqfwsjnrhwVp#4C@Swe=}Hpt;s%Q|_fFrNAXoOw-?+;*VdpnP8Ri4h0=+pp5QHuyAL(TZD{O#Du-#P93vcsAfhauekbfmQ$qAs1yf7qTyB4@nGBv%-O{#e7Xu45;YALfm~E}e<(c-mRUPgHinLPvTGl{ILPfW+NDyW;)x0qS*bX1fgC+|0q@G*5Wt7t_fAF>OCzIIZiB>Uc{kM!mvd=WF^Hbgv7!8U@A!fxeEHDWcG`1srdpg(~iZP!m6GRsyAMxhA|*?cUWMSLOo;>iObN;Z-&7vC~`M43ym=cJ1JGVUEI1iX;((nXG@if`*HDCRQntzL^@2ndG#@p%4fk4qJw>&5D@jde2@^j1ZpF@|>pp}7Ol^tf-!Wx#{3xPM^7(iRal)m~HcHginTmuG5@%N0ZBabVmeKSHB67H%95PlHDnJ!s9n)FWr>_y5pdZIu$AkI%6`pRC8&T+@vvn(6$@(Os`|A6_0btJ{jKrfrrSN8`toO`8VriIPn96k2Kb}m!{Jz_cs5%vBAod4Ggw+FB_nUhq(7p(x3rTd>LSI%U$SBsdX;{7enKDb%L!1xL~6l6?9q5X0d-CT|hexX9Oqx#ztEVsy-9HZvHzWJ(Ugf_RX7DZ>?K{$l2}KsrFua9S)(>7$&R*==!v!9P-^?hr5zERM;&XE1B0%?BEl(ntW?CF0MVr+|SJDXo;2}@^WJKcv&q(W88dY$M&%TD(J(QID{fh6bv+IongB?-zlT&x-P{I7&YXonVDh<7tXdFZKoduYy~AjJpKqCA9o{4+#nUV!y}(4~a0vrB_atPp;~9u26#rQ8xBGO?GkIz#yrw678hP6}9TZysWJ3Cdl{16HQE6kN-%K*yk2w^0Z_hTa0?NvWGU=q+J~%EegLBigOwdr)*=fqp;urmV89@t(Dpx4T1|DViJ=o6Z$&jVkRJ-~HW^+KR;*x$55u>fROQ4Iz!RGbm3x*Skt$?Fdk6KIq!Z9zTng$@o%!8Wk%k5%fzeVvbqcIBeN&H`_CZT?~UPjXwrdP?VSD4$9KmaX@Jc%9;+V-&BXhcPkhr9#RMpM-=h<&D?7qaddcr-x>wJa1fmNa6tJGmUtVA&zjhVF@(vpr3OFL8Nq<~cSa_l>~F~Y)PQ0PHJ;MFKqTP}ZSnG)S1`bTjDpt;4ge~$zG7PP(hN7&Y0;%j_fSGhi$+n)7D>97S^+EWcMptAWQ(rVie!jA)(Vd7-^`(hFUH!yD8pn8=pDuyfxBuWxl;HWGAtoRyUSsHg{#c7c5_i%4VtwyK*iN>V834SH3C#QN087AnP%@bJ>j?Xe(rO6VGTUcG74Nd#MQc!cmYAXq(>-$dD(pl4(0xQWyWnXecq=`kapbS4%32d$%sr+vzsjS3DB-*tJ+|c7Fu-XZp+!f|A8(an?unwlMt|y>PTu(e-!0Rj*idXD>h1mL}pU&e6e9xGVFqYde2A8H7UO&0H=@S&Xly*xCgmr{4Gs($(9IOvz87WzmMZh1nZcx;oc$X?7ZmkWcIjZG?Vl{Z7F{R7TOs;EQnw(e^Mh_7O+s33y_Ii*dj6@$};FUNTDNbmmvLMf^{!BU?C~F$-5#KLp*5vIFpV%>$04oRRtp;nQa^XJH0jg9SvX9k{z54EqWu-8g~nP+&Yxa%&QEuOs%SId|Em#CQW#R4uOj^2NWRe~n)Lj~Ai$;zg+5vM?k1hM(9^c%ox18c#?R2k=NvC7)Ud6tVawQ99!Lwv|o}jw`=LQGp9gvLLTL!dGN8#3%Z#z}xlgT7*OpAQS4EEgSuiD8jYcQ7So-bX&hwe+=97#?ZYQ0m0`}l%3Vc0d3i4MzL6~zp4=?cL~q!gjI>0^?KO)O79>C(s`XzOTmEog0&Jyl%Gc7x>eizQ2p-=BZ_k=^Hwr=&Xgvmr{#XfA4t7ypz&tz%A;8o9tg^jS`O7M#{7aL{HR^vwoo>I&eJVHtw793R-IjBn7gZu(yHdF;EsxiEh_zJ8KS9i<#4i~11`|g07`bdtb}3{92Nn$D;s!8=uu?~(55GC^FdHbS213+WDtW3^-<8f#FNlvKC<|KK9gCYl=5H15c5HysOL!E#4NTI>oCo36D!?N(6ORxdebKL1+5=Ea^1H9N$I;0--mj%Qt)6uS=PJELc}%QBN}sS~i=bKE&SJZLqg?E1)<`L96TSa(}4vhVq-dxXTSvJgOgmDWBxwXG-<*6=YmZC-OBAnXD%MIC%&(r%nrSeVzGQ3aPeiA%s@Gq2VQWoSs!$vh#@ks^ELRzbGSJJWRQxXw5v3l;RxydaO5Cgm9_2q`((E{gB^T)Z?vpoj@}31Wi)B*c7+XhtM(Ibwo*AlH1gXhL%RRAE@kXbG&AL!`O9{I22WcpHac1lRxe{Oocudq#21YpGOVY6XULqUF!oB@z|E#qw2mY&7>cgp7RB&syAKl*76FFEX1n|DD2+dThqxU?_$@(h5XKNF-kft6(nd?bSN}1jk2yVlk#hiTVj=mi-4!?jFJe7qKJ33#xx~$HcRow>M;nlMUK&b0k^@R8s9O7V(!ovXMVJ2UwT+kOfaGy_W#BJvZ?7IM(~dLgiJG2gUW)nr{{IVGF)I(Yf8ArBNNR*b&I;%eqbrI(sSSwm`2TtqR)p^F4%N3ojmK#;quPT(cL^i~ep=&pn**1)e_I(V{ymyde)(FC{q(Iz`CsNdD%YL>yM!_1>|xJv+QfLfvbftL};)CBCaIMU4b>_H|enWarnU2n1ATGK@f7@sBR@){;A2@G_;qYJ80`bDYR(mvi(GI!;e66Ou)Ul}rt)tRmgI%PH@YVV_N?hIkxSWYZ;AM}Jm(2N^znWCYGg;BX%`z2U!FcY<01DmbUV`wBdp?>c*uIFuN&4xhl{G)#uzwcjs_!OUi{?7w;`2#E%w`eIQH7rI6yugUfit8#E(?bam{-Ajca7p2BP5F&>Qyz@uwp`0SbMH)F`>uPkTbL$**J;Ld<`TX#6*A(fz-Sl>|stF=Kg+=NpXw{#)N&@)0(sPrePjn7D^j_1DM{ngx6L96sudzu4jd?Tep&5*SyR_dl_m#m@kso$TDS`_H-gsL-zh->CyTBCBcAUbcJz$cp)P{CXGH&PLIoA4HPZW_OhoV-5fo-iBuh|cvd>B?nYa(6PR()e@`krM{ae&P-PLCuXHz0xY&*T$TcIUtZYymu1CEG)K0k#Dfq#S(_-kCCk#@f~HhSHF$+qB@ESkRPgnR&fwiuw7TC_MmV$%Iy9SZ3HridF6KYc@c-Tb#KT+JD~5=0(->&67G@7|rF1t@e7VX8by8QI)hZvDcyBxB`av8jpYCc(Y@pQrPLnjx{cxwt;Kh{7J2`OTI)>H$&)!tdGB-FE$+;xlx=lc66fb8a&9Aok=40TNXzn!Nentx%7@1N(#$gWqb$m~4Y|sdb{{FY!`BQv;KlaR^|ixs4@3c7i5XqtUmX03jeb*2bf#Ao)`5b=waG?olBxYO`rol-*fF(0ZAP_T@gzs9nHmlhW4c{+Wy$(#xdE_FmjT9lI{y-Ve;rl-GFSr{OU1wX_vrCotHb{R{e4Z{UC%wWOo3nRY352h?g@@!(tUwos8q9~60i_#;(-#bfbSPL$ap*Bs-kQ#>9jNRi>$jv7Pi`3e1iPdJ5OtGF=uw8#f4wHk)|N<{di_djU?1I3u`TtigsI_X-Wn7{rywlY*SDNJr2Er9*b}pVoXdj!Zn}g)-^5#;eC7u@@`1yUd<_r=M(g=RSGNksA9wD{`7-b>t!l+I?QFY;mpp}D7A$KG{rVxoLPCB%2qZxj@I@!mhG~#7?ASlu1$gfCS3{)Lzjs49_^-;tdI$81kvJgnGEUf0+!lelWzQIKFMQxGBTvNh|r7#7uTEseA*Pe2h$dlW6|UXq<0(1TQup)D%cItF}?4!u1qnr+SJF6EJqov=%k#1HJ4Mb>6UaSy1Uv?Ks_q_L(gLgdMzkU0Ejow=Zj@qgQp)Y|bc-qXOZjaIE{8PDuwTvD^*vyHsjOAT-Hgf>V&07zq}-E-U6mTX*~)*=(lycZ?R^{h-OVIsMl2rjO+WG%{;dp*ZisBy-LC+K+i(-U<3TeldRn+v8ZT#XrqW8>CrX3BHZW2$QwkR(P^u2gz$S@djlmNcw2&eL)>GIefBaj;=ZIT}ejbTzDjuaI0(~A?cBq!)q*fk_mj7JmSJ#R&)zQ*2de;0p<-xF+KLAeY93Om^Ls7vB+$?ixs(6O|C9u_~q>E;qc$UZ!>xfo_&Dq8gXALwgkaP$`uSHI2?;Frqm?y--2EHfbKOM!x;mFaqq7MQ2)M-z&EHgwgM@Onm5^M+N&-HZ$wx?7#K*Oj+avl~{skNWr#o0boxc}dXUc#ZEk|IG_C%@$l5L<+R5-wb#;4Z)}zBxjuJ7QV)&YuQLn=+-y2NkUT>X(d)z_zBxlp4oIZ3tWozSYq)cp(^U-^>N0j>&tk_K*G_3(H!gp3Ae7!2u95Sn1h&9F=lk++((uVh$4_!Q(td$LUZ$2A$eWSsy?MTSO#4FomaeWZV*SLj~;Hz+xV%fa+vFbBrQhQrEsBB9i&MEbe2+8ugV-YfF60)5H9(U?`g@k|RO%YbEoI63BPHp$y8^z^*FP!6m{caNLWa)(wegw|T1w0!xQtf!y?5-WhM(^V^8I%_(O}jO6y3aAf3euZv|iR?5b<^+GYWkcTX8lO11ROGn26&5)z*$i0P*v2$`WCzx5a&4sGgT@u4c+HFEgk(fSotUD7l%N*Dpll~-gmK>_psZE^IhV&23x~(cKOPjrx``p4X=BBxDV6vZd^Q2ZPSQ@!u?}awOJN876`o9KkNMY<;QA{0xjN>fr3%Mk&2En%5%}Q+2s9Zv7RqM=Q#q?(Btbq9oy~J};U^E~@NF@bH&q~CygijG>yE}WY#os6ID0{E5-?+oK9NM9Y0xiHg8yfHZ)%%4K`M`{Yd37yzZs-s$NZBqh+VlY}j)SAV$oa#U7QBZp)ef1pECm}%9$03IjP@}g@pXY^Cb5?rxq6s3$`bQaw!Gwkm~nj9+``lMSb;a#runl@BC45G0)S!`RVfV3g#PeM74xX=6N5HO@&$!@I=}Mamqo~O6~&C;S|Gl;+iM?oW-1HoZ8ZTC7G)TQ(b3Iyr%8?8dxTV_bp`Y-DFmpPV)E2hb1hy=|KMsbHfw3ki!Uu`=%VxD>GipJ}7wxdN)v&9hK~S_<6sN3pDqyjnq}18ad4UV@H+}g(5p&d6nYC#^n#s2zb+O}sPjo&L-E&GdADtj$qIM>^kmRpB+ZQDK#Oz$nQ&g-=rzAFwQahMhb^_kpB%s~VNICVaaLp$kuWrUJGT=JPxBdYybYoOZN;nTA$pNg)j%4xV7br>hY^R-FR+R$n&K|v70<|T+ARt2hw4NDGL0~1QeEzfs2s-!y+GN*K+eQ9*ySGtIf`^U_NtmmG^~2uhFDJWhtKU*rv%kiDF<{;6)m+ZdQH=AXF$8?la8vbz}L$ah(Li3JkJNuYs|2MQQ?`Zt*q&R8Z4`4oIWD8AO1S_az`lwN2#?3d0p%=g4{PHa8c_