A small proof-of-concept compiler for running a PyTorch model in Excel as a standalone Excel formula. Works by exporting the model to IR and implementing the IR as Excel functions. Only a very limited number of functions are currently implemented.
Implements some basic N-dimensional arrays provided all dimensions other than the final two are fixed size. This is currently very early work and still isn't easily generalisable.
Follow the example script: train your model (currently must be quite simple), then run the compile
function to generate Excel code. Copy this code to excel and call it as you would a LAMBDA
: add parentheses and select the appropriate input array.
For example, this is a simple model trained (overfitted) on the iris dataset:
=LAMBDA(arg6_1,LET(arg0_1,{0.6755406856536865,0.2722516357898712,0.39513954520225525,-0.3702843487262726;-0.24654251337051392,0.13816797733306885,-0.490775465965271,0.3086247444152832;-0.21453094482421875,0.06720143556594849,-0.2270292043685913,-0.07332319021224976;-0.002623607637360692,-0.3572579622268677,0.6844033598899841,0.9872056245803833;0.5125312209129333,0.026729512959718704,-0.3425404131412506,-0.7845072746276855;-0.0820859745144844,-0.20946821570396423,0.6256487369537354,0.5311275124549866;-0.25164496898651123,0.0149918794631958,-0.1861262321472168,0.12087100744247437;-0.12344829738140106,-0.06201322749257088,0.4088282585144043,1.0024151802062988;-0.49204373359680176,-0.13200706243515015,0.36979246139526367,-0.004523932933807373;0.4690617322921753,0.4026934504508972,-0.16227367520332336,-0.033487919718027115},arg1_1,{0.7533818483352661,-0.4587647318840027,0.44453656673431396,-0.1182481050491333,0.5424882173538208,-0.16776815056800842,0.30052077770233154,0.3472484350204468,-0.4654860496520996,0.789039134979248},arg2_1,{0.17316509783267975,-0.036971237510442734,-0.0653868094086647,-0.6598910093307495,0.5232530832290649,-0.5113981366157532,-0.08833175897598267,-0.46431538462638855,0.159484401345253,0.48817718029022217;-0.2660481929779053,-0.09330783784389496,-0.07214801013469696,-0.21901381015777588,-0.07347608357667923,0.03735914081335068,-0.19995078444480896,0.2996073365211487,0.0035201350692659616,0.033016905188560486;0.21530328691005707,-0.07547577470541,-0.2436741292476654,-0.5650884509086609,0.6792961955070496,-0.32949885725975037,-0.2581961154937744,-0.041385915130376816,0.06939531117677689,0.5152519345283508;-0.30850186944007874,-0.26137399673461914,0.26357921957969666,-0.2487984001636505,-0.12437846511602402,0.05310168117284775,0.23956400156021118,-0.1433687061071396,0.13663804531097412,-0.14409689605236053;0.27470430731773376,0.19175000488758087,-0.023780768737196922,-0.4190802276134491,0.9413291811943054,-0.516299843788147,0.26722919940948486,-0.2737571597099304,0.27924060821533203,0.5663600564002991;-0.19199413061141968,0.2814283072948456,-0.004687356296926737,0.1369551122188568,0.0404154509305954,0.11832914501428604,-0.1438816785812378,-0.09671767055988312,-0.07749657332897186,0.030583016574382782;-0.16795581579208374,-0.2011336088180542,-0.21788892149925232,-0.1748097538948059,0.08774495869874954,-0.28543344140052795,-0.21982000768184662,-0.2816409170627594,-0.2085144817829132,-0.09510128200054169;0.3193264901638031,0.27786242961883545,-0.15218518674373627,-0.8634354472160339,0.5213719606399536,-0.6282461881637573,0.19269873201847076,-0.5427785515785217,0.12941716611385345,0.4307142198085785;-0.21289971470832825,-0.05548938736319542,0.20106741786003113,0.4086500406265259,-0.6302275657653809,0.3950834274291992,0.18438933789730072,0.4219886064529419,-0.02140934392809868,-0.1809024214744568;0.20861747860908508,-0.06452829390764236,0.2508927881717682,0.7906195521354675,-0.6503483057022095,0.2451571524143219,-0.24851728975772858,0.7697369456291199,0.05266676843166351,0.40741124749183655},arg3_1,{-0.010692717507481575,-0.06496988236904144,0.39448943734169006,0.13169324398040771,0.3764630854129791,-0.13816651701927185,0.0018116561695933342,0.17871730029582977,-0.006946933921426535,-0.07824358344078064},arg4_1,{0.75335294008255,0.15838003158569336,0.2154468148946762,0.09197422116994858,0.4148898720741272,0.3001541793346405,0.2199811190366745,0.5427114963531494,-0.48326757550239563,-0.8153956532478333;-0.4655643403530121,0.005202225409448147,0.45193660259246826,-0.07070443034172058,0.5038460493087769,0.1235661655664444,-0.3054121434688568,-0.39311739802360535,-0.7234961986541748,-0.19949598610401154;-0.2194778472185135,0.08164998888969421,-0.7295072078704834,0.3101988732814789,-0.6507652997970581,-0.1484612673521042,-0.2672695517539978,-0.1375863403081894,0.3265020549297333,0.08277250826358795},arg5_1,{-0.24741260707378387,0.30445533990859985,-0.1001971960067749},LAMBDA(addmm_2d,relu_2d,argmax0_2d,argmax1_2d,view_2d,LET(view,TAKE(DROP(WRAPROWS(HSTACK(TOROW(arg6_1)),4),0),1),LET(permute,TRANSPOSE(arg0_1),LET(addmm,addmm_2d(arg1_1,view,permute),LET(view_1,TAKE(DROP(WRAPROWS(HSTACK(TOROW(addmm)),10),0),1),LET(relu,relu_2d(view_1),LET(view_2,TAKE(DROP(WRAPROWS(HSTACK(TOROW(relu)),10),0),1),LET(permute_1,TRANSPOSE(arg2_1),LET(addmm_1,addmm_2d(arg3_1,view_2,permute_1),LET(view_3,TAKE(DROP(WRAPROWS(HSTACK(TOROW(addmm_1)),10),0),1),LET(relu_1,relu_2d(view_3),LET(view_4,TAKE(DROP(WRAPROWS(HSTACK(TOROW(relu_1)),10),0),1),LET(permute_2,TRANSPOSE(arg4_1),LET(addmm_2,addmm_2d(arg5_1,view_4,permute_2),LET(view_5,TAKE(DROP(WRAPROWS(HSTACK(TOROW(addmm_2)),3),0),1),LET(argmax,argmax1_2d(view_5),argmax))))))))))))))))(LAMBDA(__aten_addmm_input,__aten_addmm_mat_1,__aten_addmm_mat_2,__aten_addmm_input+MMULT(__aten_addmm_mat_1,__aten_addmm_mat_2)),LAMBDA(__aten_relu_input,IF(__aten_relu_input>0,__aten_relu_input,0)),LAMBDA(__aten_argmax_input,BYCOL(__aten_argmax_input,LAMBDA(x,MATCH(MAX(x),x,0)))-1),LAMBDA(__aten_argmax_input,BYROW(__aten_argmax_input,LAMBDA(x,MATCH(MAX(x),x,0)))-1),LAMBDA(__aten_view_arr,__aten_view_size,WRAPROWS(TOROW(__aten_view_arr),__aten_view_size)))))
To run it, download the iris.data
file and open it in Excel as a CSV file. Paste the code into the F1
cell and add (A1:D1)
. The model will output the classification of the first line.