[{"data":1,"prerenderedAt":2735},["ShallowReactive",2],{"project-krum":3},{"id":4,"title":5,"description":6,"extension":7,"favorite":8,"icon":9,"meta":10,"publishedAt":2724,"readingTime":2159,"shortDescription":2725,"slug":2726,"status":2727,"stem":2728,"tags":2729,"type":2733,"__hash__":2734},"projects\u002Fprojects\u002Fkrum.md","Krum - Byzantine-Resilient Distributed Learning","My M2 research internship at CMAP, Ecole Polytechnique. An open-source library implementing and evaluating Byzantine-robust Gradient Aggregation Rules (GARs) for secure distributed machine learning under adversarial attacks.","md",true,"i-ph-shield-check-duotone",{"body":11},{"type":12,"value":13,"toc":2707},"minimark",[14,42,47,54,58,61,68,90,93,98,149,1062,1155,1244,1248,1251,1512,1516,1592,1596,1613,1616,1627,2028,2031,2038,2459,2462,2466,2617,2621,2628,2632,2686,2690,2693,2697,2703],[15,16,17,27,28,31,32,35,36,41],"p",{},[18,19,23],"a",{"href":20,"rel":21},"https:\u002F\u002Fgithub.com\u002Fcalicarpa\u002Fkrum",[22],"nofollow",[24,25,26],"strong",{},"Krum"," is an open-source Python library for Byzantine-resilient distributed machine learning, built on PyTorch and released under the ",[24,29,30],{},"MIT license",". It is developed during my ",[24,33,34],{},"M2 research internship at CMAP, Ecole Polytechnique",", in collaboration with ",[18,37,40],{"href":38,"rel":39},"https:\u002F\u002Felmahdielmhamdi.com\u002F",[22],"El Mahdi El Mhamdi"," and co-authors.",[43,44,46],"h2",{"id":45},"paper-in-preparation","Paper in Preparation",[15,48,49,50,53],{},"The library is the subject of a ",[24,51,52],{},"JMLR MLOSS"," publication in preparation, with co-authors Sébastien Rouault, Mohammad Ammar Said, Peva Blanchard, and El Mahdi El Mhamdi.",[43,55,57],{"id":56},"overview","Overview",[15,59,60],{},"Distributed learning scales training across multiple workers, but a single malicious worker can collapse the model by sending arbitrary gradients. Krum implements aggregation rules that are provably robust to Byzantine failures, guaranteeing convergence even when a fraction of workers are adversarial.",[15,62,63,64,67],{},"As the field matures, the number of experimental parameters grows: model architecture, dataset, number of workers and Byzantine workers, communication topology, attack strategy, aggregation rule, learning rate schedule, and initialization scheme. Each paper makes distinct implementation choices that are rarely isolated in reusable components. Krum organizes its functionality into ",[24,65,66],{},"three layers"," to address this:",[69,70,71,78,84],"ol",{},[72,73,74,77],"li",{},[24,75,76],{},"Primitives",": aggregation rules, attacks, and a zero-copy model wrapper.",[72,79,80,83],{},[24,81,82],{},"Simulations",": faithful reproductions of experimental protocols from seminal papers.",[72,85,86,89],{},[24,87,88],{},"Orchestration",": a programmatic API for reproducible parameter sweeps over thousands of experiments.",[43,91,76],{"id":92},"primitives",[94,95,97],"h3",{"id":96},"aggregators-10","Aggregators (10)",[15,99,100,101,148],{},"Gradient aggregation rules that take one gradient per worker and produce a single aggregated gradient robust to up to ",[102,103,106,128],"span",{"className":104},[105],"katex",[102,107,110],{"className":108},[109],"katex-mathml",[111,112,114],"math",{"xmlns":113},"http:\u002F\u002Fwww.w3.org\u002F1998\u002FMath\u002FMathML",[115,116,117,124],"semantics",{},[118,119,120],"mrow",{},[121,122,123],"mi",{},"f",[125,126,123],"annotation",{"encoding":127},"application\u002Fx-tex",[102,129,133],{"className":130,"ariaHidden":132},[131],"katex-html","true",[102,134,137,142],{"className":135},[136],"base",[102,138],{"className":139,"style":141},[140],"strut","height:0.8889em;vertical-align:-0.1944em;",[102,143,123],{"className":144,"style":147},[145,146],"mord","mathnormal","margin-right:0.1076em;"," Byzantine outliers:",[150,151,152,169],"table",{},[153,154,155],"thead",{},[156,157,158,163,166],"tr",{},[159,160,162],"th",{"align":161},"left","Rule",[159,164,165],{"align":161},"Robustness",[159,167,168],{"align":161},"Notes",[170,171,172,186,268,368,526,656,728,741,810,937],"tbody",{},[156,173,174,180,183],{},[175,176,177],"td",{"align":161},[24,178,179],{},"Average",[175,181,182],{"align":161},"none",[175,184,185],{"align":161},"Arithmetic mean baseline",[156,187,188,193,265],{},[175,189,190],{"align":161},[24,191,192],{},"Median",[175,194,195],{"align":161},[102,196,198,227],{"className":197},[105],[102,199,201],{"className":200},[109],[111,202,203],{"xmlns":113},[115,204,205,224],{},[118,206,207,209,213,216,220],{},[121,208,123],{},[210,211,212],"mo",{},"\u003C",[121,214,215],{},"n",[121,217,219],{"mathvariant":218},"normal","\u002F",[221,222,223],"mn",{},"2",[125,225,226],{"encoding":127},"f \u003C n\u002F2",[102,228,230,251],{"className":229,"ariaHidden":132},[131],[102,231,233,236,239,244,248],{"className":232},[136],[102,234],{"className":235,"style":141},[140],[102,237,123],{"className":238,"style":147},[145,146],[102,240],{"className":241,"style":243},[242],"mspace","margin-right:0.2778em;",[102,245,212],{"className":246},[247],"mrel",[102,249],{"className":250,"style":243},[242],[102,252,254,258,261],{"className":253},[136],[102,255],{"className":256,"style":257},[140],"height:1em;vertical-align:-0.25em;",[102,259,215],{"className":260},[145,146],[102,262,264],{"className":263},[145],"\u002F2",[175,266,267],{"align":161},"Coordinate-wise median",[156,269,270,275,334],{},[175,271,272],{"align":161},[24,273,274],{},"Trimmed Mean",[175,276,277],{"align":161},[102,278,280,301],{"className":279},[105],[102,281,283],{"className":282},[109],[111,284,285],{"xmlns":113},[115,286,287,299],{},[118,288,289,291,293,295,297],{},[121,290,123],{},[210,292,212],{},[121,294,215],{},[121,296,219],{"mathvariant":218},[221,298,223],{},[125,300,226],{"encoding":127},[102,302,304,322],{"className":303,"ariaHidden":132},[131],[102,305,307,310,313,316,319],{"className":306},[136],[102,308],{"className":309,"style":141},[140],[102,311,123],{"className":312,"style":147},[145,146],[102,314],{"className":315,"style":243},[242],[102,317,212],{"className":318},[247],[102,320],{"className":321,"style":243},[242],[102,323,325,328,331],{"className":324},[136],[102,326],{"className":327,"style":257},[140],[102,329,215],{"className":330},[145,146],[102,332,264],{"className":333},[145],[175,335,336,337,367],{"align":161},"Removes the ",[102,338,340,354],{"className":339},[105],[102,341,343],{"className":342},[109],[111,344,345],{"xmlns":113},[115,346,347,352],{},[118,348,349],{},[121,350,351],{},"m",[125,353,351],{"encoding":127},[102,355,357],{"className":356,"ariaHidden":132},[131],[102,358,360,364],{"className":359},[136],[102,361],{"className":362,"style":363},[140],"height:0.4306em;",[102,365,351],{"className":366},[145,146]," smallest\u002Flargest values per coordinate",[156,369,370,374,433],{},[175,371,372],{"align":161},[24,373,26],{},[175,375,376],{"align":161},[102,377,379,400],{"className":378},[105],[102,380,382],{"className":381},[109],[111,383,384],{"xmlns":113},[115,385,386,398],{},[118,387,388,390,392,394,396],{},[121,389,123],{},[210,391,212],{},[121,393,215],{},[121,395,219],{"mathvariant":218},[221,397,223],{},[125,399,226],{"encoding":127},[102,401,403,421],{"className":402,"ariaHidden":132},[131],[102,404,406,409,412,415,418],{"className":405},[136],[102,407],{"className":408,"style":141},[140],[102,410,123],{"className":411,"style":147},[145,146],[102,413],{"className":414,"style":243},[242],[102,416,212],{"className":417},[247],[102,419],{"className":420,"style":243},[242],[102,422,424,427,430],{"className":423},[136],[102,425],{"className":426,"style":257},[140],[102,428,215],{"className":429},[145,146],[102,431,264],{"className":432},[145],[175,434,435,436,525],{"align":161},"Selects the gradient closest to its neighbors in ",[102,437,439,459],{"className":438},[105],[102,440,442],{"className":441},[109],[111,443,444],{"xmlns":113},[115,445,446,456],{},[118,447,448],{},[449,450,451,454],"msub",{},[121,452,453],{},"L",[221,455,223],{},[125,457,458],{"encoding":127},"L_2",[102,460,462],{"className":461,"ariaHidden":132},[131],[102,463,465,469],{"className":464},[136],[102,466],{"className":467,"style":468},[140],"height:0.8333em;vertical-align:-0.15em;",[102,470,472,475],{"className":471},[145],[102,473,453],{"className":474},[145,146],[102,476,479],{"className":477},[478],"msupsub",[102,480,484,516],{"className":481},[482,483],"vlist-t","vlist-t2",[102,485,488,511],{"className":486},[487],"vlist-r",[102,489,493],{"className":490,"style":492},[491],"vlist","height:0.3011em;",[102,494,496,501],{"style":495},"top:-2.55em;margin-left:0em;margin-right:0.05em;",[102,497],{"className":498,"style":500},[499],"pstrut","height:2.7em;",[102,502,508],{"className":503},[504,505,506,507],"sizing","reset-size6","size3","mtight",[102,509,223],{"className":510},[145,507],[102,512,515],{"className":513},[514],"vlist-s","​",[102,517,519],{"className":518},[487],[102,520,523],{"className":521,"style":522},[491],"height:0.15em;",[102,524],{}," (Blanchard et al., 2017)",[156,527,528,533,592],{},[175,529,530],{"align":161},[24,531,532],{},"Multi Krum",[175,534,535],{"align":161},[102,536,538,559],{"className":537},[105],[102,539,541],{"className":540},[109],[111,542,543],{"xmlns":113},[115,544,545,557],{},[118,546,547,549,551,553,555],{},[121,548,123],{},[210,550,212],{},[121,552,215],{},[121,554,219],{"mathvariant":218},[221,556,223],{},[125,558,226],{"encoding":127},[102,560,562,580],{"className":561,"ariaHidden":132},[131],[102,563,565,568,571,574,577],{"className":564},[136],[102,566],{"className":567,"style":141},[140],[102,569,123],{"className":570,"style":147},[145,146],[102,572],{"className":573,"style":243},[242],[102,575,212],{"className":576},[247],[102,578],{"className":579,"style":243},[242],[102,581,583,586,589],{"className":582},[136],[102,584],{"className":585,"style":257},[140],[102,587,215],{"className":588},[145,146],[102,590,264],{"className":591},[145],[175,593,594,595,655],{"align":161},"Selects the ",[102,596,598,619],{"className":597},[105],[102,599,601],{"className":600},[109],[111,602,603],{"xmlns":113},[115,604,605,616],{},[118,606,607,609,612,614],{},[121,608,215],{},[210,610,611],{},"−",[221,613,223],{},[121,615,123],{},[125,617,618],{"encoding":127},"n - 2f",[102,620,622,643],{"className":621,"ariaHidden":132},[131],[102,623,625,629,632,636,640],{"className":624},[136],[102,626],{"className":627,"style":628},[140],"height:0.6667em;vertical-align:-0.0833em;",[102,630,215],{"className":631},[145,146],[102,633],{"className":634,"style":635},[242],"margin-right:0.2222em;",[102,637,611],{"className":638},[639],"mbin",[102,641],{"className":642,"style":635},[242],[102,644,646,649,652],{"className":645},[136],[102,647],{"className":648,"style":141},[140],[102,650,223],{"className":651},[145],[102,653,123],{"className":654,"style":147},[145,146]," gradients with smallest scores",[156,657,658,663,725],{},[175,659,660],{"align":161},[24,661,662],{},"Bulyan",[175,664,665],{"align":161},[102,666,668,691],{"className":667},[105],[102,669,671],{"className":670},[109],[111,672,673],{"xmlns":113},[115,674,675,688],{},[118,676,677,679,681,683,685],{},[121,678,123],{},[210,680,212],{},[121,682,215],{},[121,684,219],{"mathvariant":218},[221,686,687],{},"4",[125,689,690],{"encoding":127},"f \u003C n\u002F4",[102,692,694,712],{"className":693,"ariaHidden":132},[131],[102,695,697,700,703,706,709],{"className":696},[136],[102,698],{"className":699,"style":141},[140],[102,701,123],{"className":702,"style":147},[145,146],[102,704],{"className":705,"style":243},[242],[102,707,212],{"className":708},[247],[102,710],{"className":711,"style":243},[242],[102,713,715,718,721],{"className":714},[136],[102,716],{"className":717,"style":257},[140],[102,719,215],{"className":720},[145,146],[102,722,724],{"className":723},[145],"\u002F4",[175,726,727],{"align":161},"Krum + trimmed mean two-stage procedure (El Mhamdi et al., 2018)",[156,729,730,735,738],{},[175,731,732],{"align":161},[24,733,734],{},"Brute",[175,736,737],{"align":161},"optimal",[175,739,740],{"align":161},"Combinatorial subset search with minimum diameter",[156,742,743,748,807],{},[175,744,745],{"align":161},[24,746,747],{},"GeoMed",[175,749,750],{"align":161},[102,751,753,774],{"className":752},[105],[102,754,756],{"className":755},[109],[111,757,758],{"xmlns":113},[115,759,760,772],{},[118,761,762,764,766,768,770],{},[121,763,123],{},[210,765,212],{},[121,767,215],{},[121,769,219],{"mathvariant":218},[221,771,223],{},[125,773,226],{"encoding":127},[102,775,777,795],{"className":776,"ariaHidden":132},[131],[102,778,780,783,786,789,792],{"className":779},[136],[102,781],{"className":782,"style":141},[140],[102,784,123],{"className":785,"style":147},[145,146],[102,787],{"className":788,"style":243},[242],[102,790,212],{"className":791},[247],[102,793],{"className":794,"style":243},[242],[102,796,798,801,804],{"className":797},[136],[102,799],{"className":800,"style":257},[140],[102,802,215],{"className":803},[145,146],[102,805,264],{"className":806},[145],[175,808,809],{"align":161},"Geometric median via iterative Weiszfeld algorithm",[156,811,812,817,876],{},[175,813,814],{"align":161},[24,815,816],{},"Aksel",[175,818,819],{"align":161},[102,820,822,843],{"className":821},[105],[102,823,825],{"className":824},[109],[111,826,827],{"xmlns":113},[115,828,829,841],{},[118,830,831,833,835,837,839],{},[121,832,123],{},[210,834,212],{},[121,836,215],{},[121,838,219],{"mathvariant":218},[221,840,223],{},[125,842,226],{"encoding":127},[102,844,846,864],{"className":845,"ariaHidden":132},[131],[102,847,849,852,855,858,861],{"className":848},[136],[102,850],{"className":851,"style":141},[140],[102,853,123],{"className":854,"style":147},[145,146],[102,856],{"className":857,"style":243},[242],[102,859,212],{"className":860},[247],[102,862],{"className":863,"style":243},[242],[102,865,867,870,873],{"className":866},[136],[102,868],{"className":869,"style":257},[140],[102,871,215],{"className":872},[145,146],[102,874,264],{"className":875},[145],[175,877,878,879,936],{"align":161},"Linear-time median-pivot aggregator, ",[102,880,882,909],{"className":881},[105],[102,883,885],{"className":884},[109],[111,886,887],{"xmlns":113},[115,888,889,906],{},[118,890,891,894,898,900,903],{},[121,892,893],{},"O",[210,895,897],{"stretchy":896},"false","(",[121,899,215],{},[121,901,902],{},"d",[210,904,905],{"stretchy":896},")",[125,907,908],{"encoding":127},"O(nd)",[102,910,912],{"className":911,"ariaHidden":132},[131],[102,913,915,918,922,926,929,932],{"className":914},[136],[102,916],{"className":917,"style":257},[140],[102,919,893],{"className":920,"style":921},[145,146],"margin-right:0.0278em;",[102,923,897],{"className":924},[925],"mopen",[102,927,215],{"className":928},[145,146],[102,930,902],{"className":931},[145,146],[102,933,905],{"className":934},[935],"mclose"," complexity",[156,938,939,944,1003],{},[175,940,941],{"align":161},[24,942,943],{},"Nearest Neighbor Average",[175,945,946],{"align":161},[102,947,949,970],{"className":948},[105],[102,950,952],{"className":951},[109],[111,953,954],{"xmlns":113},[115,955,956,968],{},[118,957,958,960,962,964,966],{},[121,959,123],{},[210,961,212],{},[121,963,215],{},[121,965,219],{"mathvariant":218},[221,967,223],{},[125,969,226],{"encoding":127},[102,971,973,991],{"className":972,"ariaHidden":132},[131],[102,974,976,979,982,985,988],{"className":975},[136],[102,977],{"className":978,"style":141},[140],[102,980,123],{"className":981,"style":147},[145,146],[102,983],{"className":984,"style":243},[242],[102,986,212],{"className":987},[247],[102,989],{"className":990,"style":243},[242],[102,992,994,997,1000],{"className":993},[136],[102,995],{"className":996,"style":257},[140],[102,998,215],{"className":999},[145,146],[102,1001,264],{"className":1002},[145],[175,1004,1005,1006,1061],{"align":161},"Averages the ",[102,1007,1009,1028],{"className":1008},[105],[102,1010,1012],{"className":1011},[109],[111,1013,1014],{"xmlns":113},[115,1015,1016,1026],{},[118,1017,1018,1020,1022,1024],{},[121,1019,215],{},[210,1021,611],{},[221,1023,223],{},[121,1025,123],{},[125,1027,618],{"encoding":127},[102,1029,1031,1049],{"className":1030,"ariaHidden":132},[131],[102,1032,1034,1037,1040,1043,1046],{"className":1033},[136],[102,1035],{"className":1036,"style":628},[140],[102,1038,215],{"className":1039},[145,146],[102,1041],{"className":1042,"style":635},[242],[102,1044,611],{"className":1045},[639],[102,1047],{"className":1048,"style":635},[242],[102,1050,1052,1055,1058],{"className":1051},[136],[102,1053],{"className":1054,"style":141},[140],[102,1056,223],{"className":1057},[145],[102,1059,123],{"className":1060,"style":147},[145,146]," closest gradients, used in MoNNA (Farhadkhani et al., 2023)",[15,1063,1064,1065,1068,1069,1097,1098,1097,1126,1154],{},"Each rule is a ",[24,1066,1067],{},"stateless classmethod"," with no instance state and no hidden parameters. Specialized hyperparameters (",[102,1070,1072,1085],{"className":1071},[105],[102,1073,1075],{"className":1074},[109],[111,1076,1077],{"xmlns":113},[115,1078,1079,1083],{},[118,1080,1081],{},[121,1082,123],{},[125,1084,123],{"encoding":127},[102,1086,1088],{"className":1087,"ariaHidden":132},[131],[102,1089,1091,1094],{"className":1090},[136],[102,1092],{"className":1093,"style":141},[140],[102,1095,123],{"className":1096,"style":147},[145,146],", ",[102,1099,1101,1114],{"className":1100},[105],[102,1102,1104],{"className":1103},[109],[111,1105,1106],{"xmlns":113},[115,1107,1108,1112],{},[118,1109,1110],{},[121,1111,215],{},[125,1113,215],{"encoding":127},[102,1115,1117],{"className":1116,"ariaHidden":132},[131],[102,1118,1120,1123],{"className":1119},[136],[102,1121],{"className":1122,"style":363},[140],[102,1124,215],{"className":1125},[145,146],[102,1127,1129,1142],{"className":1128},[105],[102,1130,1132],{"className":1131},[109],[111,1133,1134],{"xmlns":113},[115,1135,1136,1140],{},[118,1137,1138],{},[121,1139,351],{},[125,1141,351],{"encoding":127},[102,1143,1145],{"className":1144,"ariaHidden":132},[131],[102,1146,1148,1151],{"className":1147},[136],[102,1149],{"className":1150,"style":363},[140],[102,1152,351],{"className":1153},[145,146],") are keyword-only:",[1156,1157,1162],"pre",{"className":1158,"code":1159,"language":1160,"meta":1161,"style":1161},"language-python shiki shiki-themes material-theme-lighter catppuccin-latte catppuccin-macchiato","from krum.primitives.aggregators import Krum\naggregated = Krum.aggregate(gradients, f=2, n=10)\n","python","",[1163,1164,1165,1194],"code",{"__ignoreMap":1161},[102,1166,1169,1173,1177,1181,1183,1185,1188,1191],{"class":1167,"line":1168},"line",1,[102,1170,1172],{"class":1171},"sthAO","from",[102,1174,1176],{"class":1175},"s0g_q"," krum",[102,1178,1180],{"class":1179},"sMKYs",".",[102,1182,92],{"class":1175},[102,1184,1180],{"class":1179},[102,1186,1187],{"class":1175},"aggregators ",[102,1189,1190],{"class":1171},"import",[102,1192,1193],{"class":1175}," Krum\n",[102,1195,1197,1200,1204,1207,1209,1213,1215,1219,1222,1226,1228,1231,1233,1236,1238,1241],{"class":1167,"line":1196},2,[102,1198,1199],{"class":1175},"aggregated ",[102,1201,1203],{"class":1202},"sn2um","=",[102,1205,1206],{"class":1175}," Krum",[102,1208,1180],{"class":1179},[102,1210,1212],{"class":1211},"sung0","aggregate",[102,1214,897],{"class":1179},[102,1216,1218],{"class":1217},"su9Z2","gradients",[102,1220,1221],{"class":1179},",",[102,1223,1225],{"class":1224},"smoPz"," f",[102,1227,1203],{"class":1202},[102,1229,223],{"class":1230},"sZm5v",[102,1232,1221],{"class":1179},[102,1234,1235],{"class":1224}," n",[102,1237,1203],{"class":1202},[102,1239,1240],{"class":1230},"10",[102,1242,1243],{"class":1179},")\n",[94,1245,1247],{"id":1246},"attacks-5","Attacks (5)",[15,1249,1250],{},"Byzantine attack strategies that generate adversarial gradients from the honest workers' gradients:",[150,1252,1253,1263],{},[153,1254,1255],{},[156,1256,1257,1260],{},[159,1258,1259],{"align":161},"Attack",[159,1261,1262],{"align":161},"Description",[170,1264,1265,1472,1482,1492,1502],{},[156,1266,1267,1272],{},[175,1268,1269],{"align":161},[24,1270,1271],{},"SignFlip",[175,1273,1274,1275],{"align":161},"Sends the negation of the true gradient, ",[102,1276,1278,1333],{"className":1277},[105],[102,1279,1281],{"className":1280},[109],[111,1282,1283],{"xmlns":113},[115,1284,1285,1330],{},[118,1286,1287,1303,1305,1307],{},[449,1288,1289,1292],{},[121,1290,1291],{},"g",[118,1293,1294,1297,1300],{},[121,1295,1296],{},"b",[121,1298,1299],{},"y",[121,1301,1302],{},"z",[210,1304,1203],{},[210,1306,611],{},[449,1308,1309,1311],{},[121,1310,1291],{},[118,1312,1313,1316,1319,1321,1324,1327],{},[121,1314,1315],{},"h",[121,1317,1318],{},"o",[121,1320,215],{},[121,1322,1323],{},"e",[121,1325,1326],{},"s",[121,1328,1329],{},"t",[125,1331,1332],{"encoding":127},"g_{byz} = -g_{honest}",[102,1334,1336,1406],{"className":1335,"ariaHidden":132},[131],[102,1337,1339,1343,1397,1400,1403],{"className":1338},[136],[102,1340],{"className":1341,"style":1342},[140],"height:0.7167em;vertical-align:-0.2861em;",[102,1344,1346,1350],{"className":1345},[145],[102,1347,1291],{"className":1348,"style":1349},[145,146],"margin-right:0.0359em;",[102,1351,1353],{"className":1352},[478],[102,1354,1356,1388],{"className":1355},[482,483],[102,1357,1359,1385],{"className":1358},[487],[102,1360,1363],{"className":1361,"style":1362},[491],"height:0.3361em;",[102,1364,1366,1369],{"style":1365},"top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;",[102,1367],{"className":1368,"style":500},[499],[102,1370,1372],{"className":1371},[504,505,506,507],[102,1373,1375,1378,1381],{"className":1374},[145,507],[102,1376,1296],{"className":1377},[145,146,507],[102,1379,1299],{"className":1380,"style":1349},[145,146,507],[102,1382,1302],{"className":1383,"style":1384},[145,146,507],"margin-right:0.044em;",[102,1386,515],{"className":1387},[514],[102,1389,1391],{"className":1390},[487],[102,1392,1395],{"className":1393,"style":1394},[491],"height:0.2861em;",[102,1396],{},[102,1398],{"className":1399,"style":243},[242],[102,1401,1203],{"className":1402},[247],[102,1404],{"className":1405,"style":243},[242],[102,1407,1409,1413,1416],{"className":1408},[136],[102,1410],{"className":1411,"style":1412},[140],"height:0.7778em;vertical-align:-0.1944em;",[102,1414,611],{"className":1415},[145],[102,1417,1419,1422],{"className":1418},[145],[102,1420,1291],{"className":1421,"style":1349},[145,146],[102,1423,1425],{"className":1424},[478],[102,1426,1428,1464],{"className":1427},[482,483],[102,1429,1431,1461],{"className":1430},[487],[102,1432,1434],{"className":1433,"style":1362},[491],[102,1435,1436,1439],{"style":1365},[102,1437],{"className":1438,"style":500},[499],[102,1440,1442],{"className":1441},[504,505,506,507],[102,1443,1445,1448,1451,1454,1458],{"className":1444},[145,507],[102,1446,1315],{"className":1447},[145,146,507],[102,1449,1318],{"className":1450},[145,146,507],[102,1452,215],{"className":1453},[145,146,507],[102,1455,1457],{"className":1456},[145,146,507],"es",[102,1459,1329],{"className":1460},[145,146,507],[102,1462,515],{"className":1463},[514],[102,1465,1467],{"className":1466},[487],[102,1468,1470],{"className":1469,"style":522},[491],[102,1471],{},[156,1473,1474,1479],{},[175,1475,1476],{"align":161},[24,1477,1478],{},"ALIE",[175,1480,1481],{"align":161},"Alignment attack maximizing inner product with honest gradients under bounded norm",[156,1483,1484,1489],{},[175,1485,1486],{"align":161},[24,1487,1488],{},"Gaussian",[175,1490,1491],{"align":161},"Gradients drawn from a Gaussian centered on the honest mean",[156,1493,1494,1499],{},[175,1495,1496],{"align":161},[24,1497,1498],{},"Full Gradient Negation",[175,1500,1501],{"align":161},"Negation of the full honest gradient (El Mhamdi et al., 2018)",[156,1503,1504,1509],{},[175,1505,1506],{"align":161},[24,1507,1508],{},"Small Perturbation",[175,1510,1511],{"align":161},"Small per-coordinate perturbations exploiting curse-of-dimensionality effects (El Mhamdi et al., 2018)",[94,1513,1515],{"id":1514},"model-wrapper","Model Wrapper",[15,1517,1518,1519,1522,1523,1526,1527,1530,1531,1534,1535,1538,1539,1588,1589,1591],{},"The ",[1163,1520,1521],{},"Model"," class wraps any ",[1163,1524,1525],{},"torch.nn.Module"," and provides ",[24,1528,1529],{},"flat tensor views"," of parameters and gradients without copying: reading ",[1163,1532,1533],{},"model.parameters"," or ",[1163,1536,1537],{},"model.gradients"," returns a 1D tensor of shape ",[102,1540,1542,1562],{"className":1541},[105],[102,1543,1545],{"className":1544},[109],[111,1546,1547],{"xmlns":113},[115,1548,1549,1559],{},[118,1550,1551,1553,1555,1557],{},[210,1552,897],{"stretchy":896},[121,1554,902],{},[210,1556,1221],{"separator":132},[210,1558,905],{"stretchy":896},[125,1560,1561],{"encoding":127},"(d,)",[102,1563,1565],{"className":1564,"ariaHidden":132},[131],[102,1566,1568,1571,1574,1577,1581,1585],{"className":1567},[136],[102,1569],{"className":1570,"style":257},[140],[102,1572,897],{"className":1573},[925],[102,1575,902],{"className":1576},[145,146],[102,1578,1221],{"className":1579},[1580],"mpunct",[102,1582],{"className":1583,"style":1584},[242],"margin-right:0.1667em;",[102,1586,905],{"className":1587},[935]," sharing memory with the underlying module, and writing to ",[1163,1590,1537],{}," unpacks the flat vector back into each parameter gradient in place. Standard architectures from the literature are provided (Krum2017CNN, Monna2023CNNMnist, etc.).",[94,1593,1595],{"id":1594},"extensibility","Extensibility",[15,1597,1598,1599,1602,1603,1605,1606,1608,1609,1612],{},"Both ",[1163,1600,1601],{},"Aggregator"," and ",[1163,1604,1259],{}," are abstract base classes with a single required classmethod (",[1163,1607,1212],{}," \u002F ",[1163,1610,1611],{},"generate","). Custom rules and attacks integrate with the simulation layer by inheriting and overriding the one abstract method.",[43,1614,82],{"id":1615},"simulations",[15,1617,1618,1619,1622,1623,1626],{},"Faithful reproductions of experimental protocols from seminal papers, in both ",[24,1620,1621],{},"centralised"," (parameter server) and ",[24,1624,1625],{},"decentralised"," (peer-to-peer) topologies:",[1628,1629,1630,1636,1905],"ul",{},[72,1631,1632,1635],{},[24,1633,1634],{},"NIPS 2017 Krum protocol"," (Blanchard et al.): fixed learning rate, no scheduler, reports misclassification error and cross-entropy loss.",[72,1637,1638,1641,1642,1904],{},[24,1639,1640],{},"ICML 2018 Hidden Vulnerability"," (El Mhamdi et al.): Robbins-Monro schedule ",[102,1643,1645,1702],{"className":1644},[105],[102,1646,1648],{"className":1647},[109],[111,1649,1650],{"xmlns":113},[115,1651,1652,1699],{},[118,1653,1654,1657,1659,1661,1663,1665,1672,1675,1682,1684,1686,1688,1691,1697],{},[121,1655,1656],{},"η",[210,1658,897],{"stretchy":896},[121,1660,1329],{},[210,1662,905],{"stretchy":896},[210,1664,1203],{},[449,1666,1667,1670],{},[121,1668,1669],{},"r",[121,1671,1656],{},[210,1673,1674],{},"⋅",[449,1676,1677,1679],{},[121,1678,1656],{},[221,1680,1681],{},"0",[121,1683,219],{"mathvariant":218},[210,1685,897],{"stretchy":896},[121,1687,1329],{},[210,1689,1690],{},"+",[449,1692,1693,1695],{},[121,1694,1669],{},[121,1696,1656],{},[210,1698,905],{"stretchy":896},[125,1700,1701],{"encoding":127},"\\eta(t) = r_\\eta \\cdot \\eta_0 \u002F (t + r_\\eta)",[102,1703,1705,1732,1790,1854],{"className":1704,"ariaHidden":132},[131],[102,1706,1708,1711,1714,1717,1720,1723,1726,1729],{"className":1707},[136],[102,1709],{"className":1710,"style":257},[140],[102,1712,1656],{"className":1713,"style":1349},[145,146],[102,1715,897],{"className":1716},[925],[102,1718,1329],{"className":1719},[145,146],[102,1721,905],{"className":1722},[935],[102,1724],{"className":1725,"style":243},[242],[102,1727,1203],{"className":1728},[247],[102,1730],{"className":1731,"style":243},[242],[102,1733,1735,1739,1781,1784,1787],{"className":1734},[136],[102,1736],{"className":1737,"style":1738},[140],"height:0.7306em;vertical-align:-0.2861em;",[102,1740,1742,1745],{"className":1741},[145],[102,1743,1669],{"className":1744,"style":921},[145,146],[102,1746,1748],{"className":1747},[478],[102,1749,1751,1773],{"className":1750},[482,483],[102,1752,1754,1770],{"className":1753},[487],[102,1755,1758],{"className":1756,"style":1757},[491],"height:0.1514em;",[102,1759,1761,1764],{"style":1760},"top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;",[102,1762],{"className":1763,"style":500},[499],[102,1765,1767],{"className":1766},[504,505,506,507],[102,1768,1656],{"className":1769,"style":1349},[145,146,507],[102,1771,515],{"className":1772},[514],[102,1774,1776],{"className":1775},[487],[102,1777,1779],{"className":1778,"style":1394},[491],[102,1780],{},[102,1782],{"className":1783,"style":635},[242],[102,1785,1674],{"className":1786},[639],[102,1788],{"className":1789,"style":635},[242],[102,1791,1793,1796,1836,1839,1842,1845,1848,1851],{"className":1792},[136],[102,1794],{"className":1795,"style":257},[140],[102,1797,1799,1802],{"className":1798},[145],[102,1800,1656],{"className":1801,"style":1349},[145,146],[102,1803,1805],{"className":1804},[478],[102,1806,1808,1828],{"className":1807},[482,483],[102,1809,1811,1825],{"className":1810},[487],[102,1812,1814],{"className":1813,"style":492},[491],[102,1815,1816,1819],{"style":1365},[102,1817],{"className":1818,"style":500},[499],[102,1820,1822],{"className":1821},[504,505,506,507],[102,1823,1681],{"className":1824},[145,507],[102,1826,515],{"className":1827},[514],[102,1829,1831],{"className":1830},[487],[102,1832,1834],{"className":1833,"style":522},[491],[102,1835],{},[102,1837,219],{"className":1838},[145],[102,1840,897],{"className":1841},[925],[102,1843,1329],{"className":1844},[145,146],[102,1846],{"className":1847,"style":635},[242],[102,1849,1690],{"className":1850},[639],[102,1852],{"className":1853,"style":635},[242],[102,1855,1857,1861,1901],{"className":1856},[136],[102,1858],{"className":1859,"style":1860},[140],"height:1.0361em;vertical-align:-0.2861em;",[102,1862,1864,1867],{"className":1863},[145],[102,1865,1669],{"className":1866,"style":921},[145,146],[102,1868,1870],{"className":1869},[478],[102,1871,1873,1893],{"className":1872},[482,483],[102,1874,1876,1890],{"className":1875},[487],[102,1877,1879],{"className":1878,"style":1757},[491],[102,1880,1881,1884],{"style":1760},[102,1882],{"className":1883,"style":500},[499],[102,1885,1887],{"className":1886},[504,505,506,507],[102,1888,1656],{"className":1889,"style":1349},[145,146,507],[102,1891,515],{"className":1892},[514],[102,1894,1896],{"className":1895},[487],[102,1897,1899],{"className":1898,"style":1394},[491],[102,1900],{},[102,1902,905],{"className":1903},[935],", L2 regularization, Xavier initialization as in Section 5.1 of the original paper.",[72,1906,1907,1910,1911,1966,1967,2018,2019,2023,2024,2027],{},[24,1908,1909],{},"ICML 2023 MoNNA"," (Farhadkhani et al.): decentralized peer-to-peer protocol with one local momentum SGD step per honest worker, then replacement by a nearest-neighbor average over the ",[102,1912,1914,1933],{"className":1913},[105],[102,1915,1917],{"className":1916},[109],[111,1918,1919],{"xmlns":113},[115,1920,1921,1931],{},[118,1922,1923,1925,1927,1929],{},[121,1924,215],{},[210,1926,611],{},[221,1928,223],{},[121,1930,123],{},[125,1932,618],{"encoding":127},[102,1934,1936,1954],{"className":1935,"ariaHidden":132},[131],[102,1937,1939,1942,1945,1948,1951],{"className":1938},[136],[102,1940],{"className":1941,"style":628},[140],[102,1943,215],{"className":1944},[145,146],[102,1946],{"className":1947,"style":635},[242],[102,1949,611],{"className":1950},[639],[102,1952],{"className":1953,"style":635},[242],[102,1955,1957,1960,1963],{"className":1956},[136],[102,1958],{"className":1959,"style":141},[140],[102,1961,223],{"className":1962},[145],[102,1964,123],{"className":1965,"style":147},[145,146]," closest models among ",[102,1968,1970,1988],{"className":1969},[105],[102,1971,1973],{"className":1972},[109],[111,1974,1975],{"xmlns":113},[115,1976,1977,1985],{},[118,1978,1979,1981,1983],{},[121,1980,215],{},[210,1982,611],{},[121,1984,123],{},[125,1986,1987],{"encoding":127},"n - f",[102,1989,1991,2009],{"className":1990,"ariaHidden":132},[131],[102,1992,1994,1997,2000,2003,2006],{"className":1993},[136],[102,1995],{"className":1996,"style":628},[140],[102,1998,215],{"className":1999},[145,146],[102,2001],{"className":2002,"style":635},[242],[102,2004,611],{"className":2005},[639],[102,2007],{"className":2008,"style":635},[242],[102,2010,2012,2015],{"className":2011},[136],[102,2013],{"className":2014,"style":141},[140],[102,2016,123],{"className":2017,"style":147},[145,146]," neighbors. Supports two Byzantine reach modes: ",[2020,2021,2022],"em",{},"all"," (worst case) and ",[2020,2025,2026],{},"sampled"," (gossip style).",[43,2029,88],{"id":2030},"orchestration",[15,2032,2033,2034,2037],{},"The layer that was ",[24,2035,2036],{},"lacking in all previously published libraries",": declare experiment parameters, collect typed metrics over time, and produce pandas DataFrames from full parameter sweeps.",[1156,2039,2041],{"className":1158,"code":2040,"language":1160,"meta":1161,"style":1161},"from krum.orchestration import Metric, Orchestrator\nfrom krum.primitives.aggregators.krum import Krum\nfrom krum.primitives.attacks.alie import ALIEAttack\n\ndef my_experiment(n, f, aggregator, attack, n_steps):\n    sim = KrumSimulation(n=n, f=f, aggregator=aggregator, attack=attack)\n    loss = Metric(\"loss\")\n    for step in range(n_steps):\n        sim.step()\n        loss.push(step, sim.loss())\n\norch = Orchestrator(\"krum_byzantine_study\")\nfor n in [10, 20]:\n    for f in [2, 3]:\n        orch.run(my_experiment, n=n, f=f, aggregator=Krum, attack=ALIEAttack, n_steps=100)\n\nloss_df = orch.get(\"loss\")  # pandas DataFrame with all run parameters merged\n",[1163,2042,2043,2064,2088,2114,2120,2157,2204,2228,2251,2265,2292,2297,2319,2343,2364,2424,2429],{"__ignoreMap":1161},[102,2044,2045,2047,2049,2051,2054,2056,2059,2061],{"class":1167,"line":1168},[102,2046,1172],{"class":1171},[102,2048,1176],{"class":1175},[102,2050,1180],{"class":1179},[102,2052,2053],{"class":1175},"orchestration ",[102,2055,1190],{"class":1171},[102,2057,2058],{"class":1175}," Metric",[102,2060,1221],{"class":1179},[102,2062,2063],{"class":1175}," Orchestrator\n",[102,2065,2066,2068,2070,2072,2074,2076,2079,2081,2084,2086],{"class":1167,"line":1196},[102,2067,1172],{"class":1171},[102,2069,1176],{"class":1175},[102,2071,1180],{"class":1179},[102,2073,92],{"class":1175},[102,2075,1180],{"class":1179},[102,2077,2078],{"class":1175},"aggregators",[102,2080,1180],{"class":1179},[102,2082,2083],{"class":1175},"krum ",[102,2085,1190],{"class":1171},[102,2087,1193],{"class":1175},[102,2089,2091,2093,2095,2097,2099,2101,2104,2106,2109,2111],{"class":1167,"line":2090},3,[102,2092,1172],{"class":1171},[102,2094,1176],{"class":1175},[102,2096,1180],{"class":1179},[102,2098,92],{"class":1175},[102,2100,1180],{"class":1179},[102,2102,2103],{"class":1175},"attacks",[102,2105,1180],{"class":1179},[102,2107,2108],{"class":1175},"alie ",[102,2110,1190],{"class":1171},[102,2112,2113],{"class":1175}," ALIEAttack\n",[102,2115,2117],{"class":1167,"line":2116},4,[102,2118,2119],{"emptyLinePlaceholder":8},"\n",[102,2121,2123,2127,2131,2133,2135,2137,2139,2141,2144,2146,2149,2151,2154],{"class":1167,"line":2122},5,[102,2124,2126],{"class":2125},"s_I8y","def",[102,2128,2130],{"class":2129},"s0QKf"," my_experiment",[102,2132,897],{"class":1179},[102,2134,215],{"class":1224},[102,2136,1221],{"class":1179},[102,2138,1225],{"class":1224},[102,2140,1221],{"class":1179},[102,2142,2143],{"class":1224}," aggregator",[102,2145,1221],{"class":1179},[102,2147,2148],{"class":1224}," attack",[102,2150,1221],{"class":1179},[102,2152,2153],{"class":1224}," n_steps",[102,2155,2156],{"class":1179},"):\n",[102,2158,2160,2163,2165,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188,2190,2193,2195,2197,2199,2202],{"class":1167,"line":2159},6,[102,2161,2162],{"class":1175},"    sim ",[102,2164,1203],{"class":1202},[102,2166,2167],{"class":1211}," KrumSimulation",[102,2169,897],{"class":1179},[102,2171,215],{"class":1224},[102,2173,1203],{"class":1202},[102,2175,215],{"class":1217},[102,2177,1221],{"class":1179},[102,2179,1225],{"class":1224},[102,2181,1203],{"class":1202},[102,2183,123],{"class":1217},[102,2185,1221],{"class":1179},[102,2187,2143],{"class":1224},[102,2189,1203],{"class":1202},[102,2191,2192],{"class":1217},"aggregator",[102,2194,1221],{"class":1179},[102,2196,2148],{"class":1224},[102,2198,1203],{"class":1202},[102,2200,2201],{"class":1217},"attack",[102,2203,1243],{"class":1179},[102,2205,2207,2210,2212,2214,2216,2220,2224,2226],{"class":1167,"line":2206},7,[102,2208,2209],{"class":1175},"    loss ",[102,2211,1203],{"class":1202},[102,2213,2058],{"class":1211},[102,2215,897],{"class":1179},[102,2217,2219],{"class":2218},"srDDN","\"",[102,2221,2223],{"class":2222},"sJlHP","loss",[102,2225,2219],{"class":2218},[102,2227,1243],{"class":1179},[102,2229,2231,2234,2237,2240,2244,2246,2249],{"class":1167,"line":2230},8,[102,2232,2233],{"class":1171},"    for",[102,2235,2236],{"class":1175}," step ",[102,2238,2239],{"class":1171},"in",[102,2241,2243],{"class":2242},"sbtgA"," range",[102,2245,897],{"class":1179},[102,2247,2248],{"class":1217},"n_steps",[102,2250,2156],{"class":1179},[102,2252,2254,2257,2259,2262],{"class":1167,"line":2253},9,[102,2255,2256],{"class":1175},"        sim",[102,2258,1180],{"class":1179},[102,2260,2261],{"class":1211},"step",[102,2263,2264],{"class":1179},"()\n",[102,2266,2268,2271,2273,2276,2278,2280,2282,2285,2287,2289],{"class":1167,"line":2267},10,[102,2269,2270],{"class":1175},"        loss",[102,2272,1180],{"class":1179},[102,2274,2275],{"class":1211},"push",[102,2277,897],{"class":1179},[102,2279,2261],{"class":1217},[102,2281,1221],{"class":1179},[102,2283,2284],{"class":1217}," sim",[102,2286,1180],{"class":1179},[102,2288,2223],{"class":1211},[102,2290,2291],{"class":1179},"())\n",[102,2293,2295],{"class":1167,"line":2294},11,[102,2296,2119],{"emptyLinePlaceholder":8},[102,2298,2300,2303,2305,2308,2310,2312,2315,2317],{"class":1167,"line":2299},12,[102,2301,2302],{"class":1175},"orch ",[102,2304,1203],{"class":1202},[102,2306,2307],{"class":1211}," Orchestrator",[102,2309,897],{"class":1179},[102,2311,2219],{"class":2218},[102,2313,2314],{"class":2222},"krum_byzantine_study",[102,2316,2219],{"class":2218},[102,2318,1243],{"class":1179},[102,2320,2322,2325,2328,2330,2333,2335,2337,2340],{"class":1167,"line":2321},13,[102,2323,2324],{"class":1171},"for",[102,2326,2327],{"class":1175}," n ",[102,2329,2239],{"class":1171},[102,2331,2332],{"class":1179}," [",[102,2334,1240],{"class":1230},[102,2336,1221],{"class":1179},[102,2338,2339],{"class":1230}," 20",[102,2341,2342],{"class":1179},"]:\n",[102,2344,2346,2348,2351,2353,2355,2357,2359,2362],{"class":1167,"line":2345},14,[102,2347,2233],{"class":1171},[102,2349,2350],{"class":1175}," f ",[102,2352,2239],{"class":1171},[102,2354,2332],{"class":1179},[102,2356,223],{"class":1230},[102,2358,1221],{"class":1179},[102,2360,2361],{"class":1230}," 3",[102,2363,2342],{"class":1179},[102,2365,2367,2370,2372,2375,2377,2380,2382,2384,2386,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410,2413,2415,2417,2419,2422],{"class":1167,"line":2366},15,[102,2368,2369],{"class":1175},"        orch",[102,2371,1180],{"class":1179},[102,2373,2374],{"class":1211},"run",[102,2376,897],{"class":1179},[102,2378,2379],{"class":1217},"my_experiment",[102,2381,1221],{"class":1179},[102,2383,1235],{"class":1224},[102,2385,1203],{"class":1202},[102,2387,215],{"class":1217},[102,2389,1221],{"class":1179},[102,2391,1225],{"class":1224},[102,2393,1203],{"class":1202},[102,2395,123],{"class":1217},[102,2397,1221],{"class":1179},[102,2399,2143],{"class":1224},[102,2401,1203],{"class":1202},[102,2403,26],{"class":1217},[102,2405,1221],{"class":1179},[102,2407,2148],{"class":1224},[102,2409,1203],{"class":1202},[102,2411,2412],{"class":1217},"ALIEAttack",[102,2414,1221],{"class":1179},[102,2416,2153],{"class":1224},[102,2418,1203],{"class":1202},[102,2420,2421],{"class":1230},"100",[102,2423,1243],{"class":1179},[102,2425,2427],{"class":1167,"line":2426},16,[102,2428,2119],{"emptyLinePlaceholder":8},[102,2430,2432,2435,2437,2440,2442,2445,2447,2449,2451,2453,2455],{"class":1167,"line":2431},17,[102,2433,2434],{"class":1175},"loss_df ",[102,2436,1203],{"class":1202},[102,2438,2439],{"class":1175}," orch",[102,2441,1180],{"class":1179},[102,2443,2444],{"class":1211},"get",[102,2446,897],{"class":1179},[102,2448,2219],{"class":2218},[102,2450,2223],{"class":2222},[102,2452,2219],{"class":2218},[102,2454,905],{"class":1179},[102,2456,2458],{"class":2457},"sv490","  # pandas DataFrame with all run parameters merged\n",[15,2460,2461],{},"The orchestrator automatically tracks all run parameters and merges them with collected metrics, enabling filtering and aggregation with standard pandas operations, a programmatic approach that contrasts with configuration-file-based alternatives (JSON configs in ByzFL, CLI in FL-Byz-Lib).",[43,2463,2465],{"id":2464},"engineering","Engineering",[1628,2467,2468,2474,2480,2486,2497,2607],{},[72,2469,2470,2473],{},[24,2471,2472],{},"Datasets",": auto-download, provided list (MNIST, CIFAR-10, Spambase, etc.)",[72,2475,2476,2479],{},[24,2477,2478],{},"Checkpointing",": one-liner to save\u002Fload model state",[72,2481,2482,2485],{},[24,2483,2484],{},"Plotting",": matplotlib\u002Fseaborn for manual visualization",[72,2487,2488,2491,2492],{},[24,2489,2490],{},"Documentation",": ADRs, tutorials, and explicit references to papers, hosted at ",[18,2493,2496],{"href":2494,"rel":2495},"https:\u002F\u002Fcalicarpa.github.io\u002Fkrum\u002F",[22],"calicarpa.github.io\u002Fkrum",[72,2498,2499,2502,2503,1097,2555,2606],{},[24,2500,2501],{},"Tests",": comprehensive suite covering edge cases (",[102,2504,2506,2524],{"className":2505},[105],[102,2507,2509],{"className":2508},[109],[111,2510,2511],{"xmlns":113},[115,2512,2513,2521],{},[118,2514,2515,2517,2519],{},[121,2516,123],{},[210,2518,1203],{},[221,2520,1681],{},[125,2522,2523],{"encoding":127},"f = 0",[102,2525,2527,2545],{"className":2526,"ariaHidden":132},[131],[102,2528,2530,2533,2536,2539,2542],{"className":2529},[136],[102,2531],{"className":2532,"style":141},[140],[102,2534,123],{"className":2535,"style":147},[145,146],[102,2537],{"className":2538,"style":243},[242],[102,2540,1203],{"className":2541},[247],[102,2543],{"className":2544,"style":243},[242],[102,2546,2548,2552],{"className":2547},[136],[102,2549],{"className":2550,"style":2551},[140],"height:0.6444em;",[102,2553,1681],{"className":2554},[145],[102,2556,2558,2576],{"className":2557},[105],[102,2559,2561],{"className":2560},[109],[111,2562,2563],{"xmlns":113},[115,2564,2565,2573],{},[118,2566,2567,2569,2571],{},[121,2568,215],{},[210,2570,1203],{},[121,2572,123],{},[125,2574,2575],{"encoding":127},"n = f",[102,2577,2579,2597],{"className":2578,"ariaHidden":132},[131],[102,2580,2582,2585,2588,2591,2594],{"className":2581},[136],[102,2583],{"className":2584,"style":363},[140],[102,2586,215],{"className":2587},[145,146],[102,2589],{"className":2590,"style":243},[242],[102,2592,1203],{"className":2593},[247],[102,2595],{"className":2596,"style":243},[242],[102,2598,2600,2603],{"className":2599},[136],[102,2601],{"className":2602,"style":141},[140],[102,2604,123],{"className":2605,"style":147},[145,146],", minimal configs), run on GitHub Actions across Python 3.10–3.14",[72,2608,2609,2612,2613,2616],{},[24,2610,2611],{},"CI\u002FCD",": Ruff for linting and formatting, ",[1163,2614,2615],{},"ty"," for type checking, pre-commit hooks",[43,2618,2620],{"id":2619},"comparison-to-related-software","Comparison to Related Software",[15,2622,2623,2624,2627],{},"Compared to ByzFL, FedLab, Blades, FL-Byz-Lib, and ByzPy, Krum is the only library combining ",[24,2625,2626],{},"protocol-faithful simulations, zero-copy model wrappers, and programmatic orchestration",". It trades raw breadth (10 aggregators vs 36 in FL-Byz-Lib, 12+4 in ByzFL) for fidelity to the original NIPS 2017, ICML 2018, and ICML 2023 protocols and an orchestration layer that scales to thousands of reproducible experiments.",[43,2629,2631],{"id":2630},"installation","Installation",[1156,2633,2637],{"className":2634,"code":2635,"language":2636,"meta":1161,"style":1161},"language-bash shiki shiki-themes material-theme-lighter catppuccin-latte catppuccin-macchiato","pip install krum\n# with experiment dependencies (matplotlib, numpy, seaborn)\npip install \"krum[experiments]\"\n# or with uv\nuv add krum\n","bash",[1163,2638,2639,2651,2656,2671,2676],{"__ignoreMap":1161},[102,2640,2641,2645,2648],{"class":1167,"line":1168},[102,2642,2644],{"class":2643},"sqbHp","pip",[102,2646,2647],{"class":2222}," install",[102,2649,2650],{"class":2222}," krum\n",[102,2652,2653],{"class":1167,"line":1196},[102,2654,2655],{"class":2457},"# with experiment dependencies (matplotlib, numpy, seaborn)\n",[102,2657,2658,2660,2662,2665,2668],{"class":1167,"line":2090},[102,2659,2644],{"class":2643},[102,2661,2647],{"class":2222},[102,2663,2664],{"class":2218}," \"",[102,2666,2667],{"class":2222},"krum[experiments]",[102,2669,2670],{"class":2218},"\"\n",[102,2672,2673],{"class":1167,"line":2116},[102,2674,2675],{"class":2457},"# or with uv\n",[102,2677,2678,2681,2684],{"class":1167,"line":2122},[102,2679,2680],{"class":2643},"uv",[102,2682,2683],{"class":2222}," add",[102,2685,2650],{"class":2222},[43,2687,2689],{"id":2688},"status","Status",[15,2691,2692],{},"Active development: the paper is in preparation, and new aggregation rules, attack models, and protocol reproductions are continuously added as my research progresses.",[43,2694,2696],{"id":2695},"repository","Repository",[15,2698,2699],{},[18,2700,2702],{"href":20,"rel":2701},[22],"github.com\u002Fcalicarpa\u002Fkrum",[2704,2705,2706],"style",{},"html pre.shiki code .sthAO, html code.shiki .sthAO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#8839EF;--shiki-default-font-style:inherit;--shiki-dark:#C6A0F6;--shiki-dark-font-style:inherit}html pre.shiki code .s0g_q, html code.shiki .s0g_q{--shiki-light:#90A4AE;--shiki-default:#4C4F69;--shiki-dark:#CAD3F5}html pre.shiki code .sMKYs, html code.shiki .sMKYs{--shiki-light:#39ADB5;--shiki-default:#7C7F93;--shiki-dark:#939AB7}html pre.shiki code .sn2um, html code.shiki .sn2um{--shiki-light:#39ADB5;--shiki-default:#179299;--shiki-dark:#8BD5CA}html pre.shiki code .sung0, html code.shiki .sung0{--shiki-light:#6182B8;--shiki-default:#1E66F5;--shiki-dark:#8AADF4}html pre.shiki code .su9Z2, html code.shiki .su9Z2{--shiki-light:#6182B8;--shiki-default:#4C4F69;--shiki-dark:#CAD3F5}html pre.shiki code .smoPz, html code.shiki .smoPz{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E64553;--shiki-default-font-style:italic;--shiki-dark:#EE99A0;--shiki-dark-font-style:italic}html pre.shiki code .sZm5v, html code.shiki .sZm5v{--shiki-light:#F76D47;--shiki-default:#FE640B;--shiki-dark:#F5A97F}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s_I8y, html code.shiki .s_I8y{--shiki-light:#9C3EDA;--shiki-default:#8839EF;--shiki-dark:#C6A0F6}html pre.shiki code .s0QKf, html code.shiki .s0QKf{--shiki-light:#6182B8;--shiki-light-font-style:inherit;--shiki-default:#1E66F5;--shiki-default-font-style:italic;--shiki-dark:#8AADF4;--shiki-dark-font-style:italic}html pre.shiki code .srDDN, html code.shiki .srDDN{--shiki-light:#39ADB5;--shiki-default:#40A02B;--shiki-dark:#A6DA95}html pre.shiki code .sJlHP, html code.shiki .sJlHP{--shiki-light:#91B859;--shiki-default:#40A02B;--shiki-dark:#A6DA95}html pre.shiki code .sbtgA, html code.shiki .sbtgA{--shiki-light:#6182B8;--shiki-light-font-style:inherit;--shiki-default:#FE640B;--shiki-default-font-style:italic;--shiki-dark:#F5A97F;--shiki-dark-font-style:italic}html pre.shiki code .sv490, html code.shiki .sv490{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#7C7F93;--shiki-default-font-style:italic;--shiki-dark:#939AB7;--shiki-dark-font-style:italic}html pre.shiki code .sqbHp, html code.shiki .sqbHp{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#1E66F5;--shiki-default-font-style:italic;--shiki-dark:#8AADF4;--shiki-dark-font-style:italic}",{"title":1161,"searchDepth":1196,"depth":1196,"links":2708},[2709,2710,2711,2717,2718,2719,2720,2721,2722,2723],{"id":45,"depth":1196,"text":46},{"id":56,"depth":1196,"text":57},{"id":92,"depth":1196,"text":76,"children":2712},[2713,2714,2715,2716],{"id":96,"depth":2090,"text":97},{"id":1246,"depth":2090,"text":1247},{"id":1514,"depth":2090,"text":1515},{"id":1594,"depth":2090,"text":1595},{"id":1615,"depth":1196,"text":82},{"id":2030,"depth":1196,"text":88},{"id":2464,"depth":1196,"text":2465},{"id":2619,"depth":1196,"text":2620},{"id":2630,"depth":1196,"text":2631},{"id":2688,"depth":1196,"text":2689},{"id":2695,"depth":1196,"text":2696},"2026-06-15","Open-source framework for Byzantine-resilient aggregation in distributed learning, developed during my M2 internship at CMAP.","krum","In progress","projects\u002Fkrum",[2730,2731,2732],"Distributed Learning","AI Safety","Research","Research Project","dxLr17DSBt1rOj1l_-rmC9GCuwYrir_a8sdu6hxLlLA",1787557309470]