From 01b4292952bbc828a3d8700fed98e5c82de191a7 Mon Sep 17 00:00:00 2001 From: Agus Date: Wed, 29 May 2024 11:14:55 +0200 Subject: [PATCH] Integration instructor (#654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New module for the integration with instructor * Mode common functions related to structured outputs to it's own module * Draft instructor integration with openai * Add tests for openai integration * Add unit tests for the instructor integrations * Add tests for anthropic integration * Fix including anthropic wrapper * Update llms to deal with instructor * Update dependencies with instructor * Run tests with instructor only on python>=3.9 * Fix circular import with create_distiset * Define _prepare_structured_output as staticmethod * Remove rewritten variable * Remove dead code * Check on Enum.value instead of Enum class as it isn't pickleable * Add tests for utilities related to generation of BaseModel objects from json schema dicts * Add fix to deal with nested BaseModel objects * Fix call from instructor, this should be done on instructor end, but works for the moment * Add docstirngs and typing info * Add script to generate a sample dataset and visualize the result * Update the docstring of the structured output expected format * Add reference in the docs to structured outputs with instructor * Add reference to the dependency installation * Update typing info * Fix test with new mocked client for mistral * Update docs/sections/learn/advanced/structured_generation.md Co-authored-by: Gabriel Martín Blázquez * Update docs/sections/learn/advanced/structured_generation.md Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/instructor.py Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/instructor.py Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/utils.py Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/instructor.py Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/utils.py Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/utils.py Co-authored-by: Gabriel Martín Blázquez * Update src/distilabel/steps/tasks/structured_outputs/utils.py Co-authored-by: Gabriel Martín Blázquez * Add changes from code review * Fix type hint per code review * Update docs/sections/learn/advanced/structured_generation.md Co-authored-by: Alvaro Bartolome * Remove repeated line --------- Co-authored-by: Gabriel Martín Blázquez Co-authored-by: Alvaro Bartolome --- .github/workflows/test.yml | 2 +- .../examples/knowledge-graph-example.png | Bin 0 -> 200852 bytes .../learn/advanced/structured_generation.md | 76 ++++++++- .../pipeline_samples/examples/index.md | 41 ++++- examples/draw_kg.py | 82 +++++++++ .../structured_generation_with_instructor.py | 87 ++++++++++ pyproject.toml | 1 + src/distilabel/llms/anthropic.py | 43 +++-- src/distilabel/llms/azure.py | 9 +- src/distilabel/llms/base.py | 83 +++++++++ src/distilabel/llms/cohere.py | 51 ++++-- src/distilabel/llms/groq.py | 42 +++-- src/distilabel/llms/litellm.py | 74 ++++++--- src/distilabel/llms/mistral.py | 39 ++++- src/distilabel/llms/openai.py | 50 ++++-- src/distilabel/pipeline/local.py | 5 - src/distilabel/steps/tasks/base.py | 4 +- .../tasks/structured_outputs/instructor.py | 140 ++++++++++++++++ .../tasks/structured_outputs/outlines.py | 13 +- .../steps/tasks/structured_outputs/utils.py | 157 ++++++++++++++++++ tests/unit/llms/test_anthropic.py | 82 ++++++++- tests/unit/llms/test_azure.py | 82 +++++++-- tests/unit/llms/test_cohere.py | 98 +++++++++-- tests/unit/llms/test_groq.py | 101 +++++++++-- tests/unit/llms/test_mistral.py | 83 ++++++++- tests/unit/llms/test_openai.py | 103 ++++++++++-- tests/unit/llms/utils.py | 20 +++ .../tasks/structured_outputs/test_utils.py | 75 +++++++++ 28 files changed, 1472 insertions(+), 171 deletions(-) create mode 100644 docs/assets/images/sections/examples/knowledge-graph-example.png create mode 100644 examples/draw_kg.py create mode 100644 examples/structured_generation_with_instructor.py create mode 100644 src/distilabel/steps/tasks/structured_outputs/instructor.py create mode 100644 src/distilabel/steps/tasks/structured_outputs/utils.py create mode 100644 tests/unit/llms/utils.py create mode 100644 tests/unit/steps/tasks/structured_outputs/test_utils.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01f1ebcb9..56c39f169 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,7 +47,7 @@ jobs: pip install -e .[dev,tests,anthropic,argilla,cohere,groq,hf-inference-endpoints,hf-transformers,litellm,llama-cpp,ollama,openai,outlines,vertexai,vllm] if [ "${python_version}" != "(3, 8)" ]; then - pip install -e .[mistralai] + pip install -e .[mistralai,instructor] fi; pip install git+https://github.com/argilla-io/LLM-Blender.git diff --git a/docs/assets/images/sections/examples/knowledge-graph-example.png b/docs/assets/images/sections/examples/knowledge-graph-example.png new file mode 100644 index 0000000000000000000000000000000000000000..05c80c6cafd0f113193cffcaf7e9d6572a21a4d2 GIT binary patch literal 200852 zcmeFZXH-+swl*94wk{+?X_IKJWBdt4i zAbc%Zmlv-SL0YnQxjvVkktm01KEHB_M!c!`=X3|YuqXJ*7t+^+@*CVya6Ve1(T#zaHFTKYkRRAatEpSWH{s!};PXEq z8aFm={XoOWc-8!-)43@U0eW2yUt=CQwmlEwNeg@|MFF~Z>z8M+6d%Q}m!O|X64m)2 z(8p+zY%S(w3;nSAOGKBqWpDQD{8YKAuJ;q}o_?q={H+2M4{kJ8z7KLpxii52+gg?! zD)l<^Nnq|}kQdQ6DL=o2L&~DZP6Uu|l)ZbYtI{i0XKDgLN(sGv4DC^k-DILNANcwg z)v?ke+ij|*m7arbHvbL@ zX~1ZF%0PtZOO0DO>VeKOH@-zs62Ec3`!y-hKjOh_f``U;R&*@z*ls_Ud`(BXL$Hu2 zoX(o?JgIf?_zFpS!S4Y#R`)i3Gm3ms67GVtb#6SxlDHBY>khWZPs1laYJRvuQhn=N z?2)LOg-ZHEd4rAa$MkOmb!poOzg6Qu`_v}O#PuWoQU@nWb$5q&`7NaXx;smfZ^&ca zz}GC&`do2baZLS$&D@mL*NMC?9a(-QUT&wmbcu5*){E>3iJM9$#V`DG{SN&M&i)wP z=>?k?v*tHlh^keCEi&A>v-Cl9`Lav{lypzJxPE{R&CKxWF~}UmQNC(^ zy_=~002yKGTeL!gZ_JFBDg$Cj{PFYkJ-@iirVBFH4yjo1x|wb*^Py=%WxGQdpVR0O z$KOHoB*t~)Y24{2uwbS`sxIa|kwaepLe+iwd_I$mi=s1~tgQTeZujMePXuAAE9+gx zy>3mWx_d;|30~j%#{7}TITZWT)b~-#@t3t|0k^m>et|GH306(Rj4bbI9bwo3{;3G=7&k4jPq9WHA)qJ&A1l!p7BW)v6t%9XCQJZx&`= zxV%lJf!-#i$;xO%&LHb) zl$T{6Q@Mc;`7Nc`4UUry(}whcbRcW@hPS1x7%(CA6`>jfBouiwG#jP2rCwrCs99SmhM=0 zlUhmE5SAz$+=+ab(CwE`&=@1}#6Nzbn~hoy{0uUB87iyz@o8dsMDF&AuOL-sG;Qwg z5bKIz9VsGaJdbVY?TS|&RZ!T0B}n^==R@ruc$UwdxJgyN@IN3CCgbYpspc%Fb$l^! z#5w+E|2dNzi+b111_I+RcYN{tzp^dVZgm{`2eO&Q!G7s&NBT0I#mL;faead%>(W&V z?mGz&!Zl^t*__xISTZ8eT6FV_@03Pa4XF_G%^#lrxUbH}d*7LP{F(-(`0Kbgr}wTa zXIp9P+?RjXkdLoLV$WzVQj+Q!J}Q4KqkAVkKJ)wI-_$j)ji2(ep;?&N%i86AX~HXxBNXxshED7_>hPzp8w#PQQFy4A zw@mt;#pHGBrB~?Y>Q;HnqYA|25n7oAQjg(EaO2a^W7d6B@~DU;BBPgO4^{JI7d~~W z#RRK0EwT5p_eu11q%{i;IC?w2t1GX=haMX4LhBtehy9;+tt@#8XDVhZ&M8Q%p@;7~ z7&&^>)k1sgFm^CU%&OgL!^*w2r(-39qJ<+RZ&wXh-90_LQr0#n;JH})4?_>eAAI>F z|J5PV-=6*_aiY00Y%X}RDh5BU-Q4zU+q$369 zRzJO|Sm61Vctmk-rbYR@=hun|NW`f^r@|M7=XqWVMbZ8-UNNW9wJ~}(nM5`p=B6Kh zxU8m|Dwr-|yYfIk+PKqDfh%udbWre{jzd#N9b&IG6>9LppxPjFD#)W$bVTB7V3OZk zzwGcg@~=9syuI~SJegXx&^meXR&Q-Gx}v<|eL1bZkiM7Ex`9Xe+j7Tp^wgkJAmsjx z&XjR2>oh;a!%1Y)v|bKnjH=n-+~A$cJ8(Xb#gZQ|-o1QRLgBT7PE5mU&e~^pcF$rr z-<9I^8=LwYlRppL^Ei<D_)zgyy*-U=I2kNju9HJG@e zf1NI*bk3=LQjWi0cdwMK@V+ivs|Kl(;k!{$@86TDmVEc=?~x_YYb$ZQ;h51r?jnpe zlC0z!6N28`@AO^Y*6zyAHh*x(r@i{k8dW0|MgFzn_ru-=LGuc3WeumR8GAi@Qn%A# z5ttX~F0&5wHD5B_%URaGw&mR`{d@h!sZ$Ay>ENs}E-SJLGBfK)E0><&Y^tQ%ySB_C z95CLvjFe;_{e0G*YfyFmEI}`=$VpRUmd%U}QNR7)Qpz8!0;JwcOSM(Y(4Td~lp*i2z=Amq`@ZKZo$ zo;{s_F(7_=_{S~X7roC+i6b~YNUs!yFf^gT4vT@aBETn)OCFX@@A(0tn;M8zxm5S z4a&^twYTSHG-ApSWoiQNb)6W#Ri|J$QY-F-S(L;JxaG*`02^H$PeKs}6a-|WRcCxG zLnhCX34RbjiFqh=Z+~RstWaDl8p8-#33&?N7x8AeDmgp+d(3m?^};(wMYT9xh7r;F zy+`|pCkq69@_nal-`M;$Y_bAp`KuQ%O_-d&@emtuyEm!W{!)kipW^fBgO;uYrlJ) zQRKSwY*VU#?Jn)PE(SF_Q?*HrJPP#bmu!a*V{c)4nQllGAAdcFYf^{xTT&3*u9u7o z@WebsZ@*K*8kMElRr%NIVeFO^}#G_OmXI{*av)?EU5Lm(HkkGp;Rm zkcS!`p5GoJJ9l=*|Kvk25&Sr4UkCKj9`r2$~lUySAmfwY9T{or`DKfsYMvfW%eFzyk!LWxaUeDQn%^0`5OyucPm& zul7{T(gnh6Vde7Nn%5WNdT}3+gs&Lz5n}CW!R!lha`q7Om1Ozz4Kd*J#bG`c=09KY zbd+S#SJPycb8)w37Uq4x`+!A?l$n`X!rjV7OzVllKQ9OVl4P;-^mG;DI0rFj(;d{vYfbT!=4O}X5aa2sx-q+g6;E6p1 zuo=*Xl&GMf#Gmi~b>_cX{BKw4|JRlLBK!~j`=$Tw)c?E`>|yOL=K=xR^pyIq`TFO@ z|NZ1YFO=ZB82W!R#Xs!)=O|!kDN+f(|C}@_(v3W14KR-k_D?i)fOo*lE`IPPfnV(Z zcn3b?kt@u6T{-}PWI)PK9_#qxZ6JIysP|91wlN!~3!9JppCz*3zX-)=(cOT*y+LIZ zeakUgVdK8TbM#qs#H5hQ^DmW?9Gow-E?s)!pWr^a4udUY zhHn15eU%9Xakl;27lFbINhoD1Xy`Jp{o8#721x&JUqo5_{|5N4X6gUUAkJm>|6KH6 zhpqo#t--K0LY8atFCL@wR(u|nznDY|bgct{^C2G1;~ z2xDt3*@VFADp9|K8QMZdj@A@A3~-NhG7SHcrVq1JoB~biRgWy`v*t zDqNnFj+XOzm%Myb0~QHG(KR!{+GaKK^S>eZ-l;?(f*iTLrN@_oQ<9YLV5nyI7)c0c z7k-XksXdr5WFJElX$9FMVY9BKC!4`(Gs)vmR0iVt)4G*45*C7Isz<(^>Ie8YHD`0M z31~~96Ij`L4-jXm20K%&0Wpl&np*fzM-*{4&1L3L5dL4kWI#!CI1c~$>ZiMevpu=F zEfV3vPOj4QH1+5hdTP@))A^P_z> z>g2B;|LI!1C;mH`RN3`$&Iad9S;ukCI`0^)L7A&_WxL}z`>)%I!sTGAJnVO~WnKd& zl_pVN0{1}Y#UW}@-5^0$Yi*igY9Hw_1kB@LTXZueMEk~wc)d5q!Lc?|$#;Z}!L1Fo zaJw0ME!|_XzY%iBM|wrq0P0ZIrehxSs$!?qD11yZGtnr@C`PC(DPyT(vCfsCyke$j zq6vBeneLvefd*C>a(2WTHO=uDHFz(5iNIxHnXlKFL#JJltOAd5I#C#k*?dgprE|Ps zgL{%}8DgMxY}2-&olB3iX3bW9yj(NCTeiSU;)ck^s+E=Ml=E2s4+f4A6LqACDY6>v zPouwCM6)rR#~?fTes)j**7?(Ldy?r-PvXe? z2v>*SDXtFR$cq*5@xoPAX||iX2y_2|H$y z0YO_^I6B|pvJ(j3i|;4VZ8_($;Tjq)>XRv{UK+!*TC71~_kikb=&F{;C4&Y?mj#VN zEyDG=Kw05x@T@~>D=iPAG>r$bh(r|pgtN}4H}$sL_M&;o(7k8Y(lg}Q$FmL>?n+4# zLCxE({isa_Sb6;e=Zg#Vi;Y-%5%!i~ILrEk-&~Y#C67KjA{qu+G%R{Uf8TlTS?ks2 zrfieM8V}+laZk;)esK=#qD(-gf7$7T(_8Po0U*>pziU?ra19>_773w7&qnYItyNR} zvwyztAm#D?TA)hTgf}AZ{JGAmjQCf+wNl@7Q*RB-BgGn4Fg4?3m<3O27HsC}MV2OM z849Mf`FV(Ft`R9S8r5c1n3B9ge5x@b7pb#=(;IqAJ5DrZ3n6`c)hgQ?9cLXH%4iJM zgLib5ztmJ@WhD&h^s8qsu20IJsb?k)yXh5dP7j?nSb$+soNaj(_m_xpjR{K09BN3$ z-Nb?`ri99zUi+j{7$*M~T<@COL;FL|Zb&vfh1*rG@NL0hawJ|RH%zRgIk9P^KUo{b zIy&dB@t zfDfNGfW1}8>U{-i{k^AslB#Oy)loI+T5t{90xxfZGFo>VoEX`ho{Ulk(U~)Q^PpGqX**OQ<4m@Sa(8vA zT2W1-2X&f&;{1^SLKE3EP5xuM*B)ug#WHFbu6i4mc}=5lj)^r~|}!hL8n6a3nw zIzAB336q#a&;Rq41|e1{5qTK%{Rlu$&!2(_EhC5fAoiEF{bvziWuDgExl z!wx=o{qN#%0YMc!{Nk7$sDM4rp}aTx%=tL^>@W|%*0#)P{Asw2x}MdTtcW>X<@V>y z`+dJXz00IF4^+n#eK>Y>unl8RNhZfWyo=p`!fb3@USr*>Q}6l?Yp?>obd}Gu4396f zOev>$sdlTV8`gV!2eX+sniarVVXIN#gXT56|79cX?l9Hg({0B90TrgwP%}LZL8irALW>?bt`CMl_TF#vjI()vvYUdTRK5Cdqim`Cg(0b zxi0hdXH!u$oJKAB)?~D$PDtbM;IxYF7fc9qhsS+|C|&Xc)Ueu_X;9L1S<3M79=P+i zKO6Pp61utC*&ts>tDWC9ZIO3a$f%V#E%G;AQ4{ZX47R%y!?@yC&g09JG7!qDcgi^NMSKSSyZ2f& z=MUrx5{inQhM$Dns_W)^?tE#rC|oW~z2J>YFrsi(Mi06({cq^^x%%G_*>Kcq1qR``lDt z`w-sW^ITkXfhAVoT2A7g=RBDPX0s0Mq7u&@zOa$(!iF!pNLBTNBXVpfmUiI`UnYsL!xzNEn z7aD`MkJI*ICC-yAm|zvjEoPycf=V|7Htrk+j+uT{#?`OiK)=#j&=K!&`6P3EB7VW{ zQrY2p74?mCX!{5o`*rqG|BN&0Bkws?j#Fai($EGyvm+yDX_K@qrA!WzG?B-w@;$l& zf5$4kFtBWESXAqt@nT>``O*%>BmGrkhMfDv48@~Y#r39AsBlfvcQzT2&=Hd4t}HI7 z#9VU8=?L|!L>nyOU)R%msQ+%Z102W4s&Y9^LSI3EU$H(C(=3PK{ z5DzycXmFeah2>MR8&%87TXvP~y&a%VJ4mADF7u35SEnyv@XY7GDyox;MRA#VkEmdW zUIXw;hmG=wN!~}7&a%;pN`|yYhVO=7s5FbOPVJz58u+hD%cc@D-V52aNjk{8hNC@m zEGf{LR-^=Oq?dpFGPmi+_Ge6-TSr}+JCg#X4Cyez1B=b!$(Izm3TPyEj7b4C8>Ni7 z>Lr#iej1I`@?X`KVBztKrWOZ_MVMO|FE#*Ow0AdFYrMLPqrj`I2Rjsn12t+cU#$6z z55zd9DBc)<{slfw;7Li;-0hOB4HB*VUxyiWSB{7nK1RzS7ON0ZFF8;%dK*v30LG-L zh#y8s1{QSAz_)DET#0<6^+72t9QL|8Ob6i-F7- zF(;-JecWCE^V>wrngx|AZFiE&xz?m{?SB|a^6L4XUMi@!@|XZeQ=jW;nM0c@Pz%XPrY@f-NMH=$bz8sHP8IO#wJvwZs-Iq#Dl zw8!hT4B;nJkxaa7LPFaTinv-aVwC}Tl^r(Rz~R22u;14%FD-Gpd<&uRJ?&6QDL&X| zD2`502OkV6_Rf8j-?@_U?xN>L9GdkfwlvYlng!_Ag6x(LOLSesF}*S|fB-%I`i(lSIk|lAjm*7|?Z8ss+7KWe zNQ-~OPNu`?m6nzjkTo2zr}U3o4(b!mhKRgvJ=G=TgBK5e8@Nt@jn&{FzFoFK#;cP6 z$2gSB{-FPRS|?cm5M}hOQyyp2P9b6KZVNhFgF&Qx=?Pn|MfQ$9%B#DH9!sg4?}sa> z`rZC`>Q!e@MK`c1fEE?P?CMuN+PEhKlY=F3<@u&;$!j3Xy__;CkNtjNhq*!0m zcjR2bs1@BOYLfHZLgypdNyANJRj3VId0OX!qlLX9!rinSv$1B*{?|yZt?62=Vs2sf zq98r%^F@Darr?I(kE*@B|M-ss8zl!Br^|088j6r7?@olO-)2TLSR1=T(@qay?poTG zs0|zo`SJ;;3}|1E>;RV!QYu{yQ+nd(0rCn9{Gt*jueA*?t+EO2 zX*-*Z+Vg(eA&g*^wBi01O`bE~YCxe1hS*YExQ%%_Y2xWgt+2#d2x;(fAvH$o7>wUH7IE@?gEEMEm8MyufR~_ggaFmbX)_~@YyrxrkR*=@xgH7g^WQh_=KU!Hy(ak`6R0gufvi-@>2~xOu1)fq z33BlN@vvG7m;b~lUo_}H^8*)*r?}u&YKIwCm<1aTat{ueW*gnaa9uweUaI z%6nDjPv&9c6wM0r9RijFs^SZ>PzK>26^5C&aC^>`3(xs#WD|=kZ~)10`je?+zqI1K zwTEyF2P;^OxA}43fV9~~C}#T;iYbeYnXj{tH4)#|`PsK@$+#hXt?p=<>XoJ?%ijZ( zu>|75^bI7x#}gbNT8Z?6Ik@v3!`nUX2Q0YNq?H{}4RGaYWar;tdilqk#f>s&T})*^ zt3r}xAEQ4e-qp}c4?r(SQ;lZCXZ$8Tb|Ka=nJuA|7`&UO#Umv*H8&$Vn*<7lc!aE&= zK~NRe2cP;6tp9q;cW}&_G5eU9m6f%6?)%~P!dQ*9YK2L&H*rkiytME+0;98qaYRr$ zOr|?^7KoH~bkGT%yb+N5Yj}2h7Y=o*0RsJX3W$JBwE6*PIBCmSH0A~ykDO?nWYLcx zOvQTFcsf@4@aIeay&=UihAOc0$xbid;_gxDhV}?m!hN;jlAFfy zLt%zAy|&pw<78sA)YMPXVagycWQ*V0c!kkMR=p(z=((Dm;|j5W&5uEC4atI{>|n!! zf&#EQOe0(Bc!BA>I9D#xzb&B|-D(7zb$@&R>4%)hFNwf@h=WHKXw=biHU_^(mr
  • - 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 z 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

    _C+ieGX(L%O3mzQpSGo#_{q^tK+VLG<{w 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ﻶ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 z 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 K0axJ>a_UbM+vFGk literal 0 HcmV?d00001 diff --git a/docs/sections/learn/advanced/structured_generation.md b/docs/sections/learn/advanced/structured_generation.md index c0ba743ad..579427434 100644 --- a/docs/sections/learn/advanced/structured_generation.md +++ b/docs/sections/learn/advanced/structured_generation.md @@ -8,6 +8,14 @@ The [`LLM`][distilabel.llms.LLM] has an argument named `structured_output`[^1] that determines how we can generate structured outputs with it, let's see an example using [`LlamaCppLLM`][distilabel.llms.LlamaCppLLM]. +!!! Note + + For `outlines` integration to work you may need to install the corresponding dependencies: + + ```bash + pip install distilabel[outlines] + ``` + ### JSON We will start with a JSON example, where we initially define a `pydantic.BaseModel` schema to guide the generation of the structured output. @@ -101,7 +109,7 @@ if match: These were some simple examples, but one can see the options this opens. -!!! NOTE +!!! Tip A full pipeline example can be seen in the following script: [`examples/structured_generation_with_outlines.py`](../../pipeline_samples/examples/index.md#llama-cpp-with-outlines) @@ -119,6 +127,72 @@ These were some simple examples, but one can see the options this opens. curl -L -o ~/Downloads/openhermes-2.5-mistral-7b.Q4_K_M.gguf https://huggingface.co/TheBloke/OpenHermes-2.5-Mistral-7B-GGUF/resolve/main/openhermes-2.5-mistral-7b.Q4_K_M.gguf ``` +## Instructor + +When working with model providers behind an API, there's no direct way of accesing the internal logit processor as `outlines` does, but thanks to [`instructor`](https://python.useinstructor.com/) we can generate structured output from LLM providers. We have integrated `instructor` to deal with the [`AsyncLLM`][distilabel.llms.AsyncLLM], so you can work with the following LLMs: [`OpenAILLM`][distilabel.llms.OpenAILLM], [`AzureOpenAILLM`][distilabel.llms.AzureOpenAILLM], [`CohereLLM`][distilabel.llms.CohereLLM], [`GroqLLM`][distilabel.llms.GroqLLM], [`LiteLLM`][distilabel.llms.LiteLLM] and [`MistralLLM`][distilabel.llms.MistralLLM]. + +`instructor` works with `pydantic.BaseModel` objects internally but in `distilabel` the examples generated would result in the string representation of them, from which the `BaseModel` object can be regenerated. + +!!! Note + For `instructor` integration to work you may need to install the corresponding dependencies: + + ```bash + pip install distilabel[instructor] + ``` + +!!! Note + Take a look at [`InstructorStructuredOutputType`][distilabel.steps.tasks.structured_outputs.instructor.InstructorStructuredOutputType] to see the expected format + of the `structured_output` dict variable. + +The following is the same example you can see with `outlines`'s `JSON` section for comparison purposes. + +```python +from pydantic import BaseModel + +class User(BaseModel): + name: str + last_name: str + id: int +``` + +And then we provide that schema to the `structured_output` argument of the LLM: + +!!! Note + In this example we are using *open-mixtral-8x22b*, keep in mind not all the models work with the function calling functionality required for this example to work. + +```python +from distilabel.llms import MistralLLM + +llm = MistralLLM( + model="open-mixtral-8x22b", + structured_output={"schema": User} +) +llm.load() +``` + +And we are ready to pass our instruction as usual: + +```python +import json + +result = llm.generate( + [[{"role": "user", "content": "Create a user profile for the following marathon"}]], + max_new_tokens=256 +) + +data = json.loads(result[0][0]) +data +# {'name': 'John', 'last_name': 'Doe', 'id': 12345} +User(**data) +# User(name='John', last_name='Doe', id=12345) +``` + +We get back a Python dictionary (formatted as a string) that we can parse using `json.loads`, or validate it directly using the `User`, which is a `pydantic.BaseModel` instance. + +!!! Tip + A full pipeline example can be seen in the following script: + [`examples/structured_generation_with_instructor.py`](../../pipeline_samples/examples/index.md#mistralai-with-instructor) + ## OpenAI JSON OpenAI offers a [JSON Mode](https://platform.openai.com/docs/guides/text-generation/json-mode) to deal with structured output via their API, let's see how to make use of them. The JSON mode instructs the model to always return a JSON object following the instruction required. diff --git a/docs/sections/pipeline_samples/examples/index.md b/docs/sections/pipeline_samples/examples/index.md index 3958fe55c..efa512cfe 100644 --- a/docs/sections/pipeline_samples/examples/index.md +++ b/docs/sections/pipeline_samples/examples/index.md @@ -2,7 +2,7 @@ This section contains different example pipelines that showcase different tasks, maybe you can take inspiration from them. -### [llama.cpp with outlines](#llama-cpp-with-outlines) +### [llama.cpp with `outlines`](#llama-cpp-with-outlines) Generate RPG characters following a `pydantic.BaseModel` with `outlines` in `distilabel`. @@ -21,3 +21,42 @@ Generate RPG characters following a `pydantic.BaseModel` with `outlines` in `dis ```python title="structured_generation_with_outlines.py" --8<-- "examples/structured_generation_with_outlines.py" ``` + + +### [MistralAI with `instructor`](#mistralai-with-instructor) + +Answer instructions with knowledge graphs defined as `pydantic.BaseModel` objects using `instructor` in `distilabel`. + +??? Example "See example" + + This script makes use of [`MistralLLM`][distilabel.llms.mistral.MistralLLM] and the structured output capabilities thanks to [`instructor`](https://python.useinstructor.com/) to generate knowledge graphs from complex topics. + + This example is translated from this [awesome example](https://python.useinstructor.com/examples/knowledge_graph/) from `instructor` cookbook. + + ??? Run + + ```python + python examples/structured_generation_with_instructor.py + ``` + + ```python title="structured_generation_with_instructor.py" + --8<-- "examples/structured_generation_with_instructor.py" + ``` + + ??? "Visualizing the graphs" + + Want to see how to visualize the graphs? You can test it using the following script. Generate some samples on your own and take a look: + + !!! NOTE + + This example uses graphviz to render the graph, you can install with `pip` in the following way: + + ```console + pip install graphviz + ``` + + ```python + python examples/draw_kg.py 2 # You can pass 0,1,2 to visualize each of the samples. + ``` + + ![Knowledge graph figure](../../../assets/images/sections/examples/knowledge-graph-example.png) diff --git a/examples/draw_kg.py b/examples/draw_kg.py new file mode 100644 index 000000000..8d45e40b8 --- /dev/null +++ b/examples/draw_kg.py @@ -0,0 +1,82 @@ +# Copyright 2023-present, Argilla, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from typing import Any, Dict, List, Union + +from graphviz import Digraph +from pydantic import BaseModel, Field + + +class Node(BaseModel): + id: int + label: str + color: str + + +class Edge(BaseModel): + source: int + target: int + label: str + color: str = "black" + + +class KnowledgeGraph(BaseModel): + nodes: List[Node] = Field(..., default_factory=list) + edges: List[Edge] = Field(..., default_factory=list) + + +def visualize_knowledge_graph(kg: KnowledgeGraph): + dot = Digraph(comment="Knowledge Graph") + + # Add nodes + for node in kg.nodes: + dot.node(str(node.id), node.label, color=node.color) + + # Add edges + for edge in kg.edges: + dot.edge( + str(edge.source), + str(edge.target), + label=edge.label, + color=edge.color or "black", + ) + + # Render the graph + dot.render("knowledge_graph.gv", view=True) + + +def create_knowledge_graph(data: str) -> Union[KnowledgeGraph, None]: + data: Dict[str, Any] = json.loads(data) + + nodes = [Node(**node) for node in data["nodes"]] + edges = [] + for edge in data["edges"]: + if edge.get("color") is None: + edge["color"] = "black" + edges.append(Edge(**edge)) + + return KnowledgeGraph(nodes=nodes, edges=edges) + + +if __name__ == "__main__": + import sys + + args = sys.argv[1:] + + from datasets import load_dataset + + ds = load_dataset("distilabel-internal-testing/knowledge_graphs", split="train") + graphs = [create_knowledge_graph(g) for g in ds["generation"]] + visualize_knowledge_graph(graphs[int(args[0])]) diff --git a/examples/structured_generation_with_instructor.py b/examples/structured_generation_with_instructor.py new file mode 100644 index 000000000..48082886f --- /dev/null +++ b/examples/structured_generation_with_instructor.py @@ -0,0 +1,87 @@ +# Copyright 2023-present, Argilla, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import List + +from distilabel.llms import MistralLLM +from distilabel.pipeline import Pipeline +from distilabel.steps import LoadDataFromDicts +from distilabel.steps.tasks import TextGeneration +from pydantic import BaseModel, Field + + +class Node(BaseModel): + id: int + label: str + color: str + + +class Edge(BaseModel): + source: int + target: int + label: str + color: str = "black" + + +class KnowledgeGraph(BaseModel): + nodes: List[Node] = Field(..., default_factory=list) + edges: List[Edge] = Field(..., default_factory=list) + + +with Pipeline( + name="Knowledge-Graphs", + description=( + "Generate knowledge graphs to answer questions, this type of dataset can be used to " + "steer a model to answer questions with a knowledge graph." + ), +) as pipeline: + sample_questions = [ + "Teach me about quantum mechanics", + "Who is who in The Simpsons family?", + "Tell me about the evolution of programming languages", + ] + + load_dataset = LoadDataFromDicts( + name="load_instructions", + data=[ + { + "system_prompt": "You are a knowledge graph expert generator. Help me understand by describing everything as a detailed knowledge graph.", + "instruction": f"{question}", + } + for question in sample_questions + ], + ) + + text_generation = TextGeneration( + name="knowledge_graph_generation", + llm=MistralLLM( + model="open-mixtral-8x22b", structured_output={"schema": KnowledgeGraph} + ), + input_batch_size=8, + output_mappings={"model_name": "generation_model"}, + ) + load_dataset >> text_generation + + +if __name__ == "__main__": + distiset = pipeline.run( + parameters={ + text_generation.name: { + "llm": {"generation_kwargs": {"max_new_tokens": 2048}} + } + }, + use_cache=False, + ) + + distiset.push_to_hub("distilabel-internal-testing/knowledge_graphs") diff --git a/pyproject.toml b/pyproject.toml index 8883eb0bc..79bad9636 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ cohere = ["cohere >= 5.2.0"] groq = ["groq >= 0.4.1"] hf-inference-endpoints = ["huggingface_hub >= 0.19.0"] hf-transformers = ["transformers >= 4.34.1", "torch >= 2.0.0"] +instructor = ["instructor >= 1.2.3"] litellm = ["litellm >= 1.30.0"] llama-cpp = ["llama-cpp-python >= 0.2.0"] mistralai = ["mistralai >= 0.1.0"] diff --git a/src/distilabel/llms/anthropic.py b/src/distilabel/llms/anthropic.py index f472aca66..fb4f6dc03 100644 --- a/src/distilabel/llms/anthropic.py +++ b/src/distilabel/llms/anthropic.py @@ -59,6 +59,8 @@ class AnthropicLLM(AsyncLLM): to `6`. http_client: if provided, an alternative HTTP client to use for calling Anthropic API. Defaults to `None`. + structured_output: a dictionary containing the structured output configuration configuration + using `instructor`. Defaults to None. _api_key_env_var: the name of the environment variable to use for the API key. It is meant to be used internally. _aclient: the `AsyncAnthropic` client to use for the Anthropic API. It is meant @@ -143,6 +145,15 @@ def load(self) -> None: http_client=self.http_client, max_retries=self.max_retries, ) + if self.structured_output: + result = self._prepare_structured_output( + structured_output=self.structured_output, + client=self._aclient, + framework="anthropic", + ) + self._aclient = result.get("client") + if structured_output := result.get("structured_output"): + self.structured_output = structured_output @property def model_name(self) -> str: @@ -174,22 +185,32 @@ async def agenerate( # type: ignore """ from anthropic._types import NOT_GIVEN - completion = await self._aclient.messages.create( # type: ignore - model=self.model, - system=( + kwargs = { + "messages": input, # type: ignore + "model": self.model, + "system": ( input.pop(0)["content"] if input and input[0]["role"] == "system" else NOT_GIVEN ), - messages=input, # type: ignore - max_tokens=max_tokens, - stream=False, - stop_sequences=NOT_GIVEN if stop_sequences is None else stop_sequences, - temperature=temperature, - top_p=NOT_GIVEN if top_p is None else top_p, - top_k=NOT_GIVEN if top_k is None else top_k, - ) + "max_tokens": max_tokens, + "stream": False, + "stop_sequences": NOT_GIVEN if stop_sequences is None else stop_sequences, + "temperature": temperature, + "top_p": NOT_GIVEN if top_p is None else top_p, + "top_k": NOT_GIVEN if top_k is None else top_k, + } + + if self.structured_output: + kwargs = self._prepare_kwargs(kwargs, self.structured_output) + generations = [] + + completion = await self._aclient.messages.create(**kwargs) # type: ignore + if self.structured_output: + generations.append(completion.model_dump_json()) + return generations + if (content := completion.content[0].text) is None: self._logger.warning( f"Received no response using Anthropic client (model: '{self.model}')." diff --git a/src/distilabel/llms/azure.py b/src/distilabel/llms/azure.py index 58d455d65..3fa1f7cde 100644 --- a/src/distilabel/llms/azure.py +++ b/src/distilabel/llms/azure.py @@ -14,6 +14,7 @@ import os from typing import TYPE_CHECKING, Optional +from unittest.mock import patch from pydantic import Field, PrivateAttr, SecretStr from typing_extensions import override @@ -68,7 +69,10 @@ class AzureOpenAILLM(OpenAILLM): @override def load(self) -> None: """Loads the `AsyncAzureOpenAI` client to benefit from async requests.""" - super().load() + # This is a workaround to avoid the `OpenAILLM` calling the _prepare_structured_output + # in the load method before we have the proper client. + with patch("OpenAILLM._prepare_structured_output", lambda x: x): + super().load() try: from openai import AsyncAzureOpenAI @@ -93,3 +97,6 @@ def load(self) -> None: max_retries=self.max_retries, # type: ignore timeout=self.timeout, ) + + if self.structured_output: + self._prepare_structured_output(self.structured_output) diff --git a/src/distilabel/llms/base.py b/src/distilabel/llms/base.py index 5bab1c603..b61c72cf0 100644 --- a/src/distilabel/llms/base.py +++ b/src/distilabel/llms/base.py @@ -33,6 +33,9 @@ if TYPE_CHECKING: from distilabel.llms.typing import GenerateOutput, HiddenState from distilabel.mixins.runtime_parameters import RuntimeParametersNames + from distilabel.steps.tasks.structured_outputs.instructor import ( + InstructorStructuredOutputType, + ) from distilabel.steps.tasks.structured_outputs.outlines import StructuredOutputType from distilabel.steps.tasks.typing import ChatType from distilabel.utils.docstring import Docstring @@ -300,3 +303,83 @@ def __del__(self) -> None: return if self.event_loop is not None: self.event_loop.close() + + @staticmethod + def _prepare_structured_output( + structured_output: "InstructorStructuredOutputType", + client: Any = None, + framework: Optional[str] = None, + ) -> Dict[str, Union[str, Any]]: + """Wraps the client and updates the schema to work store it internally as a json schema. + + Args: + structured_output: The configuration dict to prepare the structured output. + client: The client to wrap to generate structured output. Implemented to work + with `instructor`. + framework: The name of the framework. + + Returns: + A dictionary containing the wrapped client and the schema to update the structured_output + variable in case it is a pydantic model. + """ + from distilabel.steps.tasks.structured_outputs.instructor import ( + prepare_instructor, + ) + + result = {} + client = prepare_instructor( + client, + mode=structured_output.get("mode"), + framework=framework, + ) + result["client"] = client + + schema = structured_output.get("schema") + if not schema: + raise ValueError( + f"The `structured_output` argument must contain a schema: {structured_output}" + ) + if issubclass(schema, BaseModel): + # We want a json schema for the serialization, but instructor wants a pydantic BaseModel. + structured_output["schema"] = schema.model_json_schema() + result["structured_output"] = structured_output + + return result + + @staticmethod + def _prepare_kwargs( + arguments: Dict[str, Any], structured_output: Dict[str, Any] + ) -> Dict[str, Any]: + """Helper method to update the kwargs with the structured output configuration, + used in case they are defined. + + Args: + arguments: The arguments that would be passed to the LLM as **kwargs. + to update with the structured output configuration. + structured_outputs: The structured output configuration to update the arguments. + + Returns: + kwargs updated with the special arguments used by `instructor`. + """ + # We can deal with json schema or BaseModel, but we need to convert it to a BaseModel + # for the Instructor client. + schema = structured_output.get("schema") + if not issubclass(schema, BaseModel): + from distilabel.steps.tasks.structured_outputs.utils import ( + json_schema_to_model, + ) + + try: + schema = json_schema_to_model(schema) + except Exception as e: + raise ValueError( + f"Failed to convert the schema to a pydantic model, the model is too complex currently: {e}" + ) from e + + arguments.update( + **{ + "response_model": schema, + "max_retries": structured_output.get("max_retries", 1), + }, + ) + return arguments diff --git a/src/distilabel/llms/cohere.py b/src/distilabel/llms/cohere.py index b7ecafcac..a49b203f3 100644 --- a/src/distilabel/llms/cohere.py +++ b/src/distilabel/llms/cohere.py @@ -38,6 +38,7 @@ from distilabel.llms.typing import GenerateOutput + _COHERE_API_KEY_ENV_VAR_NAME = "COHERE_API_KEY" @@ -54,6 +55,9 @@ class CohereLLM(AsyncLLM): to `120`. client_name: the name of the client to use for the API requests. Defaults to `"distilabel"`. + structured_output: a dictionary containing the structured output configuration configuration + using `instructor`. You can take a look at the dictionary structure in + `InstructorStructuredOutputType` from `distilabel.steps.tasks.structured_outputs.instructor`. _ChatMessage: the `ChatMessage` class from the `cohere` package. _aclient: the `AsyncClient` client from the `cohere` package. @@ -117,6 +121,16 @@ def load(self) -> None: timeout=self.timeout, ) + if self.structured_output: + result = self._prepare_structured_output( + structured_output=self.structured_output, + client=self._aclient, + framework="cohere", + ) + self._aclient = result.get("client") + if structured_output := result.get("structured_output"): + self.structured_output = structured_output + def _format_chat_to_cohere( self, input: "ChatType" ) -> Tuple[Union[str, None], List["ChatMessage"], str]: @@ -192,21 +206,28 @@ async def agenerate( # type: ignore """ system, chat_history, message = self._format_chat_to_cohere(input) - response = await self._aclient.chat( # type: ignore - message=message, - model=self.model, - preamble=system, - chat_history=chat_history, - temperature=temperature, - max_tokens=max_tokens, - k=k, - p=p, - seed=seed, - stop_sequences=stop_sequences, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty, - raw_prompting=raw_prompting, - ) + kwargs = { + "message": message, + "model": self.model, + "preamble": system, + "chat_history": chat_history, + "temperature": temperature, + "max_tokens": max_tokens, + "k": k, + "p": p, + "seed": seed, + "stop_sequences": stop_sequences, + "frequency_penalty": frequency_penalty, + "presence_penalty": presence_penalty, + "raw_prompting": raw_prompting, + } + if self.structured_output: + kwargs = self._prepare_kwargs(kwargs, self.structured_output) + + response = await self._aclient.chat(**kwargs) # type: ignore + + if self.structured_output: + return response.model_dump_json() if (text := response.text) == "": self._logger.warning( diff --git a/src/distilabel/llms/groq.py b/src/distilabel/llms/groq.py index f7fbda1dc..4905f8283 100644 --- a/src/distilabel/llms/groq.py +++ b/src/distilabel/llms/groq.py @@ -28,6 +28,7 @@ if TYPE_CHECKING: from groq import AsyncGroq + _GROQ_API_BASE_URL_ENV_VAR_NAME = "GROQ_BASE_URL" _GROQ_API_KEY_ENV_VAR_NAME = "GROQ_API_KEY" @@ -45,6 +46,9 @@ class GroqLLM(AsyncLLM): failing. Defaults to `2`. timeout: the maximum time in seconds to wait for a response from the API. Defaults to `120`. + structured_output: a dictionary containing the structured output configuration configuration + using `instructor`. You can take a look at the dictionary structure in + `InstructorStructuredOutputType` from `distilabel.steps.tasks.structured_outputs.instructor`. _api_key_env_var: the name of the environment variable to use for the API key. _aclient: the `AsyncGroq` client from the `groq` package. @@ -109,6 +113,16 @@ def load(self) -> None: timeout=self.timeout, ) + if self.structured_output: + result = self._prepare_structured_output( + structured_output=self.structured_output, + client=self._aclient, + framework="groq", + ) + self._aclient = result.get("client") + if structured_output := result.get("structured_output"): + self.structured_output = structured_output + @property def model_name(self) -> str: """Returns the model name used for the LLM.""" @@ -142,17 +156,25 @@ async def agenerate( # type: ignore References: - https://console.groq.com/docs/text-chat """ - completion = await self._aclient.chat.completions.create( # type: ignore - messages=input, # type: ignore - model=self.model, - seed=seed, # type: ignore - temperature=temperature, - max_tokens=max_new_tokens, - top_p=top_p, - stream=False, - stop=stop, - ) + kwargs = { + "messages": input, # type: ignore + "model": self.model, + "seed": seed, + "temperature": temperature, + "max_tokens": max_new_tokens, + "top_p": top_p, + "stream": False, + "stop": stop, + } + if self.structured_output: + kwargs = self._prepare_kwargs(kwargs, self.structured_output) + generations = [] + completion = await self._aclient.chat.completions.create(**kwargs) # type: ignore + if self.structured_output: + generations.append(completion.model_dump_json()) + return generations + for choice in completion.choices: if (content := choice.message.content) is None: self._logger.warning( # type: ignore diff --git a/src/distilabel/llms/litellm.py b/src/distilabel/llms/litellm.py index 1b0add14a..d3660c5ea 100644 --- a/src/distilabel/llms/litellm.py +++ b/src/distilabel/llms/litellm.py @@ -33,6 +33,9 @@ class LiteLLM(AsyncLLM): model: the model name to use for the LLM e.g. "gpt-3.5-turbo" or "mistral/mistral-large", etc. verbose: whether to log the LiteLLM client's logs. Defaults to `False`. + structured_output: a dictionary containing the structured output configuration configuration + using `instructor`. You can take a look at the dictionary structure in + `InstructorStructuredOutputType` from `distilabel.steps.tasks.structured_outputs.instructor`. Runtime parameters: - `verbose`: whether to log the LiteLLM client's logs. Defaults to `False`. @@ -69,6 +72,16 @@ def load(self) -> None: continue logging.getLogger(key).setLevel(logging.CRITICAL) + if self.structured_output: + result = self._prepare_structured_output( + structured_output=self.structured_output, + client=self._aclient, + framework="litellm", + ) + self._aclient = result.get("client") + if structured_output := result.get("structured_output"): + self.structured_output = structured_output + @property def model_name(self) -> str: """Returns the model name used for the LLM.""" @@ -141,34 +154,40 @@ async def agenerate( # type: ignore """ import litellm + kwargs = { + "model": self.model, + "messages": input, + "n": num_generations, + "functions": functions, + "function_call": function_call, + "temperature": temperature, + "top_p": top_p, + "stream": False, + "stop": stop, + "max_tokens": max_tokens, + "presence_penalty": presence_penalty, + "frequency_penalty": frequency_penalty, + "logit_bias": logit_bias, + "user": user, + "metadata": metadata, + "api_base": api_base, + "api_version": api_version, + "api_key": api_key, + "model_list": model_list, + "mock_response": mock_response, + "force_timeout": force_timeout, + "custom_llm_provider": custom_llm_provider, + } + if self.structured_output: + kwargs = self._prepare_kwargs(kwargs, self.structured_output) + async def _call_aclient_until_n_choices() -> List["Choices"]: choices = [] while len(choices) < num_generations: - completion = await self._aclient( # type: ignore - model=self.model, - messages=input, - n=num_generations, - functions=functions, - function_call=function_call, - temperature=temperature, - top_p=top_p, - stream=False, - stop=stop, - max_tokens=max_tokens, - presence_penalty=presence_penalty, - frequency_penalty=frequency_penalty, - logit_bias=logit_bias, - user=user, - metadata=metadata, - api_base=api_base, - api_version=api_version, - api_key=api_key, - model_list=model_list, - mock_response=mock_response, - force_timeout=force_timeout, - custom_llm_provider=custom_llm_provider, - ) - choices.extend(completion.choices) + completion = await self._aclient(**kwargs) # type: ignore + if not self.structured_output: + completion = completion.choices + choices.extend(completion) return choices # litellm.drop_params is used to en/disable sending **kwargs parameters to the API if they cannot be used @@ -183,6 +202,11 @@ async def _call_aclient_until_n_choices() -> List["Choices"]: raise e generations = [] + + if self.structured_output: + generations.append([choice.model_dump_json() for choice in choices]) + return generations + for choice in choices: if (content := choice.message.content) is None: self._logger.warning( diff --git a/src/distilabel/llms/mistral.py b/src/distilabel/llms/mistral.py index d05d9d3f6..dd96cae91 100644 --- a/src/distilabel/llms/mistral.py +++ b/src/distilabel/llms/mistral.py @@ -45,6 +45,9 @@ class MistralLLM(AsyncLLM): timeout: the maximum time in seconds to wait for a response. Defaults to `120`. max_concurrent_requests: the maximum number of concurrent requests to send. Defaults to `64`. + structured_output: a dictionary containing the structured output configuration configuration + using `instructor`. You can take a look at the dictionary structure in + `InstructorStructuredOutputType` from `distilabel.steps.tasks.structured_outputs.instructor`. _api_key_env_var: the name of the environment variable to use for the API key. It is meant to be used internally. _aclient: the `MistralAsyncClient` to use for the Mistral API. It is meant to be used internally. @@ -107,6 +110,16 @@ def load(self) -> None: max_concurrent_requests=self.max_concurrent_requests, ) + if self.structured_output: + result = self._prepare_structured_output( + structured_output=self.structured_output, + client=self._aclient, + framework="mistral", + ) + self._aclient = result.get("client") + if structured_output := result.get("structured_output"): + self.structured_output = structured_output + @property def model_name(self) -> str: """Returns the model name used for the LLM.""" @@ -134,14 +147,26 @@ async def agenerate( # type: ignore Returns: A list of lists of strings containing the generated responses for each input. """ - completion = await self._aclient.chat( # type: ignore - messages=input, - model=self.model, - temperature=temperature, - max_tokens=max_new_tokens, - top_p=top_p, - ) + kwargs = { + "messages": input, # type: ignore + "model": self.model, + "max_tokens": max_new_tokens, + "temperature": temperature, + "top_p": top_p, + } generations = [] + if self.structured_output: + kwargs = self._prepare_kwargs(kwargs, self.structured_output) + # TODO: This should work just with the _aclient.chat method, but it's not working. + # We need to check instructor and see if we can create a PR. + completion = await self._aclient.chat.completions.create(**kwargs) + else: + completion = await self._aclient.chat(**kwargs) + + if self.structured_output: + generations.append(completion.model_dump_json()) + return generations + for choice in completion.choices: if (content := choice.message.content) is None: self._logger.warning( diff --git a/src/distilabel/llms/openai.py b/src/distilabel/llms/openai.py index 7314f7c74..6dedc2387 100644 --- a/src/distilabel/llms/openai.py +++ b/src/distilabel/llms/openai.py @@ -45,8 +45,9 @@ class OpenAILLM(AsyncLLM): failing. Defaults to `6`. timeout: the maximum time in seconds to wait for a response from the API. Defaults to `120`. - structured_output: a dictionary containing the structured output configuration or if more - fine-grained control is needed, an instance of `OutlinesStructuredOutput`. Defaults to None. + structured_output: a dictionary containing the structured output configuration configuration + using `instructor`. You can take a look at the dictionary structure in + `InstructorStructuredOutputType` from `distilabel.steps.tasks.structured_outputs.instructor`. Runtime parameters: - `base_url`: the base URL to use for the OpenAI API requests. Defaults to `None`. @@ -110,6 +111,16 @@ def load(self) -> None: timeout=self.timeout, ) + if self.structured_output: + result = self._prepare_structured_output( + structured_output=self.structured_output, + client=self._aclient, + framework="openai", + ) + self._aclient = result.get("client") + if structured_output := result.get("structured_output"): + self.structured_output = structured_output + @property def model_name(self) -> str: """Returns the model name used for the LLM.""" @@ -162,20 +173,29 @@ async def agenerate( # type: ignore f"Invalid response format '{response_format}'. Must be either 'text' or 'json'." ) - completion = await self._aclient.chat.completions.create( # type: ignore - messages=input, # type: ignore - model=self.model, - max_tokens=max_new_tokens, - n=num_generations, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty, - temperature=temperature, - top_p=top_p, - stop=stop, - timeout=50, - response_format={"type": response_format}, - ) + kwargs = { + "messages": input, # type: ignore + "model": self.model, + "max_tokens": max_new_tokens, + "n": num_generations, + "frequency_penalty": frequency_penalty, + "presence_penalty": presence_penalty, + "temperature": temperature, + "top_p": top_p, + "stop": stop, + "timeout": 50, + "response_format": {"type": response_format}, + } + if self.structured_output: + kwargs = self._prepare_kwargs(kwargs, self.structured_output) + generations = [] + completion = await self._aclient.chat.completions.create(**kwargs) + + if self.structured_output: + generations.append(completion.model_dump_json()) + return generations + for choice in completion.choices: if (content := choice.message.content) is None: self._logger.warning( # type: ignore diff --git a/src/distilabel/pipeline/local.py b/src/distilabel/pipeline/local.py index 98c5f00a3..a88f26381 100644 --- a/src/distilabel/pipeline/local.py +++ b/src/distilabel/pipeline/local.py @@ -691,11 +691,6 @@ def _stop( if _STOP_CALLED: global _STOP_CALLS _STOP_CALLS += 1 - # if _STOP_CALLS == 1: - # self._logger.warning( - # "🛑 Stop has already been called. Ignoring subsequent calls and waiting" - # " for the pipeline to finish..." - # ) if _STOP_CALLS == 1: self._logger.warning( "🛑 Press again to force the pipeline to stop." diff --git a/src/distilabel/steps/tasks/base.py b/src/distilabel/steps/tasks/base.py index b2a473487..120f2758f 100644 --- a/src/distilabel/steps/tasks/base.py +++ b/src/distilabel/steps/tasks/base.py @@ -25,6 +25,7 @@ StepInput, _Step, ) +from distilabel.steps.constants import DISTILABEL_METADATA_KEY from distilabel.utils.dicts import combine_dicts if TYPE_CHECKING: @@ -33,9 +34,6 @@ from distilabel.steps.typing import StepOutput -DISTILABEL_METADATA_KEY = "distilabel_metadata" - - class _Task(_Step, ABC): """_Task is an abstract class that implements the `_Step` interface and adds the `format_input` and `format_output` methods to format the inputs and outputs of the diff --git a/src/distilabel/steps/tasks/structured_outputs/instructor.py b/src/distilabel/steps/tasks/structured_outputs/instructor.py new file mode 100644 index 000000000..e9ec1ea43 --- /dev/null +++ b/src/distilabel/steps/tasks/structured_outputs/instructor.py @@ -0,0 +1,140 @@ +# Copyright 2023-present, Argilla, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import importlib.util +from typing import ( + TYPE_CHECKING, + Callable, + Literal, + Optional, + Tuple, + Type, + TypeAlias, + TypedDict, + Union, + get_args, +) + +from pydantic import BaseModel + +if TYPE_CHECKING: + import instructor + from anthropic import AsyncAnthropic + from cohere import AsyncClient as AsyncCohere + from groq import AsyncGroq + from mistralai.async_client import MistralAsyncClient + from openai import AsyncAzureOpenAI, AsyncOpenAI + + +InstructorFrameworks = Literal[ + "openai", "azure_openai", "anthropic", "cohere", "groq", "litellm", "mistral" +] +"""Available frameworks for the structured output configuration with `instructor`. """ + +InstructorAvailableClients: TypeAlias = Union[ + "AsyncAnthropic", + "AsyncAzureOpenAI", + "AsyncCohere", + "AsyncGroq", + "AsyncOpenAI", + "MistralAsyncClient", +] +"""Available clients that can be wrapped with `instructor`. """ + + +class InstructorStructuredOutputType(TypedDict): + """TypedDict to represent the structured output configuration from `instructor`.""" + + schema: Type[BaseModel] + """The schema to use for the structured output, a `pydantic.BaseModel` class. """ + mode: Optional["instructor.Mode"] + """Generation mode. Take a look at `instructor.Mode` for more information, if not informed it will + be determined automatically. """ + max_retries: int + """Number of times to reask the model in case of error, if not set will default to the model's default. """ + + +def _client_patcher(framework: InstructorFrameworks) -> Tuple[Callable, str]: + """Helper function to return the appropriate instructor client for the given framework. + + Args: + framework: The framework to use for the instructor client. + + Raises: + ValueError: If the framework is not one of the available frameworks. + + Returns: + Tuple of Callable and string, with the builder of the client patch and the + default mode to use. + """ + import instructor + + if framework in {"openai", "azure_openai"}: + patch = instructor.from_openai, instructor.Mode.TOOLS + elif framework == "anthropic": + patch = instructor.from_anthropic, instructor.Mode.ANTHROPIC_JSON + elif framework == "litellm": + patch = instructor.from_litellm, instructor.Mode.TOOLS + elif framework == "mistral": + patch = instructor.from_mistral, instructor.Mode.MISTRAL_TOOLS + elif framework == "cohere": + patch = instructor.from_cohere, instructor.Mode.COHERE_TOOLS + elif framework == "groq": + patch = instructor.from_groq, instructor.Mode.TOOLS + else: + raise ValueError( + f"Invalid framework '{framework}'. Must be one of {get_args(InstructorFrameworks)}" + ) + + return patch + + +def prepare_instructor( + client: InstructorAvailableClients, + mode: Optional["instructor.Mode"] = None, + framework: Optional[InstructorFrameworks] = None, +) -> "instructor.AsyncInstructor": + """Wraps the given client with the instructor client for the given framework. + + Args: + client: The client to wrap with the instructor client, corresponds to the internal + client we wrap on `LLM`, and one of the implemented in `instructor`. + mode: One of the `instructor.Mode` values. Defaults to None. + framework: The framework corresponding to the client. Defaults to None. + + Raises: + ImportError: If `instructor` is not installed. + ValueError: If the mode is not one of the available modes. + + Returns: + patched_client: The instructor wrapping the original client to be used for + structured generation. + """ + if not importlib.util.find_spec("instructor"): + raise ImportError( + "`instructor` is not installed. Please install it using `pip install instructor`." + ) + import instructor + + builder, default_mode = _client_patcher(framework) + + mode = mode or default_mode + if mode.value not in [m.value for m in instructor.mode.Mode]: + raise ValueError( + f"Invalid mode '{mode}'. Must be one of {[m.value for m in instructor.mode.Mode]}" + ) + + patched_client: instructor.AsyncInstructor = builder(client, mode=mode) + + return patched_client diff --git a/src/distilabel/steps/tasks/structured_outputs/outlines.py b/src/distilabel/steps/tasks/structured_outputs/outlines.py index 087f4913b..7bc53623d 100644 --- a/src/distilabel/steps/tasks/structured_outputs/outlines.py +++ b/src/distilabel/steps/tasks/structured_outputs/outlines.py @@ -31,6 +31,8 @@ from pydantic import BaseModel +from distilabel.steps.tasks.structured_outputs.utils import schema_as_dict + Frameworks = Literal["transformers", "llamacpp", "vllm"] """Available frameworks for the structured output configuration. """ @@ -59,15 +61,6 @@ def model_to_schema(schema: Type[BaseModel]) -> Dict[str, Any]: return json.dumps(schema.model_json_schema()) -def _schema_as_dict(schema: Union[str, Type[BaseModel]]) -> Dict[str, Any]: - """Helper function to obtain the schema and simplify serialization.""" - if type(schema) == type(BaseModel): - return schema.model_json_schema() - elif isinstance(schema, str): - return json.loads(schema) - return schema - - def _get_logits_processor(framework: Frameworks) -> Tuple[Callable, Callable]: """Helper function to return the appropriate logits processor for the given framework.""" if framework == "transformers": @@ -137,7 +130,7 @@ def prepare_guided_output( llm, whitespace_pattern=structured_output.get("whitespace_pattern"), ), - "schema": _schema_as_dict(schema), + "schema": schema_as_dict(schema), } if format == "regex": diff --git a/src/distilabel/steps/tasks/structured_outputs/utils.py b/src/distilabel/steps/tasks/structured_outputs/utils.py new file mode 100644 index 000000000..8bcebcb81 --- /dev/null +++ b/src/distilabel/steps/tasks/structured_outputs/utils.py @@ -0,0 +1,157 @@ +# Copyright 2023-present, Argilla, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from typing import Any, Dict, List, Optional, Type, Union + +from pydantic import BaseModel, Field, create_model + + +def schema_as_dict(schema: Union[str, Type[BaseModel]]) -> Dict[str, Any]: + """Helper function to obtain the schema and simplify serialization.""" + if type(schema) == type(BaseModel): + return schema.model_json_schema() + elif isinstance(schema, str): + return json.loads(schema) + return schema + + +# NOTE: The following functions were copied from: +# https://github.com/pydantic/pydantic/issues/643#issuecomment-1999755873 +# and slightly modified to work with nested models. +# It would be nice to find the original source of this code to give credit. +# Other option would be working with this library: https://github.com/c32168/dyntamic + + +def json_schema_to_model(json_schema: Dict[str, Any]) -> Type[BaseModel]: + """Converts a JSON schema to a `pydantic.BaseModel` class. + + Args: + json_schema: The JSON schema to convert. + + Returns: + A `pydantic.BaseModel` class. + """ + + # Extract the model name from the schema title. + model_name = json_schema.get("title") + if defs := json_schema.get("$defs", None): + # This is done to grab the content of nested classes that need to dereference + # the objects (those should be in a higher level). + pass + + # Extract the field definitions from the schema properties. + field_definitions = { + name: json_schema_to_pydantic_field( + name, prop, json_schema.get("required", []), defs=defs + ) + for name, prop in json_schema.get("properties", {}).items() + } + + # Create the BaseModel class using create_model(). + return create_model(model_name, **field_definitions) + + +def json_schema_to_pydantic_field( + name: str, + json_schema: Dict[str, Any], + required: List[str], + defs: Optional[Dict[str, Any]] = None, +) -> Any: + """Converts a JSON schema property to a `pydantic.Field`. + + Args: + name: The field name. + json_schema: The JSON schema property. + required: The list of required fields. + defs: The definitions of the JSON schema. It's used to dereference nested classes, + so we can grab the original definition from the json schema (it won't + work out of the box with just the reference). + + Returns: + A `pydantic.Field`. + """ + + # NOTE(plaguss): This needs more testing, nested classes need extra work to be converted + # here if we pass a reference to another class it will crash, we have to find the original + # definition and insert it here + # This takes into account single items referred to other classes + if ref := json_schema.get("$ref"): + json_schema = defs.get(ref.split("/")[-1]) + + # This takes into account lists of items referred to other classes + if "items" in json_schema and (ref := json_schema["items"].get("$ref")): + json_schema["items"] = defs.get(ref.split("/")[-1]) + + # Get the field type. + type_ = json_schema_to_pydantic_type(json_schema) + + # Get the field description. + description = json_schema.get("description") + + # Get the field examples. + examples = json_schema.get("examples") + + # Create a Field object with the type, description, and examples. + # The "required" flag will be set later when creating the model. + return ( + type_, + Field( + description=description, + examples=examples, + default=... if name in required else None, + ), + ) + + +def json_schema_to_pydantic_type(json_schema: Dict[str, Any]) -> Any: + """Converts a JSON schema type to a Pydantic type. + + Args: + json_schema: The JSON schema to convert. + + Returns: + A Pydantic type. + """ + type_ = json_schema.get("type") + + if type_ == "string": + type_val = str + elif type_ == "integer": + type_val = int + elif type_ == "number": + type_val = float + elif type_ == "boolean": + type_val = bool + elif type_ == "array": + items_schema = json_schema.get("items") + if items_schema: + item_type = json_schema_to_pydantic_type(items_schema) + type_val = List[item_type] + else: + type_val = List + elif type_ == "object": + # Handle nested models. + properties = json_schema.get("properties") + if properties: + nested_model = json_schema_to_model(json_schema) + type_val = nested_model + else: + type_val = Dict + elif type_ == "null": + type_val = Optional[Any] # Use Optional[Any] for nullable fields + else: + raise ValueError(f"Unsupported JSON schema type: {type_}") + + return type_val diff --git a/tests/unit/llms/test_anthropic.py b/tests/unit/llms/test_anthropic.py index 28e486756..75e7bcbf6 100644 --- a/tests/unit/llms/test_anthropic.py +++ b/tests/unit/llms/test_anthropic.py @@ -13,12 +13,16 @@ # limitations under the License. import os +import sys +from typing import Any, Dict from unittest.mock import AsyncMock, MagicMock, Mock, patch import nest_asyncio import pytest from distilabel.llms.anthropic import AnthropicLLM +from .utils import DummyUserDetail + @patch("anthropic.AsyncAnthropic") class TestAnthropicLLM: @@ -47,6 +51,37 @@ async def test_agenerate(self, mock_anthropic: MagicMock) -> None: ] ) + @pytest.mark.asyncio + async def test_agenerate_structured(self, mock_openai: MagicMock) -> None: + llm = AnthropicLLM( + model="claude-3-opus-20240229", + api_key="api.key", + structured_output={ + "schema": DummyUserDetail, + "mode": "tool_call", + "max_retries": 1, + }, + ) # type: ignore + llm._aclient = mock_openai + + sample_user = DummyUserDetail(name="John Doe", age=30) + + llm._aclient.messages.create = AsyncMock(return_value=sample_user) + + generation = await llm.agenerate( + input=[ + {"role": "system", "content": ""}, + { + "role": "user", + "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + ] + ) + assert generation[0] == sample_user.model_dump_json() + + @pytest.mark.skipif( + sys.version_info < (3, 9), reason="`mistralai` requires Python 3.9 or higher" + ) @pytest.mark.asyncio async def test_generate(self, mock_anthropic: MagicMock) -> None: llm = AnthropicLLM(model="claude-3-opus-20240229") # type: ignore @@ -71,7 +106,52 @@ async def test_generate(self, mock_anthropic: MagicMock) -> None: ] ) - def test_serialization(self, _: MagicMock) -> None: + @pytest.mark.parametrize( + "structured_output, dump", + [ + ( + None, + { + "base_url": "https://api.anthropic.com", + "generation_kwargs": {}, + "max_retries": 6, + "model": "claude-3-opus-20240229", + "timeout": 600.0, + "structured_output": None, + "type_info": { + "module": "distilabel.llms.anthropic", + "name": "AnthropicLLM", + }, + }, + ), + ( + { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + { + "base_url": "https://api.anthropic.com", + "generation_kwargs": {}, + "max_retries": 6, + "model": "claude-3-opus-20240229", + "timeout": 600.0, + "structured_output": { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + "type_info": { + "module": "distilabel.llms.anthropic", + "name": "AnthropicLLM", + }, + }, + ), + ], + ) + def test_serialization( + self, _: MagicMock, structured_output: Dict[str, Any], dump: Dict[str, Any] + ) -> None: os.environ["ANTHROPIC_API_KEY"] = "api.key" llm = AnthropicLLM(model="claude-3-opus-20240229") # type: ignore diff --git a/tests/unit/llms/test_azure.py b/tests/unit/llms/test_azure.py index a5208da95..e8af5d7b8 100644 --- a/tests/unit/llms/test_azure.py +++ b/tests/unit/llms/test_azure.py @@ -13,10 +13,14 @@ # limitations under the License. import os +from typing import Any, Dict from unittest import mock +import pytest from distilabel.llms.azure import AzureOpenAILLM +from .utils import DummyUserDetail + class TestAzureOpenAILLM: model_id: str = "gpt-4" @@ -56,20 +60,70 @@ def test_azure_openai_llm_env_vars(self) -> None: assert llm.api_key.get_secret_value() == "another.api.key" # type: ignore assert llm.api_version == self.api_version - def test_serialization(self) -> None: + @pytest.mark.parametrize( + "structured_output, dump", + [ + ( + None, + { + "model": "gpt-4", + "api_version": "preview", + "generation_kwargs": {}, + "max_retries": 6, + "base_url": "https://example-resource.azure.openai.com/", + "timeout": 120, + "structured_output": None, + "type_info": { + "module": "distilabel.llms.azure", + "name": "AzureOpenAILLM", + }, + }, + ), + ( + { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + { + "model": "gpt-4", + "api_version": "preview", + "generation_kwargs": {}, + "max_retries": 6, + "base_url": "https://example-resource.azure.openai.com/", + "timeout": 120, + "structured_output": { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + "type_info": { + "module": "distilabel.llms.azure", + "name": "AzureOpenAILLM", + }, + }, + ), + ], + ) + def test_serialization( + self, structured_output: Dict[str, Any], dump: Dict[str, Any] + ) -> None: llm = AzureOpenAILLM( - model=self.model_id, base_url=self.base_url, api_version=self.api_version + model=self.model_id, + base_url=self.base_url, + api_version=self.api_version, + structured_output=structured_output, ) - _dump = { - "generation_kwargs": {}, - "model": "gpt-4", - "base_url": "https://example-resource.azure.openai.com/", - "max_retries": 6, - "timeout": 120, - "api_version": "preview", - "structured_output": None, - "type_info": {"module": "distilabel.llms.azure", "name": "AzureOpenAILLM"}, - } - assert llm.dump() == _dump - assert isinstance(AzureOpenAILLM.from_dict(_dump), AzureOpenAILLM) + # _dump = { + # "generation_kwargs": {}, + # "model": "gpt-4", + # "base_url": "https://example-resource.azure.openai.com/", + # "max_retries": 6, + # "timeout": 120, + # "api_version": "preview", + # "structured_output": None, + # "type_info": {"module": "distilabel.llms.azure", "name": "AzureOpenAILLM"}, + # } + assert llm.dump() == dump + assert isinstance(AzureOpenAILLM.from_dict(dump), AzureOpenAILLM) diff --git a/tests/unit/llms/test_cohere.py b/tests/unit/llms/test_cohere.py index 0c2e2e213..3cba9611d 100644 --- a/tests/unit/llms/test_cohere.py +++ b/tests/unit/llms/test_cohere.py @@ -13,12 +13,16 @@ # limitations under the License. import os +import sys +from typing import Any, Dict from unittest import mock import nest_asyncio import pytest from distilabel.llms.cohere import CohereLLM +from .utils import DummyUserDetail + @mock.patch("cohere.AsyncClient") class TestCohereLLM: @@ -64,6 +68,38 @@ async def test_agenerate(self, mock_async_client: mock.MagicMock) -> None: ] ) + @pytest.mark.skipif( + sys.version_info < (3, 9), reason="`mistralai` requires Python 3.9 or higher" + ) + @pytest.mark.asyncio + async def test_agenerate_structured( + self, mock_async_client: mock.MagicMock + ) -> None: + llm = CohereLLM( + model="command-r", + structured_output={ + "schema": DummyUserDetail, + "mode": "tool_call", + "max_retries": 1, + }, + ) + llm._aclient = mock_async_client # type: ignore + + sample_user = DummyUserDetail(name="John Doe", age=30) + + llm._aclient.chat = mock.AsyncMock(return_value=sample_user) + + generation = await llm.agenerate( + input=[ + {"role": "system", "content": ""}, + { + "role": "user", + "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + ] + ) + assert generation == sample_user.model_dump_json() + @pytest.mark.asyncio async def test_generate(self, mock_async_client: mock.MagicMock) -> None: llm = CohereLLM(model="command-r") @@ -92,21 +128,53 @@ async def test_generate(self, mock_async_client: mock.MagicMock) -> None: ] ) - def test_serialization(self, _: mock.MagicMock) -> None: - llm = CohereLLM(model="command-r") - - dump = { - "model": "command-r", - "generation_kwargs": {}, - "base_url": "https://api.cohere.ai/v1", - "timeout": 120, - "client_name": "distilabel", - "structured_output": None, - "type_info": { - "module": "distilabel.llms.cohere", - "name": "CohereLLM", - }, - } + @pytest.mark.parametrize( + "structured_output, dump", + [ + ( + None, + { + "model": "command-r", + "generation_kwargs": {}, + "base_url": "https://api.cohere.ai/v1", + "timeout": 120, + "client_name": "distilabel", + "structured_output": None, + "type_info": { + "module": "distilabel.llms.cohere", + "name": "CohereLLM", + }, + }, + ), + ( + { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + { + "model": "command-r", + "generation_kwargs": {}, + "base_url": "https://api.cohere.ai/v1", + "timeout": 120, + "client_name": "distilabel", + "structured_output": { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + "type_info": { + "module": "distilabel.llms.cohere", + "name": "CohereLLM", + }, + }, + ), + ], + ) + def test_serialization( + self, _: mock.MagicMock, structured_output: Dict[str, Any], dump: Dict[str, Any] + ) -> None: + llm = CohereLLM(model="command-r", structured_output=structured_output) assert llm.dump() == dump assert isinstance(CohereLLM.from_dict(dump), CohereLLM) diff --git a/tests/unit/llms/test_groq.py b/tests/unit/llms/test_groq.py index e75166ce9..7607ab2cb 100644 --- a/tests/unit/llms/test_groq.py +++ b/tests/unit/llms/test_groq.py @@ -13,12 +13,16 @@ # limitations under the License. import os +import sys +from typing import Any, Dict from unittest.mock import AsyncMock, MagicMock, Mock, patch import nest_asyncio import pytest from distilabel.llms.groq import GroqLLM +from .utils import DummyUserDetail + @patch("groq._client.AsyncGroq") class TestGroqLLM: @@ -47,6 +51,37 @@ async def test_agenerate(self, mock_groq: MagicMock) -> None: ] ) == [" Aenean hendrerit aliquam velit. ..."] + @pytest.mark.skipif( + sys.version_info < (3, 9), reason="`mistralai` requires Python 3.9 or higher" + ) + @pytest.mark.asyncio + async def test_agenerate_structured(self, mock_openai: MagicMock) -> None: + llm = GroqLLM( + model="llama3-70b-8192", + api_key="api.key", + structured_output={ + "schema": DummyUserDetail, + "mode": "tool_call", + "max_retries": 1, + }, + ) # type: ignore + llm._aclient = mock_openai + + sample_user = DummyUserDetail(name="John Doe", age=30) + + llm._aclient.chat.completions.create = AsyncMock(return_value=sample_user) + + generation = await llm.agenerate( + input=[ + {"role": "system", "content": ""}, + { + "role": "user", + "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + ] + ) + assert generation[0] == sample_user.model_dump_json() + @pytest.mark.asyncio async def test_generate(self, mock_groq: MagicMock) -> None: llm = GroqLLM(model="llama3-70b-8192", api_key="api.key") # type: ignore @@ -71,22 +106,54 @@ async def test_generate(self, mock_groq: MagicMock) -> None: ] ) == [(" Aenean hendrerit aliquam velit. ...",)] - def test_serialization(self, mock_groq: MagicMock) -> None: + @pytest.mark.parametrize( + "structured_output, dump", + [ + ( + None, + { + "model": "llama3-70b-8192", + "base_url": "https://api.groq.com", + "generation_kwargs": {}, + "max_retries": 2, + "timeout": 120, + "structured_output": None, + "type_info": { + "module": "distilabel.llms.groq", + "name": "GroqLLM", + }, + }, + ), + ( + { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + { + "model": "llama3-70b-8192", + "base_url": "https://api.groq.com", + "generation_kwargs": {}, + "max_retries": 2, + "timeout": 120, + "structured_output": { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + "type_info": { + "module": "distilabel.llms.groq", + "name": "GroqLLM", + }, + }, + ), + ], + ) + def test_serialization( + self, _: MagicMock, structured_output: Dict[str, Any], dump: Dict[str, Any] + ) -> None: os.environ["GROQ_API_KEY"] = "api.key" - llm = GroqLLM(model="llama3-70b-8192") - - _dump = { - "model": "llama3-70b-8192", - "base_url": "https://api.groq.com", - "generation_kwargs": {}, - "max_retries": 2, - "timeout": 120, - "structured_output": None, - "type_info": { - "module": "distilabel.llms.groq", - "name": "GroqLLM", - }, - } + llm = GroqLLM(model="llama3-70b-8192", structured_output=structured_output) - assert llm.dump() == _dump - assert isinstance(GroqLLM.from_dict(_dump), GroqLLM) # type: ignore + assert llm.dump() == dump + assert isinstance(GroqLLM.from_dict(dump), GroqLLM) # type: ignore diff --git a/tests/unit/llms/test_mistral.py b/tests/unit/llms/test_mistral.py index f31e903d3..5bb233748 100644 --- a/tests/unit/llms/test_mistral.py +++ b/tests/unit/llms/test_mistral.py @@ -14,11 +14,14 @@ import os import sys +from typing import Any, Dict from unittest.mock import AsyncMock, MagicMock, Mock, patch import nest_asyncio import pytest +from .utils import DummyUserDetail + try: from distilabel.llms.mistral import MistralLLM except ImportError: @@ -55,6 +58,37 @@ async def test_agenerate(self, mock_mistral: MagicMock) -> None: ] ) + @pytest.mark.asyncio + async def test_agenerate_structured(self, mock_mistral: MagicMock) -> None: + llm = MistralLLM( + model="mistral-tiny", + api_key="api.key", + structured_output={ + "schema": DummyUserDetail, + "mode": "tool_call", + "max_retries": 1, + }, + ) # type: ignore + llm._aclient = mock_mistral + + sample_user = DummyUserDetail(name="John Doe", age=30) + + llm._aclient.chat.completions.create = AsyncMock(return_value=sample_user) + # This should work just with the _aclient.chat method once it's fixed in instructor, and + # then in our code. + # llm._aclient.chat = AsyncMock(return_value=sample_user) + + generation = await llm.agenerate( + input=[ + {"role": "system", "content": ""}, + { + "role": "user", + "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + ] + ) + assert generation[0] == sample_user.model_dump_json() + @pytest.mark.asyncio async def test_generate(self, mock_mistral: MagicMock) -> None: llm = MistralLLM(model="mistral-tiny", api_key="api.key") # type: ignore @@ -79,7 +113,54 @@ async def test_generate(self, mock_mistral: MagicMock) -> None: ] ) - def test_serialization(self, mock_mistral: MagicMock) -> None: + @pytest.mark.parametrize( + "structured_output, dump", + [ + ( + None, + { + "model": "mistral-tiny", + "endpoint": "https://api.mistral.ai", + "generation_kwargs": {}, + "max_retries": 6, + "timeout": 120, + "max_concurrent_requests": 64, + "structured_output": None, + "type_info": { + "module": "distilabel.llms.mistral", + "name": "MistralLLM", + }, + }, + ), + ( + { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + { + "model": "mistral-tiny", + "endpoint": "https://api.mistral.ai", + "generation_kwargs": {}, + "max_retries": 6, + "timeout": 120, + "max_concurrent_requests": 64, + "structured_output": { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + "type_info": { + "module": "distilabel.llms.mistral", + "name": "MistralLLM", + }, + }, + ), + ], + ) + def test_serialization( + self, _: MagicMock, structured_output: Dict[str, Any], dump: Dict[str, Any] + ) -> None: os.environ["MISTRAL_API_KEY"] = "api.key" llm = MistralLLM(model="mistral-tiny") # type: ignore diff --git a/tests/unit/llms/test_openai.py b/tests/unit/llms/test_openai.py index 3562b6588..7f90f513a 100644 --- a/tests/unit/llms/test_openai.py +++ b/tests/unit/llms/test_openai.py @@ -13,6 +13,8 @@ # limitations under the License. import os +import sys +from typing import Any, Dict from unittest import mock from unittest.mock import AsyncMock, MagicMock, Mock, patch @@ -20,6 +22,8 @@ import pytest from distilabel.llms.openai import OpenAILLM +from .utils import DummyUserDetail + @patch("openai.AsyncOpenAI") class TestOpenAILLM: @@ -63,6 +67,37 @@ async def test_agenerate(self, mock_openai: MagicMock) -> None: ] ) + @pytest.mark.asyncio + async def test_agenerate_structured(self, mock_openai: MagicMock) -> None: + llm = OpenAILLM( + model=self.model_id, + api_key="api.key", + structured_output={ + "schema": DummyUserDetail, + "mode": "tool_call", + "max_retries": 1, + }, + ) # type: ignore + llm._aclient = mock_openai + + sample_user = DummyUserDetail(name="John Doe", age=30) + + llm._aclient.chat.completions.create = AsyncMock(return_value=sample_user) + + generation = await llm.agenerate( + input=[ + {"role": "system", "content": ""}, + { + "role": "user", + "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + }, + ] + ) + assert generation[0] == sample_user.model_dump_json() + + @pytest.mark.skipif( + sys.version_info < (3, 9), reason="`mistralai` requires Python 3.9 or higher" + ) @pytest.mark.asyncio async def test_generate(self, mock_openai: MagicMock) -> None: llm = OpenAILLM(model=self.model_id, api_key="api.key") # type: ignore @@ -101,21 +136,53 @@ async def test_generate(self, mock_openai: MagicMock) -> None: response_format="unkown_format", ) - def test_serialization(self, _: MagicMock) -> None: - llm = OpenAILLM(model=self.model_id) - - _dump = { - "model": self.model_id, - "generation_kwargs": {}, - "max_retries": 6, - "base_url": "https://api.openai.com/v1", - "timeout": 120, - "structured_output": None, - "type_info": { - "module": "distilabel.llms.openai", - "name": "OpenAILLM", - }, - } - - assert llm.dump() == _dump - assert isinstance(OpenAILLM.from_dict(_dump), OpenAILLM) + @pytest.mark.parametrize( + "structured_output, dump", + [ + ( + None, + { + "model": "gpt-4", + "generation_kwargs": {}, + "max_retries": 6, + "base_url": "https://api.openai.com/v1", + "timeout": 120, + "structured_output": None, + "type_info": { + "module": "distilabel.llms.openai", + "name": "OpenAILLM", + }, + }, + ), + ( + { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + { + "model": "gpt-4", + "generation_kwargs": {}, + "max_retries": 6, + "base_url": "https://api.openai.com/v1", + "timeout": 120, + "structured_output": { + "schema": DummyUserDetail.model_json_schema(), + "mode": "tool_call", + "max_retries": 1, + }, + "type_info": { + "module": "distilabel.llms.openai", + "name": "OpenAILLM", + }, + }, + ), + ], + ) + def test_serialization( + self, _: MagicMock, structured_output: Dict[str, Any], dump: Dict[str, Any] + ) -> None: + llm = OpenAILLM(model=self.model_id, structured_output=structured_output) + + assert llm.dump() == dump + assert isinstance(OpenAILLM.from_dict(dump), OpenAILLM) diff --git a/tests/unit/llms/utils.py b/tests/unit/llms/utils.py new file mode 100644 index 000000000..7b899253b --- /dev/null +++ b/tests/unit/llms/utils.py @@ -0,0 +1,20 @@ +# Copyright 2023-present, Argilla, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pydantic import BaseModel + + +class DummyUserDetail(BaseModel): + name: str + age: int diff --git a/tests/unit/steps/tasks/structured_outputs/test_utils.py b/tests/unit/steps/tasks/structured_outputs/test_utils.py new file mode 100644 index 000000000..6238c8567 --- /dev/null +++ b/tests/unit/steps/tasks/structured_outputs/test_utils.py @@ -0,0 +1,75 @@ +# Copyright 2023-present, Argilla, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from enum import Enum +from typing import List + +from distilabel.steps.tasks.structured_outputs.utils import json_schema_to_model +from pydantic import BaseModel, Field, StringConstraints, conint +from typing_extensions import Annotated + + +class Node(BaseModel): + id: int + label: str + color: str + + +class Edge(BaseModel): + source: int + target: int + label: str + color: str = "black" + + +class KnowledgeGraph(BaseModel): + nodes: List[Node] = Field(..., default_factory=list) + edges: List[Edge] = Field(..., default_factory=list) + + +class Weapon(str, Enum): + sword = "sword" + axe = "axe" + mace = "mace" + spear = "spear" + bow = "bow" + crossbow = "crossbow" + + +class Armor(str, Enum): + leather = "leather" + chainmail = "chainmail" + plate = "plate" + mithril = "mithril" + + +class Character(BaseModel): + name: Annotated[str, StringConstraints(max_length=30)] + age: conint(gt=1, lt=3000) + armor: Armor + weapon: Weapon + + +def test_json_schema_to_model(): + assert type(json_schema_to_model(Node.model_json_schema())) == type(Node) + + +def test_json_schema_to_model_with_enum(): + assert type(json_schema_to_model(Character.model_json_schema())) == type(Character) + + +def test_json_schema_to_model_nested(): + assert type(json_schema_to_model(KnowledgeGraph.model_json_schema())) == type( + KnowledgeGraph + )