Fa1dz julien-c HF Staff commited on
Commit
e734794
·
0 Parent(s):

Duplicate from flax-community/chef-transformer

Browse files

Co-authored-by: Julien Chaumond <[email protected]>

.gitattributes ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.bin.* filter=lfs diff=lfs merge=lfs -text
2
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.h5 filter=lfs diff=lfs merge=lfs -text
5
+ *.tflite filter=lfs diff=lfs merge=lfs -text
6
+ *.tar.gz filter=lfs diff=lfs merge=lfs -text
7
+ *.ot filter=lfs diff=lfs merge=lfs -text
8
+ *.onnx filter=lfs diff=lfs merge=lfs -text
9
+ *.arrow filter=lfs diff=lfs merge=lfs -text
10
+ *.ftz filter=lfs diff=lfs merge=lfs -text
11
+ *.joblib filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.pb filter=lfs diff=lfs merge=lfs -text
15
+ *.pt filter=lfs diff=lfs merge=lfs -text
16
+ *.pth filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,887 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### TeX template
2
+ ## Core latex/pdflatex auxiliary files:
3
+ *.aux
4
+ *.lof
5
+ *.log
6
+ *.lot
7
+ *.fls
8
+ *.out
9
+ *.toc
10
+ *.fmt
11
+ *.fot
12
+ *.cb
13
+ *.cb2
14
+ .*.lb
15
+
16
+ ## Intermediate documents:
17
+ *.dvi
18
+ *.xdv
19
+ *-converted-to.*
20
+ # these rules might exclude image files for figures etc.
21
+ # *.ps
22
+ # *.eps
23
+ # *.pdf
24
+
25
+ ## Generated if empty string is given at "Please type another file name for output:"
26
+ .pdf
27
+
28
+ ## Bibliography auxiliary files (bibtex/biblatex/biber):
29
+ *.bbl
30
+ *.bcf
31
+ *.blg
32
+ *-blx.aux
33
+ *-blx.bib
34
+ *.run.xml
35
+
36
+ ## Build tool auxiliary files:
37
+ *.fdb_latexmk
38
+ *.synctex
39
+ *.synctex(busy)
40
+ *.synctex.gz
41
+ *.synctex.gz(busy)
42
+ *.pdfsync
43
+
44
+ ## Build tool directories for auxiliary files
45
+ # latexrun
46
+ latex.out/
47
+
48
+ ## Auxiliary and intermediate files from other packages:
49
+ # algorithms
50
+ *.alg
51
+ *.loa
52
+
53
+ # achemso
54
+ acs-*.bib
55
+
56
+ # amsthm
57
+ *.thm
58
+
59
+ # beamer
60
+ *.nav
61
+ *.pre
62
+ *.snm
63
+ *.vrb
64
+
65
+ # changes
66
+ *.soc
67
+
68
+ # comment
69
+ *.cut
70
+
71
+ # cprotect
72
+ *.cpt
73
+
74
+ # elsarticle (documentclass of Elsevier journals)
75
+ *.spl
76
+
77
+ # endnotes
78
+ *.ent
79
+
80
+ # fixme
81
+ *.lox
82
+
83
+ # feynmf/feynmp
84
+ *.mf
85
+ *.mp
86
+ *.t[1-9]
87
+ *.t[1-9][0-9]
88
+ *.tfm
89
+
90
+ #(r)(e)ledmac/(r)(e)ledpar
91
+ *.end
92
+ *.?end
93
+ *.[1-9]
94
+ *.[1-9][0-9]
95
+ *.[1-9][0-9][0-9]
96
+ *.[1-9]R
97
+ *.[1-9][0-9]R
98
+ *.[1-9][0-9][0-9]R
99
+ *.eledsec[1-9]
100
+ *.eledsec[1-9]R
101
+ *.eledsec[1-9][0-9]
102
+ *.eledsec[1-9][0-9]R
103
+ *.eledsec[1-9][0-9][0-9]
104
+ *.eledsec[1-9][0-9][0-9]R
105
+
106
+ # glossaries
107
+ *.acn
108
+ *.acr
109
+ *.glg
110
+ *.glo
111
+ *.gls
112
+ *.glsdefs
113
+ *.lzo
114
+ *.lzs
115
+
116
+ # uncomment this for glossaries-extra (will ignore makeindex's style files!)
117
+ # *.ist
118
+
119
+ # gnuplottex
120
+ *-gnuplottex-*
121
+
122
+ # gregoriotex
123
+ *.gaux
124
+ *.gtex
125
+
126
+ # htlatex
127
+ *.4ct
128
+ *.4tc
129
+ *.idv
130
+ *.lg
131
+ *.trc
132
+ *.xref
133
+
134
+ # hyperref
135
+ *.brf
136
+
137
+ # knitr
138
+ *-concordance.tex
139
+ # TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files
140
+ # *.tikz
141
+ *-tikzDictionary
142
+
143
+ # listings
144
+ *.lol
145
+
146
+ # luatexja-ruby
147
+ *.ltjruby
148
+
149
+ # makeidx
150
+ *.idx
151
+ *.ilg
152
+ *.ind
153
+
154
+ # minitoc
155
+ *.maf
156
+ *.mlf
157
+ *.mlt
158
+ *.mtc[0-9]*
159
+ *.slf[0-9]*
160
+ *.slt[0-9]*
161
+ *.stc[0-9]*
162
+
163
+ # minted
164
+ _minted*
165
+ *.pyg
166
+
167
+ # morewrites
168
+ *.mw
169
+
170
+ # nomencl
171
+ *.nlg
172
+ *.nlo
173
+ *.nls
174
+
175
+ # pax
176
+ *.pax
177
+
178
+ # pdfpcnotes
179
+ *.pdfpc
180
+
181
+ # sagetex
182
+ *.sagetex.sage
183
+ *.sagetex.py
184
+ *.sagetex.scmd
185
+
186
+ # scrwfile
187
+ *.wrt
188
+
189
+ # sympy
190
+ *.sout
191
+ *.sympy
192
+ sympy-plots-for-*.tex/
193
+
194
+ # pdfcomment
195
+ *.upa
196
+ *.upb
197
+
198
+ # pythontex
199
+ *.pytxcode
200
+ pythontex-files-*/
201
+
202
+ # tcolorbox
203
+ *.listing
204
+
205
+ # thmtools
206
+ *.loe
207
+
208
+ # TikZ & PGF
209
+ *.dpth
210
+ *.md5
211
+ *.auxlock
212
+
213
+ # todonotes
214
+ *.tdo
215
+
216
+ # vhistory
217
+ *.hst
218
+ *.ver
219
+
220
+ # easy-todo
221
+ *.lod
222
+
223
+ # xcolor
224
+ *.xcp
225
+
226
+ # xmpincl
227
+ *.xmpi
228
+
229
+ # xindy
230
+ *.xdy
231
+
232
+ # xypic precompiled matrices and outlines
233
+ *.xyc
234
+ *.xyd
235
+
236
+ # endfloat
237
+ *.ttt
238
+ *.fff
239
+
240
+ # Latexian
241
+ TSWLatexianTemp*
242
+
243
+ ## Editors:
244
+ # WinEdt
245
+ *.bak
246
+ *.sav
247
+
248
+ # Texpad
249
+ .texpadtmp
250
+
251
+ # LyX
252
+ *.lyx~
253
+
254
+ # Kile
255
+ *.backup
256
+
257
+ # gummi
258
+ .*.swp
259
+
260
+ # KBibTeX
261
+ *~[0-9]*
262
+
263
+ # TeXnicCenter
264
+ *.tps
265
+
266
+ # auto folder when using emacs and auctex
267
+ ./auto/*
268
+ *.el
269
+
270
+ # expex forward references with \gathertags
271
+ *-tags.tex
272
+
273
+ # standalone packages
274
+ *.sta
275
+
276
+ # Makeindex log files
277
+ *.lpz
278
+
279
+ # xwatermark package
280
+ *.xwm
281
+
282
+ # REVTeX puts footnotes in the bibliography by default, unless the nofootinbib
283
+ # option is specified. Footnotes are the stored in a file with suffix Notes.bib.
284
+ # Uncomment the next line to have this generated file ignored.
285
+ #*Notes.bib
286
+
287
+ ### VisualStudio template
288
+ ## Ignore Visual Studio temporary files, build results, and
289
+ ## files generated by popular Visual Studio add-ons.
290
+ ##
291
+ ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
292
+
293
+ # User-specific files
294
+ *.rsuser
295
+ *.suo
296
+ *.user
297
+ *.userosscache
298
+ *.sln.docstates
299
+
300
+ # User-specific files (MonoDevelop/Xamarin Studio)
301
+ *.userprefs
302
+
303
+ # Mono auto generated files
304
+ mono_crash.*
305
+
306
+ # Build results
307
+ [Dd]ebug/
308
+ [Dd]ebugPublic/
309
+ [Rr]elease/
310
+ [Rr]eleases/
311
+ x64/
312
+ x86/
313
+ [Ww][Ii][Nn]32/
314
+ [Aa][Rr][Mm]/
315
+ [Aa][Rr][Mm]64/
316
+ bld/
317
+ [Bb]in/
318
+ [Oo]bj/
319
+ [Ll]og/
320
+ [Ll]ogs/
321
+
322
+ # Visual Studio 2015/2017 cache/options directory
323
+ .vs/
324
+ # Uncomment if you have tasks that create the project's static files in wwwroot
325
+ #wwwroot/
326
+
327
+ # Visual Studio 2017 auto generated files
328
+ Generated\ Files/
329
+
330
+ # MSTest test Results
331
+ [Tt]est[Rr]esult*/
332
+ [Bb]uild[Ll]og.*
333
+
334
+ # NUnit
335
+ *.VisualState.xml
336
+ TestResult.xml
337
+ nunit-*.xml
338
+
339
+ # Build Results of an ATL Project
340
+ [Dd]ebugPS/
341
+ [Rr]eleasePS/
342
+ dlldata.c
343
+
344
+ # Benchmark Results
345
+ BenchmarkDotNet.Artifacts/
346
+
347
+ # .NET Core
348
+ project.lock.json
349
+ project.fragment.lock.json
350
+ artifacts/
351
+
352
+ # ASP.NET Scaffolding
353
+ ScaffoldingReadMe.txt
354
+
355
+ # StyleCop
356
+ StyleCopReport.xml
357
+
358
+ # Files built by Visual Studio
359
+ *_i.c
360
+ *_p.c
361
+ *_h.h
362
+ *.ilk
363
+ *.meta
364
+ *.obj
365
+ *.iobj
366
+ *.pch
367
+ *.pdb
368
+ *.ipdb
369
+ *.pgc
370
+ *.pgd
371
+ *.rsp
372
+ *.sbr
373
+ *.tlb
374
+ *.tli
375
+ *.tlh
376
+ *.tmp
377
+ *.tmp_proj
378
+ *_wpftmp.csproj
379
+ *.log
380
+ *.vspscc
381
+ *.vssscc
382
+ .builds
383
+ *.pidb
384
+ *.svclog
385
+ *.scc
386
+
387
+ # Chutzpah Test files
388
+ _Chutzpah*
389
+
390
+ # Visual C++ cache files
391
+ ipch/
392
+ *.aps
393
+ *.ncb
394
+ *.opendb
395
+ *.opensdf
396
+ *.sdf
397
+ *.cachefile
398
+ *.VC.db
399
+ *.VC.VC.opendb
400
+
401
+ # Visual Studio profiler
402
+ *.psess
403
+ *.vsp
404
+ *.vspx
405
+ *.sap
406
+
407
+ # Visual Studio Trace Files
408
+ *.e2e
409
+
410
+ # TFS 2012 Local Workspace
411
+ $tf/
412
+
413
+ # Guidance Automation Toolkit
414
+ *.gpState
415
+
416
+ # ReSharper is a .NET coding add-in
417
+ _ReSharper*/
418
+ *.[Rr]e[Ss]harper
419
+ *.DotSettings.user
420
+
421
+ # TeamCity is a build add-in
422
+ _TeamCity*
423
+
424
+ # DotCover is a Code Coverage Tool
425
+ *.dotCover
426
+
427
+ # AxoCover is a Code Coverage Tool
428
+ .axoCover/*
429
+ !.axoCover/settings.json
430
+
431
+ # Coverlet is a free, cross platform Code Coverage Tool
432
+ coverage*.json
433
+ coverage*.xml
434
+ coverage*.info
435
+
436
+ # Visual Studio code coverage results
437
+ *.coverage
438
+ *.coveragexml
439
+
440
+ # NCrunch
441
+ _NCrunch_*
442
+ .*crunch*.local.xml
443
+ nCrunchTemp_*
444
+
445
+ # MightyMoose
446
+ *.mm.*
447
+ AutoTest.Net/
448
+
449
+ # Web workbench (sass)
450
+ .sass-cache/
451
+
452
+ # Installshield output folder
453
+ [Ee]xpress/
454
+
455
+ # DocProject is a documentation generator add-in
456
+ DocProject/buildhelp/
457
+ DocProject/Help/*.HxT
458
+ DocProject/Help/*.HxC
459
+ DocProject/Help/*.hhc
460
+ DocProject/Help/*.hhk
461
+ DocProject/Help/*.hhp
462
+ DocProject/Help/Html2
463
+ DocProject/Help/html
464
+
465
+ # Click-Once directory
466
+ publish/
467
+
468
+ # Publish Web Output
469
+ *.[Pp]ublish.xml
470
+ *.azurePubxml
471
+ # Note: Comment the next line if you want to checkin your web deploy settings,
472
+ # but database connection strings (with potential passwords) will be unencrypted
473
+ *.pubxml
474
+ *.publishproj
475
+
476
+ # Microsoft Azure Web App publish settings. Comment the next line if you want to
477
+ # checkin your Azure Web App publish settings, but sensitive information contained
478
+ # in these scripts will be unencrypted
479
+ PublishScripts/
480
+
481
+ # NuGet Packages
482
+ *.nupkg
483
+ # NuGet Symbol Packages
484
+ *.snupkg
485
+ # The packages folder can be ignored because of Package Restore
486
+ **/[Pp]ackages/*
487
+ # except build/, which is used as an MSBuild target.
488
+ !**/[Pp]ackages/build/
489
+ # Uncomment if necessary however generally it will be regenerated when needed
490
+ #!**/[Pp]ackages/repositories.config
491
+ # NuGet v3's project.json files produces more ignorable files
492
+ *.nuget.props
493
+ *.nuget.targets
494
+
495
+ # Microsoft Azure Build Output
496
+ csx/
497
+ *.build.csdef
498
+
499
+ # Microsoft Azure Emulator
500
+ ecf/
501
+ rcf/
502
+
503
+ # Windows Store app package directories and files
504
+ AppPackages/
505
+ BundleArtifacts/
506
+ Package.StoreAssociation.xml
507
+ _pkginfo.txt
508
+ *.appx
509
+ *.appxbundle
510
+ *.appxupload
511
+
512
+ # Visual Studio cache files
513
+ # files ending in .cache can be ignored
514
+ *.[Cc]ache
515
+ # but keep track of directories ending in .cache
516
+ !?*.[Cc]ache/
517
+
518
+ # Others
519
+ ClientBin/
520
+ ~$*
521
+ *~
522
+ *.dbmdl
523
+ *.dbproj.schemaview
524
+ *.jfm
525
+ *.pfx
526
+ *.publishsettings
527
+ orleans.codegen.cs
528
+
529
+ # Including strong name files can present a security risk
530
+ # (https://github.com/github/gitignore/pull/2483#issue-259490424)
531
+ #*.snk
532
+
533
+ # Since there are multiple workflows, uncomment next line to ignore bower_components
534
+ # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
535
+ #bower_components/
536
+
537
+ # RIA/Silverlight projects
538
+ Generated_Code/
539
+
540
+ # Backup & report files from converting an old project file
541
+ # to a newer Visual Studio version. Backup files are not needed,
542
+ # because we have git ;-)
543
+ _UpgradeReport_Files/
544
+ Backup*/
545
+ UpgradeLog*.XML
546
+ UpgradeLog*.htm
547
+ ServiceFabricBackup/
548
+ *.rptproj.bak
549
+
550
+ # SQL Server files
551
+ *.mdf
552
+ *.ldf
553
+ *.ndf
554
+
555
+ # Business Intelligence projects
556
+ *.rdl.data
557
+ *.bim.layout
558
+ *.bim_*.settings
559
+ *.rptproj.rsuser
560
+ *- [Bb]ackup.rdl
561
+ *- [Bb]ackup ([0-9]).rdl
562
+ *- [Bb]ackup ([0-9][0-9]).rdl
563
+
564
+ # Microsoft Fakes
565
+ FakesAssemblies/
566
+
567
+ # GhostDoc plugin setting file
568
+ *.GhostDoc.xml
569
+
570
+ # Node.js Tools for Visual Studio
571
+ .ntvs_analysis.dat
572
+ node_modules/
573
+
574
+ # Visual Studio 6 build log
575
+ *.plg
576
+
577
+ # Visual Studio 6 workspace options file
578
+ *.opt
579
+
580
+ # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
581
+ *.vbw
582
+
583
+ # Visual Studio LightSwitch build output
584
+ **/*.HTMLClient/GeneratedArtifacts
585
+ **/*.DesktopClient/GeneratedArtifacts
586
+ **/*.DesktopClient/ModelManifest.xml
587
+ **/*.Server/GeneratedArtifacts
588
+ **/*.Server/ModelManifest.xml
589
+ _Pvt_Extensions
590
+
591
+ # Paket dependency manager
592
+ .paket/paket.exe
593
+ paket-files/
594
+
595
+ # FAKE - F# Make
596
+ .fake/
597
+
598
+ # CodeRush personal settings
599
+ .cr/personal
600
+
601
+ # Python Tools for Visual Studio (PTVS)
602
+ __pycache__/
603
+ *.pyc
604
+
605
+ # Cake - Uncomment if you are using it
606
+ # tools/**
607
+ # !tools/packages.config
608
+
609
+ # Tabs Studio
610
+ *.tss
611
+
612
+ # Telerik's JustMock configuration file
613
+ *.jmconfig
614
+
615
+ # BizTalk build output
616
+ *.btp.cs
617
+ *.btm.cs
618
+ *.odx.cs
619
+ *.xsd.cs
620
+
621
+ # OpenCover UI analysis results
622
+ OpenCover/
623
+
624
+ # Azure Stream Analytics local run output
625
+ ASALocalRun/
626
+
627
+ # MSBuild Binary and Structured Log
628
+ *.binlog
629
+
630
+ # NVidia Nsight GPU debugger configuration file
631
+ *.nvuser
632
+
633
+ # MFractors (Xamarin productivity tool) working folder
634
+ .mfractor/
635
+
636
+ # Local History for Visual Studio
637
+ .localhistory/
638
+
639
+ # BeatPulse healthcheck temp database
640
+ healthchecksdb
641
+
642
+ # Backup folder for Package Reference Convert tool in Visual Studio 2017
643
+ MigrationBackup/
644
+
645
+ # Ionide (cross platform F# VS Code tools) working folder
646
+ .ionide/
647
+
648
+ # Fody - auto-generated XML schema
649
+ FodyWeavers.xsd
650
+
651
+ ### Python template
652
+ # Byte-compiled / optimized / DLL files
653
+ __pycache__/
654
+ *.py[cod]
655
+ *$py.class
656
+
657
+ # C extensions
658
+ *.so
659
+
660
+ # Distribution / packaging
661
+ .Python
662
+ build/
663
+ develop-eggs/
664
+ dist/
665
+ downloads/
666
+ eggs/
667
+ .eggs/
668
+ lib/
669
+ lib64/
670
+ parts/
671
+ sdist/
672
+ var/
673
+ wheels/
674
+ share/python-wheels/
675
+ *.egg-info/
676
+ .installed.cfg
677
+ *.egg
678
+ MANIFEST
679
+
680
+ # PyInstaller
681
+ # Usually these files are written by a python script from a template
682
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
683
+ *.manifest
684
+ *.spec
685
+
686
+ # Installer logs
687
+ pip-log.txt
688
+ pip-delete-this-directory.txt
689
+
690
+ # Unit test / coverage reports
691
+ htmlcov/
692
+ .tox/
693
+ .nox/
694
+ .coverage
695
+ .coverage.*
696
+ .cache
697
+ nosetests.xml
698
+ coverage.xml
699
+ *.cover
700
+ *.py,cover
701
+ .hypothesis/
702
+ .pytest_cache/
703
+ cover/
704
+
705
+ # Translations
706
+ *.mo
707
+ *.pot
708
+
709
+ # Django stuff:
710
+ *.log
711
+ local_settings.py
712
+ db.sqlite3
713
+ db.sqlite3-journal
714
+
715
+ # Flask stuff:
716
+ instance/
717
+ .webassets-cache
718
+
719
+ # Scrapy stuff:
720
+ .scrapy
721
+
722
+ # Sphinx documentation
723
+ docs/_build/
724
+
725
+ # PyBuilder
726
+ .pybuilder/
727
+ target/
728
+
729
+ # Jupyter Notebook
730
+ .ipynb_checkpoints
731
+
732
+ # IPython
733
+ profile_default/
734
+ ipython_config.py
735
+
736
+ # pyenv
737
+ # For a library or package, you might want to ignore these files since the code is
738
+ # intended to run in multiple environments; otherwise, check them in:
739
+ # .python-version
740
+
741
+ # pipenv
742
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
743
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
744
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
745
+ # install all needed dependencies.
746
+ #Pipfile.lock
747
+
748
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
749
+ __pypackages__/
750
+
751
+ # Celery stuff
752
+ celerybeat-schedule
753
+ celerybeat.pid
754
+
755
+ # SageMath parsed files
756
+ *.sage.py
757
+
758
+ # Environments
759
+ .env
760
+ .venv
761
+ env/
762
+ venv/
763
+ ENV/
764
+ env.bak/
765
+ venv.bak/
766
+
767
+ # Spyder project settings
768
+ .spyderproject
769
+ .spyproject
770
+
771
+ # Rope project settings
772
+ .ropeproject
773
+
774
+ # mkdocs documentation
775
+ /site
776
+
777
+ # mypy
778
+ .mypy_cache/
779
+ .dmypy.json
780
+ dmypy.json
781
+
782
+ # Pyre type checker
783
+ .pyre/
784
+
785
+ # pytype static type analyzer
786
+ .pytype/
787
+
788
+ # Cython debug symbols
789
+ cython_debug/
790
+
791
+ ### JupyterNotebooks template
792
+ # gitignore template for Jupyter Notebooks
793
+ # website: http://jupyter.org/
794
+
795
+ .ipynb_checkpoints
796
+ */.ipynb_checkpoints/*
797
+
798
+ # IPython
799
+ profile_default/
800
+ ipython_config.py
801
+
802
+ # Remove previous ipynb_checkpoints
803
+ # git rm -r .ipynb_checkpoints/
804
+
805
+ ### VirtualEnv template
806
+ # Virtualenv
807
+ # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
808
+ .Python
809
+ [Bb]in
810
+ [Ii]nclude
811
+ [Ll]ib
812
+ [Ll]ib64
813
+ [Ll]ocal
814
+ [Ss]cripts
815
+ pyvenv.cfg
816
+ .venv
817
+ pip-selfcheck.json
818
+
819
+ ### Eclipse template
820
+ .metadata
821
+ bin/
822
+ tmp/
823
+ *.tmp
824
+ *.bak
825
+ *.swp
826
+ *~.nib
827
+ local.properties
828
+ .settings/
829
+ .loadpath
830
+ .recommenders
831
+
832
+ # External tool builders
833
+ .externalToolBuilders/
834
+
835
+ # Locally stored "Eclipse launch configurations"
836
+ *.launch
837
+
838
+ # PyDev specific (Python IDE for Eclipse)
839
+ *.pydevproject
840
+
841
+ # CDT-specific (C/C++ Development Tooling)
842
+ .cproject
843
+
844
+ # CDT- autotools
845
+ .autotools
846
+
847
+ # Java annotation processor (APT)
848
+ .factorypath
849
+
850
+ # PDT-specific (PHP Development Tools)
851
+ .buildpath
852
+
853
+ # sbteclipse plugin
854
+ .target
855
+
856
+ # Tern plugin
857
+ .tern-project
858
+
859
+ # TeXlipse plugin
860
+ .texlipse
861
+
862
+ # STS (Spring Tool Suite)
863
+ .springBeans
864
+
865
+ # Code Recommenders
866
+ .recommenders/
867
+
868
+ # Annotation Processing
869
+ .apt_generated/
870
+ .apt_generated_test/
871
+
872
+ # Scala IDE specific (Scala & Java development for Eclipse)
873
+ .cache-main
874
+ .scala_dependencies
875
+ .worksheet
876
+
877
+ # Uncomment this line if you wish to ignore the project description file.
878
+ # Typically, this file would be tracked if it contains build/dependency configurations:
879
+ #.project
880
+
881
+ # CUSTOM
882
+ .idea
883
+ .DS_Store
884
+ .DS_store
885
+ *.tmp.py
886
+ *.tmp.json
887
+ tmp
CONTRIBUTING.md ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 1. Fork the repository by clicking on the ``Fork`` button on the repository's page. This creates a copy of the code under your GitHub user account.
2
+
3
+ 2. Clone your fork to your local disk, and add the base repository as a remote.
4
+ ```bash
5
+ $ git clone [email protected]:<your-GitHub-username>/chef-transformer.git
6
+ $ cd chef-transformer
7
+ $ git remote add upstream https://github.com/chef-transformer/chef-transformer.git
8
+ ```
9
+
10
+ 3. Create a new branch to hold your development changes.
11
+ ```bash
12
+ $ git checkout -b a-descriptive-name-for-your-changes
13
+ ```
14
+
15
+ > NOTE: Do not work on the ``main`` branch.
16
+
17
+ 4. Set up a development environment by running the following command in a virtual environment.
18
+ ```bash
19
+ $ pip install -r requirements.txt
20
+ ```
21
+
22
+ 5. DEVELOP THE CODE
23
+
24
+ 6. It is a good idea to sync your copy of the code with the original repository regularly. This way you can quickly account for changes.
25
+ ```bash
26
+ $ git fetch upstream
27
+ $ git rebase upstream/main
28
+ ```
29
+
30
+ 7. Push the changes to your account using:
31
+ ```bash
32
+ $ git push -u origin a-descriptive-name-for-your-changes
33
+ ```
34
+
35
+ 8. Once you are satisfied (and the checklist above is happy too), go to the webpage of your fork on GitHub. Click on ``Pull Request`` to send your changes to the project maintainers for review.
README.md ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Chef Transformer
3
+ emoji: 🍲
4
+ colorFrom: blue
5
+ colorTo: red
6
+ sdk: streamlit
7
+ sdk_version: 1.1.0
8
+ app_file: app.py
9
+ pinned: false
10
+ duplicated_from: flax-community/chef-transformer
11
+ ---
12
+
13
+ # Chef Transformer (T5)
14
+ > This is part of the [Flax/Jax Community Week](https://discuss.huggingface.co/t/recipe-generation-model/7475), organized by [HuggingFace](https://huggingface.co/) and TPU usage sponsored by Google.
15
+
16
+ Want to give it a try? Then what's the wait, head over to the demo [here](https://share.streamlit.io/chef-transformer/chef-transformer/main/app.py).
17
+
18
+
19
+ ## Team Members
20
+ - Mehrdad Farahani ([m3hrdadfi](https://huggingface.co/m3hrdadfi))
21
+ - Kartik Godawat ([dk-crazydiv](https://huggingface.co/dk-crazydiv))
22
+ - Haswanth Aekula ([hassiahk](https://huggingface.co/hassiahk))
23
+ - Deepak Pandian ([rays2pix](https://huggingface.co/rays2pix))
24
+ - Nicholas Broad ([nbroad](https://huggingface.co/nbroad))
25
+
26
+ ## Dataset
27
+
28
+ [RecipeNLG: A Cooking Recipes Dataset for Semi-Structured Text Generation](https://recipenlg.cs.put.poznan.pl/). This dataset contains **2,231,142** cooking recipes (>2 millions) with size of **2.14 GB**. It's processed in more careful way.
29
+
30
+ ### Example
31
+
32
+ ```json
33
+ {
34
+ "NER": [
35
+ "oyster crackers",
36
+ "salad dressing",
37
+ "lemon pepper",
38
+ "dill weed",
39
+ "garlic powder",
40
+ "salad oil"
41
+ ],
42
+ "directions": [
43
+ "Combine salad dressing mix and oil.",
44
+ "Add dill weed, garlic powder and lemon pepper.",
45
+ "Pour over crackers; stir to coat.",
46
+ "Place in warm oven.",
47
+ "Use very low temperature for 15 to 20 minutes."
48
+ ],
49
+ "ingredients": [
50
+ "12 to 16 oz. plain oyster crackers",
51
+ "1 pkg. Hidden Valley Ranch salad dressing mix",
52
+ "1/4 tsp. lemon pepper",
53
+ "1/2 to 1 tsp. dill weed",
54
+ "1/4 tsp. garlic powder",
55
+ "3/4 to 1 c. salad oil"
56
+ ],
57
+ "link": "www.cookbooks.com/Recipe-Details.aspx?id=648947",
58
+ "source": "Gathered",
59
+ "title": "Hidden Valley Ranch Oyster Crackers"
60
+ }
61
+ ```
62
+
63
+ ## How To Use
64
+
65
+ ```bash
66
+ # Installing requirements
67
+ pip install transformers
68
+ ```
69
+
70
+ ```python
71
+ from transformers import FlaxAutoModelForSeq2SeqLM
72
+ from transformers import AutoTokenizer
73
+
74
+ MODEL_NAME_OR_PATH = "flax-community/t5-recipe-generation"
75
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME_OR_PATH, use_fast=True)
76
+ model = FlaxAutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME_OR_PATH)
77
+
78
+ prefix = "items: "
79
+ # generation_kwargs = {
80
+ # "max_length": 512,
81
+ # "min_length": 64,
82
+ # "no_repeat_ngram_size": 3,
83
+ # "early_stopping": True,
84
+ # "num_beams": 5,
85
+ # "length_penalty": 1.5,
86
+ # }
87
+ generation_kwargs = {
88
+ "max_length": 512,
89
+ "min_length": 64,
90
+ "no_repeat_ngram_size": 3,
91
+ "do_sample": True,
92
+ "top_k": 60,
93
+ "top_p": 0.95
94
+ }
95
+
96
+
97
+ special_tokens = tokenizer.all_special_tokens
98
+ tokens_map = {
99
+ "<sep>": "--",
100
+ "<section>": "\n"
101
+ }
102
+ def skip_special_tokens(text, special_tokens):
103
+ for token in special_tokens:
104
+ text = text.replace(token, "")
105
+
106
+ return text
107
+
108
+ def target_postprocessing(texts, special_tokens):
109
+ if not isinstance(texts, list):
110
+ texts = [texts]
111
+
112
+ new_texts = []
113
+ for text in texts:
114
+ text = skip_special_tokens(text, special_tokens)
115
+
116
+ for k, v in tokens_map.items():
117
+ text = text.replace(k, v)
118
+
119
+ new_texts.append(text)
120
+
121
+ return new_texts
122
+
123
+ def generation_function(texts):
124
+ _inputs = texts if isinstance(texts, list) else [texts]
125
+ inputs = [prefix + inp for inp in _inputs]
126
+ inputs = tokenizer(
127
+ inputs,
128
+ max_length=256,
129
+ padding="max_length",
130
+ truncation=True,
131
+ return_tensors="jax"
132
+ )
133
+
134
+ input_ids = inputs.input_ids
135
+ attention_mask = inputs.attention_mask
136
+
137
+ output_ids = model.generate(
138
+ input_ids=input_ids,
139
+ attention_mask=attention_mask,
140
+ **generation_kwargs
141
+ )
142
+ generated = output_ids.sequences
143
+ generated_recipe = target_postprocessing(
144
+ tokenizer.batch_decode(generated, skip_special_tokens=False),
145
+ special_tokens
146
+ )
147
+ return generated_recipe
148
+ ```
149
+
150
+ ```python
151
+ items = [
152
+ "macaroni, butter, salt, bacon, milk, flour, pepper, cream corn",
153
+ "provolone cheese, bacon, bread, ginger"
154
+ ]
155
+ generated = generation_function(items)
156
+ for text in generated:
157
+ sections = text.split("\n")
158
+ for section in sections:
159
+ section = section.strip()
160
+ if section.startswith("title:"):
161
+ section = section.replace("title:", "")
162
+ headline = "TITLE"
163
+ elif section.startswith("ingredients:"):
164
+ section = section.replace("ingredients:", "")
165
+ headline = "INGREDIENTS"
166
+ elif section.startswith("directions:"):
167
+ section = section.replace("directions:", "")
168
+ headline = "DIRECTIONS"
169
+
170
+ if headline == "TITLE":
171
+ print(f"[{headline}]: {section.strip().capitalize()}")
172
+ else:
173
+ section_info = [f" - {i+1}: {info.strip().capitalize()}" for i, info in enumerate(section.split("--"))]
174
+ print(f"[{headline}]:")
175
+ print("\n".join(section_info))
176
+
177
+ print("-" * 130)
178
+ ```
179
+
180
+ Output:
181
+ ```text
182
+ [TITLE]: Macaroni and corn
183
+ [INGREDIENTS]:
184
+ - 1: 2 c. macaroni
185
+ - 2: 2 tbsp. butter
186
+ - 3: 1 tsp. salt
187
+ - 4: 4 slices bacon
188
+ - 5: 2 c. milk
189
+ - 6: 2 tbsp. flour
190
+ - 7: 1/4 tsp. pepper
191
+ - 8: 1 can cream corn
192
+ [DIRECTIONS]:
193
+ - 1: Cook macaroni in boiling salted water until tender.
194
+ - 2: Drain.
195
+ - 3: Melt butter in saucepan.
196
+ - 4: Blend in flour, salt and pepper.
197
+ - 5: Add milk all at once.
198
+ - 6: Cook and stir until thickened and bubbly.
199
+ - 7: Stir in corn and bacon.
200
+ - 8: Pour over macaroni and mix well.
201
+ --------------------------------------------------------------------------------------------------------------------------------
202
+ [TITLE]: Grilled provolone and bacon sandwich
203
+ [INGREDIENTS]:
204
+ - 1: 2 slices provolone cheese
205
+ - 2: 2 slices bacon
206
+ - 3: 2 slices sourdough bread
207
+ - 4: 2 slices pickled ginger
208
+ [DIRECTIONS]:
209
+ - 1: Place a slice of provolone cheese on one slice of bread.
210
+ - 2: Top with a slice of bacon.
211
+ - 3: Top with a slice of pickled ginger.
212
+ - 4: Top with the other slice of bread.
213
+ - 5: Heat a skillet over medium heat.
214
+ - 6: Place the sandwich in the skillet and cook until the cheese is melted and the bread is golden brown.
215
+ --------------------------------------------------------------------------------------------------------------------------------
216
+ ```
217
+
218
+ ## Evaluation
219
+ ...
220
+
221
+ ### Result
222
+ Since the test set is not available, we will evaluate the model based on a shared test set. This test set consists of 5% of the whole test (*= 5,000 records*),
223
+ and we will generate five recipes for each input(*= 25,000 records*).
224
+ The following table summarizes the scores obtained by the **Chef Transformer** and **RecipeNLG** as our baseline.
225
+
226
+ | Model | COSIM | WER | ROUGE-2 | BLEU | GLEU | METEOR |
227
+ |:--------------------------------------------------------------------------------:|:----------:|:----------:|:----------:|:----------:|:----------:|:----------:|
228
+ | [RecipeNLG](https://huggingface.co/mbien/recipenlg) | 0.5723 | 1.2125 | 0.1354 | 0.1164 | 0.1503 | 0.2309 |
229
+ | [Chef Transformer](https://huggingface.co/flax-community/t5-recipe-generation) * | **0.7282** | **0.7613** | **0.2470** | **0.3245** | **0.2624** | **0.4150** |
230
+
231
+ *From the 5 generated recipes corresponding to each NER (food items), only the highest score was taken into account in the WER, COSIM, and ROUGE metrics. At the same time, BLEU, GLEU, Meteor were designed to have many possible references.*
232
+
233
+ ## Streamlit demo
234
+
235
+ ```bash
236
+ streamlit run app.py
237
+ ```
238
+
239
+ ## Looking to contribute?
240
+ Then follow the steps mentioned in this [contributing guide](CONTRIBUTING.md) and you are good to go.
241
+
242
+ ## Copyright
243
+
244
+ Special thanks to those who provided these fantastic materials.
245
+ - [Anatomy](https://www.flaticon.com/free-icon)
246
+ - [Chef Hat](https://www.vecteezy.com/members/jellyfishwater)
247
+ - [Moira Nazzari](https://pixabay.com/photos/food-dessert-cake-eggs-butter-3048440/)
248
+ - [Instagram Post](https://www.freepik.com/free-psd/recipes-ad-social-media-post-template_11520617.htm)
app.py ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ import torch
4
+ from transformers import pipeline, set_seed
5
+ from transformers import AutoTokenizer
6
+
7
+ from PIL import (
8
+ ImageFont,
9
+ )
10
+
11
+ import os
12
+ import re
13
+ import random
14
+ import textwrap
15
+ from examples import EXAMPLES
16
+ import dummy
17
+ import meta
18
+ from utils import ext
19
+ from utils.api import generate_cook_image
20
+ from utils.draw import generate_food_with_logo_image, generate_recipe_image
21
+ from utils.st import (
22
+ remote_css,
23
+ local_css,
24
+
25
+ )
26
+ from utils.utils import (
27
+ load_image_from_url,
28
+ load_image_from_local,
29
+ image_to_base64,
30
+ pure_comma_separation
31
+ )
32
+
33
+
34
+ class TextGeneration:
35
+ def __init__(self):
36
+ self.debug = False
37
+ self.dummy_outputs = dummy.recipes
38
+ self.tokenizer = None
39
+ self.generator = None
40
+ self.api_ids = []
41
+ self.api_keys = []
42
+ self.api_test = 2
43
+ self.task = "text2text-generation"
44
+ self.model_name_or_path = "flax-community/t5-recipe-generation"
45
+ self.color_frame = "#ffffff"
46
+ self.main_frame = "asset/frame/recipe-bg.png"
47
+ self.no_food = "asset/frame/no_food.png"
48
+ self.logo_frame = "asset/frame/logo.png"
49
+ self.chef_frames = {
50
+ "scheherazade": "asset/frame/food-image-logo-bg-s.png",
51
+ "giovanni": "asset/frame/food-image-logo-bg-g.png",
52
+ }
53
+ self.fonts = {
54
+ "title": ImageFont.truetype("asset/fonts/Poppins-Bold.ttf", 70),
55
+ "sub_title": ImageFont.truetype("asset/fonts/Poppins-Medium.ttf", 30),
56
+ "body_bold": ImageFont.truetype("asset/fonts/Montserrat-Bold.ttf", 22),
57
+ "body": ImageFont.truetype("asset/fonts/Montserrat-Regular.ttf", 18),
58
+
59
+ }
60
+ set_seed(42)
61
+
62
+ def _skip_special_tokens_and_prettify(self, text):
63
+ recipe_maps = {"<sep>": "--", "<section>": "\n"}
64
+ recipe_map_pattern = "|".join(map(re.escape, recipe_maps.keys()))
65
+
66
+ text = re.sub(
67
+ recipe_map_pattern,
68
+ lambda m: recipe_maps[m.group()],
69
+ re.sub("|".join(self.tokenizer.all_special_tokens), "", text)
70
+ )
71
+
72
+ data = {"title": "", "ingredients": [], "directions": []}
73
+ for section in text.split("\n"):
74
+ section = section.strip()
75
+ if section.startswith("title:"):
76
+ data["title"] = " ".join(
77
+ [w.strip().capitalize() for w in section.replace("title:", "").strip().split() if w.strip()]
78
+ )
79
+ elif section.startswith("ingredients:"):
80
+ data["ingredients"] = [s.strip() for s in section.replace("ingredients:", "").split('--')]
81
+ elif section.startswith("directions:"):
82
+ data["directions"] = [s.strip() for s in section.replace("directions:", "").split('--')]
83
+ else:
84
+ pass
85
+
86
+ return data
87
+
88
+ def load_pipeline(self):
89
+ self.tokenizer = AutoTokenizer.from_pretrained(self.model_name_or_path)
90
+ self.generator = pipeline(self.task, model=self.model_name_or_path, tokenizer=self.model_name_or_path)
91
+
92
+ def load_api(self):
93
+ app_ids = os.getenv("EDAMAM_APP_ID")
94
+ app_ids = app_ids.split(",") if app_ids else []
95
+ app_keys = os.getenv("EDAMAM_APP_KEY")
96
+ app_keys = app_keys.split(",") if app_keys else []
97
+
98
+ if len(app_ids) != len(app_keys):
99
+ self.api_ids = []
100
+ self.api_keys = []
101
+
102
+ self.api_ids = app_ids
103
+ self.api_keys = app_keys
104
+
105
+ def load(self):
106
+ self.load_api()
107
+ if not self.debug:
108
+ self.load_pipeline()
109
+
110
+ def prepare_frame(self, recipe, chef_name):
111
+ frame_path = self.chef_frames[chef_name.lower()]
112
+ food_logo = generate_food_with_logo_image(frame_path, self.logo_frame, recipe["image"])
113
+ frame = generate_recipe_image(
114
+ recipe,
115
+ self.main_frame,
116
+ food_logo,
117
+ self.fonts,
118
+ bg_color="#ffffff"
119
+ )
120
+ return frame
121
+
122
+ def generate(self, items, generation_kwargs):
123
+ recipe = self.dummy_outputs[0]
124
+ # recipe = self.dummy_outputs[random.randint(0, len(self.dummy_outputs) - 1)]
125
+
126
+ if not self.debug:
127
+ generation_kwargs["num_return_sequences"] = 1
128
+ # generation_kwargs["return_full_text"] = False
129
+ generation_kwargs["return_tensors"] = True
130
+ generation_kwargs["return_text"] = False
131
+
132
+ generated_ids = self.generator(
133
+ items,
134
+ **generation_kwargs,
135
+ )[0]["generated_token_ids"]
136
+ recipe = self.tokenizer.decode(generated_ids, skip_special_tokens=False)
137
+ recipe = self._skip_special_tokens_and_prettify(recipe)
138
+
139
+ if self.api_ids and self.api_keys and len(self.api_ids) == len(self.api_keys):
140
+ test = 0
141
+ for i in range(len(self.api_keys)):
142
+ if test > self.api_test:
143
+ recipe["image"] = None
144
+ break
145
+ image = generate_cook_image(recipe["title"].lower(), self.api_ids[i], self.api_keys[i])
146
+ test += 1
147
+ if image:
148
+ recipe["image"] = image
149
+ break
150
+ else:
151
+ recipe["image"] = None
152
+
153
+ return recipe
154
+
155
+ def generate_frame(self, recipe, chef_name):
156
+ return self.prepare_frame(recipe, chef_name)
157
+
158
+
159
+ @st.cache(allow_output_mutation=True)
160
+ def load_text_generator():
161
+ generator = TextGeneration()
162
+ generator.load()
163
+ return generator
164
+
165
+
166
+ chef_top = {
167
+ "max_length": 512,
168
+ "min_length": 64,
169
+ "no_repeat_ngram_size": 3,
170
+ "do_sample": True,
171
+ "top_k": 60,
172
+ "top_p": 0.95,
173
+ "num_return_sequences": 1
174
+ }
175
+ chef_beam = {
176
+ "max_length": 512,
177
+ "min_length": 64,
178
+ "no_repeat_ngram_size": 3,
179
+ "early_stopping": True,
180
+ "num_beams": 5,
181
+ "length_penalty": 1.5,
182
+ "num_return_sequences": 1
183
+ }
184
+
185
+
186
+ def main():
187
+ st.set_page_config(
188
+ page_title="Chef Transformer",
189
+ page_icon="🍲",
190
+ layout="wide",
191
+ initial_sidebar_state="expanded"
192
+ )
193
+ generator = load_text_generator()
194
+ # if hasattr(st, "session_state"):
195
+ # if 'get_random_frame' not in st.session_state:
196
+ # st.session_state.get_random_frame = generator.frames[0]
197
+ # else:
198
+ # get_random_frame = generator.frames[0]
199
+
200
+ remote_css("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&family=Poppins:wght@600&display=swap")
201
+ local_css("asset/css/style.css")
202
+
203
+ col1, col2 = st.columns([6, 4])
204
+ with col2:
205
+ st.image(load_image_from_local("asset/images/chef-transformer-transparent.png"), width=300)
206
+ st.markdown(meta.SIDEBAR_INFO, unsafe_allow_html=True)
207
+
208
+ with st.expander("Where did this story start?", expanded=True):
209
+ st.markdown(meta.STORY, unsafe_allow_html=True)
210
+
211
+ with col1:
212
+ st.markdown(meta.HEADER_INFO, unsafe_allow_html=True)
213
+
214
+ st.markdown(meta.CHEF_INFO, unsafe_allow_html=True)
215
+ chef = st.selectbox("Choose your chef", index=0, options=["Chef Scheherazade", "Chef Giovanni"])
216
+
217
+ prompts = list(EXAMPLES.keys()) + ["Custom"]
218
+ prompt = st.selectbox(
219
+ 'Examples (select from this list)',
220
+ prompts,
221
+ # index=len(prompts) - 1,
222
+ index=0
223
+ )
224
+
225
+ if prompt == "Custom":
226
+ prompt_box = ""
227
+ else:
228
+ prompt_box = EXAMPLES[prompt]
229
+
230
+ items = st.text_area(
231
+ 'Insert your food items here (separated by `,`): ',
232
+ pure_comma_separation(prompt_box, return_list=False),
233
+ )
234
+ items = pure_comma_separation(items, return_list=False)
235
+ entered_items = st.empty()
236
+
237
+ recipe_button = st.button('Get Recipe!')
238
+
239
+ st.markdown(
240
+ "<hr />",
241
+ unsafe_allow_html=True
242
+ )
243
+ if recipe_button:
244
+ # if hasattr(st, "session_state"):
245
+ # st.session_state.get_random_frame = generator.frames[random.randint(0, len(generator.frames)) - 1]
246
+ # else:
247
+ # get_random_frame = generator.frames[random.randint(0, len(generator.frames)) - 1]
248
+
249
+ entered_items.markdown("**Generate recipe for:** " + items)
250
+ with st.spinner("Generating recipe..."):
251
+
252
+ if not isinstance(items, str) or not len(items) > 1:
253
+ entered_items.markdown(
254
+ f"**{chef}** would like to know what ingredients do you like to use in "
255
+ f"your food? "
256
+ )
257
+ else:
258
+ gen_kw = chef_top if chef == "Chef Scheherazade" else chef_beam
259
+ generated_recipe = generator.generate(items, gen_kw)
260
+
261
+ title = generated_recipe["title"]
262
+ food_image = generated_recipe["image"]
263
+ food_image = load_image_from_url(food_image, rgba_mode=True, default_image=generator.no_food)
264
+ food_image = image_to_base64(food_image)
265
+
266
+ ingredients = ext.ingredients(
267
+ generated_recipe["ingredients"],
268
+ pure_comma_separation(items, return_list=True)
269
+ )
270
+ # ingredients = [textwrap.fill(item, 10).replace("\n", "<br /> ") for item in ingredients]
271
+
272
+ directions = ext.directions(generated_recipe["directions"])
273
+ # directions = [textwrap.fill(item, 70).replace("\n", "<br /> ") for item in directions]
274
+
275
+ generated_recipe["by"] = chef
276
+
277
+ r1, r2 = st.columns([6, 2])
278
+
279
+ with r2:
280
+ # st.write(st.session_state.get_random_frame)
281
+ # if hasattr(st, "session_state"):
282
+ # recipe_post = generator.generate_frame(generated_recipe, st.session_state.get_random_frame)
283
+ # else:
284
+ # recipe_post = generator.generate_frame(generated_recipe, get_random_frame)
285
+
286
+ recipe_post = generator.generate_frame(generated_recipe, chef.split()[-1])
287
+
288
+ st.image(
289
+ recipe_post,
290
+ # width=500,
291
+ caption="Save image and share on your social media",
292
+ use_column_width="auto",
293
+ output_format="PNG"
294
+ )
295
+
296
+ with r1:
297
+ st.markdown(
298
+ " ".join([
299
+ "<div class='r-text-recipe'>",
300
+ "<div class='food-title'>",
301
+ f"<img src='{food_image}' />",
302
+ f"<h2 class='font-title text-bold'>{title}</h2>",
303
+ "</div>",
304
+ '<div class="divider"><div class="divider-mask"></div></div>',
305
+ "<h3 class='ingredients font-body text-bold'>Ingredients</h3>",
306
+ "<ul class='ingredients-list font-body'>",
307
+ " ".join([f'<li>{item}</li>' for item in ingredients]),
308
+ "</ul>",
309
+ "<h3 class='directions font-body text-bold'>Directions</h3>",
310
+ "<ol class='ingredients-list font-body'>",
311
+ " ".join([f'<li>{item}</li>' for item in directions]),
312
+ "</ol>",
313
+ "</div>"
314
+ ]),
315
+ unsafe_allow_html=True
316
+ )
317
+
318
+
319
+ if __name__ == '__main__':
320
+ main()
asset/css/style.css ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ background-color: #fff;
3
+ }
4
+
5
+ .font-title {
6
+ font-family: 'Poppins', sans-serif !important;
7
+ }
8
+ .font-body {
9
+ font-family: 'Montserrat', sans-serif !important;
10
+ }
11
+ .text-bold {
12
+ font-weight: normal !important;
13
+ }
14
+ .text-bold {
15
+ font-weight: bold !important;
16
+ }
17
+
18
+ .fullScreenFrame > div {
19
+ display: flex;
20
+ justify-content: center;
21
+ }
22
+ .comma:not(:empty) ~ .comma:not(:empty):before {
23
+ content: ", ";
24
+ }
25
+ .strong {
26
+ font-weight: bold;
27
+ }
28
+ .d-block {
29
+ display: block;
30
+ }
31
+ .extra-info {
32
+ font-weight: normal;
33
+ font-style: italic;
34
+ font-size: small;
35
+ }
36
+
37
+ .contributors {
38
+ margin-bottom: 10px;
39
+ border-bottom: 1px solid #f3f3f3;
40
+ padding-bottom: 10px;
41
+ }
42
+ .contributors a.contributor {
43
+ text-decoration: none;
44
+ color: #585858;
45
+ }
46
+ .contributors a.contributor:hover {
47
+ text-decoration: underline;
48
+ }
49
+
50
+ .story-box {
51
+ overflow-y: scroll;
52
+ max-height: 240px;
53
+ }
54
+
55
+ .story-box p {
56
+ font-size: 0.85rem;
57
+ }
58
+ .story-box pre {
59
+ font-size: 0.6rem;
60
+ }
61
+
62
+ .r-text-recipe {
63
+ /* padding-left: 30px;
64
+ margin-left: 10px;*/
65
+ border-right: 1px dashed #eee;
66
+ }
67
+
68
+ .divider {
69
+ margin: 5px 0;
70
+ width: 400px;
71
+ max-width: 100%;
72
+ position:relative;
73
+ }
74
+
75
+ .divider-mask {
76
+ overflow: hidden;
77
+ height: 20px;
78
+ }
79
+
80
+ .divider-mask:after {
81
+ content: '';
82
+ display: block;
83
+ width: 170px;
84
+ height: 0px;
85
+ border-bottom: 2px solid #e9a726;
86
+ border-radius: 10px;
87
+ left: 0px;
88
+ }
89
+
90
+ .r-text-recipe .food-title {
91
+ text-align: left;
92
+ }
93
+ .r-text-recipe .food-title img {
94
+ max-width: 300px;
95
+ float: left;
96
+ margin-right: 30px;
97
+ margin-bottom: 30px;
98
+ }
99
+ .r-text-recipe .food-title h2 {
100
+ }
101
+ .ingredients {}
102
+ .ingredients-list {
103
+ columns: 2;
104
+ -webkit-columns: 2;
105
+ -moz-columns: 2;
106
+ }
107
+ .directions {
108
+ clear: both;
109
+ float: none;
110
+ padding-top: 20px;
111
+ display: block;
112
+ }
113
+ .directions-list {}
114
+
115
+
116
+ @media only screen and (max-width: 600px) {
117
+ .r-text-recipe {
118
+ border-right: 0;
119
+ border-bottom: 1px dashed #eee;
120
+ }
121
+ .r-text-recipe .food-title img {
122
+ max-width: 200px;
123
+ }
124
+ .directions {
125
+ padding-top: 0px;
126
+ }
127
+ .ingredients-list {
128
+ columns: 1;
129
+ -webkit-columns: 1;
130
+ -moz-columns: 1;
131
+ }
132
+ }
asset/fonts/Montserrat-Bold.ttf ADDED
Binary file (244 kB). View file
 
asset/fonts/Montserrat-Regular.ttf ADDED
Binary file (246 kB). View file
 
asset/fonts/Poppins-Bold.ttf ADDED
Binary file (154 kB). View file
 
asset/fonts/Poppins-Medium.ttf ADDED
Binary file (156 kB). View file
 
asset/frame/export/food-image-logo.png ADDED
asset/frame/food-image-logo-background.png ADDED
asset/frame/food-image-logo-bg-g.png ADDED
asset/frame/food-image-logo-bg-s.png ADDED
asset/frame/food.jpg ADDED
asset/frame/logo.png ADDED
asset/frame/no_food.png ADDED
asset/frame/recipe-bg.png ADDED
asset/images/chef-transformer-transparent.png ADDED
asset/images/chef-transformer.png ADDED
asset/images/frames/1.jpg ADDED
asset/images/frames/10.jpg ADDED
asset/images/frames/2.jpg ADDED
asset/images/frames/3.jpg ADDED
asset/images/frames/4.jpg ADDED
asset/images/frames/5.jpg ADDED
asset/images/frames/6.jpg ADDED
asset/images/frames/7.jpg ADDED
asset/images/frames/8.jpg ADDED
asset/images/frames/9.jpg ADDED
asset/images/logo.png ADDED
asset/images/recipe-frame.png ADDED
asset/images/recipe-post.png ADDED
dummy.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ recipes = [
2
+ {
3
+ 'directions': [
4
+ "preheat oven to 350.",
5
+ "grease a 13 x 9 x 2 inch baking pan.",
6
+ "place 1 sheet of the dough on a work surface.",
7
+ "brush with melted butter.",
8
+ "top with another sheet of dough and brush with butter. repeat with 3 more sheets of dough, brushing each sheet with butter between each layer.",
9
+ "combine walnuts and cinnamon in a small bowl.",
10
+ "sprinkle half of the walnut mixture over the dough.",
11
+ "repeat with the remaining dough and walnut mixture.",
12
+ "starting at the long side, roll up the dough into a log.",
13
+ "cut the log into 1 inch slices.",
14
+ "arrange the slices, cut side down, in the prepared baking dish.",
15
+ "bake until golden brown, about 30 minutes.",
16
+ "meanwhile, bring water and honey to a boil.",
17
+ "remove from heat and stir in chocolate until melted.",
18
+ "pour over the cooled strudel.",
19
+ "serve warm or at room temperature.",
20
+ "makes 12 servings.",
21
+ ],
22
+ 'ingredients': [
23
+ "1 lb. phyllo dough, thawed 1 lb. phyllo dough, thawed",
24
+ "1 c. unsalted butter, melted",
25
+ "2 c chopped walnuts",
26
+ "1/2 tsp. cinnamon",
27
+ "1 1/2 c water",
28
+ "3/4 c honey",
29
+ "1/4 c melted chocolate",
30
+ ],
31
+ 'title': 'Baklava'
32
+ },
33
+ {
34
+ 'directions': [
35
+ "in a large skillet, heat oil to 375.",
36
+ "season chops on both sides with salt and pepper.",
37
+ "dredge chops in flour, shaking off excess.",
38
+ "dip chops into eggs, then coat with breadcrumbs.",
39
+ "fry chops until golden brown, about 3 minutes per side.",
40
+ "transfer to a platter and keep warm.",
41
+ "pour off all but 1 tablespoon of fat from skillet.",
42
+ "add gravy and cook over medium heat, stirring occasionally, until thickened, about 5 minutes.",
43
+ "spoon gravy over chops and sprinkle with parsley.",
44
+ "makes 4 servings.",
45
+ ],
46
+ 'ingredients': [
47
+ "1 lb beef, cubed",
48
+ "2 tablespoons oil",
49
+ "1 large onion, chopped",
50
+ "2 medium tomatoes, peeled and chopped",
51
+ "1 teaspoon turmeric powder",
52
+ "2 limes, juice of",
53
+ "1 cup water",
54
+ "salt",
55
+ "pepper",
56
+ "1 15 ounce can red beans, drained and rinsed",
57
+ "1 tablespoon dried herb",
58
+ ],
59
+ 'title': 'Beef And Red Beans'
60
+ },
61
+ {
62
+ 'directions': [
63
+ "heat the oil in a large saucepan.",
64
+ "add the onion and saute until golden brown.",
65
+ "stir in the tomatoes, turmeric powder, lime juice, water, salt and pepper.",
66
+ "bring to a boil.",
67
+ "reduce the heat and simmer for 10 minutes.",
68
+ "mix in the beef and beans.",
69
+ "cover and cook over low heat for 30 minutes or until the beef is tender.",
70
+ "garnish with the dried herbs.",
71
+ ],
72
+ 'ingredients': [
73
+ "oil for frying",
74
+ "4 6 oz. boneless pork loin chops",
75
+ "salt",
76
+ "pepper",
77
+ "1/2 c. flour",
78
+ "2 eggs, lightly beaten",
79
+ "2 tbsp. dry breadcrumbs",
80
+ "gravy",
81
+ "chopped parsley",
82
+ ],
83
+ 'title': 'Breaded Pork Chops With Gravy'
84
+ }
85
+ ]
examples.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ EXAMPLES = {
2
+ "Turkish Food 1": "phyllo dough, unsalted butter, walnuts, cinnamon, water, honey, melted chocolate",
3
+ "Persian Food 1": "beef, oil, onion, tomatoes, turmeric powder, limes, water, salt, pepper, red beans, herb",
4
+ "Persian Food 2": "beef, potatoes, eggs, onion, flour, turmeric powder, oil, salt, pepper",
5
+ "Persian Food 3": "walnut pieces, onion, boneless skinless chicken thighs, pomegranate molasses, orange juice, chicken stock, cinnamon, salt, pepper, oil",
6
+ "Turkish Food 2": "water, dry active yeast, flour, salt, olive oil, ground beef, onion, pepper, salt, feta cheese, parsley, lemon",
7
+ "Korean Food 1": "pork chops, soy sauce, honey, garlic, sesame oil, fresh ginger root, sweet chili sauce, olive oil",
8
+ "Italian Food 1": "rotini pasta, broccoli florets, parmesan cheese, red pepper, onions, black olives",
9
+ "German Food 1": "oil, boneless pork chops, salt, pepper, flour, eggs, breadcrumbs, gravy, parsley"
10
+ }
meta.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ HEADER_INFO = """""".strip()
2
+ SIDEBAR_INFO = """
3
+ <div class="contributors font-body text-bold">
4
+ <a class="contributor comma" href="https://huggingface.co/m3hrdadfi">Mehrdad Farahani</a>
5
+ <a class="contributor comma" href="https://huggingface.co/dk-crazydiv">Kartik Godawat</a>
6
+ <a class="contributor comma" href="https://huggingface.co/hassiahk">Haswanth Aekula</a>
7
+ <a class="contributor comma" href="https://huggingface.co/rays2pix">Deepak Pandian</a>
8
+ <a class="contributor comma" href="https://huggingface.co/nbroad">Nicholas Broad</a>
9
+ </div>
10
+ """
11
+ CHEF_INFO = """
12
+ <h2 class="font-title">Welcome to our lovely restaurant! </h2>
13
+ <p class="strong font-body">
14
+ <span class="d-block extra-info">(We are at your service with two of the best chefs in the world: Chef Scheherazade,
15
+ Chef Giovanni. Scheherazade is known for being more creative whereas Giovanni is more meticulous.)</span>
16
+ </p>
17
+ """.strip()
18
+ PROMPT_BOX = "Add custom ingredients here (separated by `,`): "
19
+ STORY = """
20
+ <div class="story-box font-body">
21
+ <p>
22
+ Hello everyone 👋, I am <strong>Chef Transformer</strong>,
23
+ the owner of this restaurant. I was made by a group of <a href="https://huggingface.co/flax-community/t5-recipe-generation#team-members">NLP Engineers</a> to train my two prodigy recipe creators: <strong>Chef Scheherazade</strong> and <strong>Chef Giovanni</strong>.
24
+ Both of my students participated in my rigorous culinary program, <a href="https://huggingface.co/flax-community/t5-recipe-generation">T5 fine-tuning</a>,
25
+ to learn how to prepare exquisite cuisines from a wide variety of ingredients.
26
+ I've never been more proud of my students -- both can produce exceptional dishes but I regard Scheherazade as being <em>creative</em> while Giovanni is <em>meticulous</em>.
27
+ If you give each of them the same ingredients, they'll usually come up with something different. <br /><br />
28
+ At the start of the program the chefs read cookbooks containing thousands of recipes of varying difficulties and from cultures all over the world.
29
+ The NLP engineers helped guide the learning process so that the chefs could actually learn which ingredients work well together rather than just memorize recipes.
30
+ I trained my chefs by asking them to generate a title, a list of ingredients (including amounts!), and a list of directions after giving them just a simple list of food items.
31
+ </p>
32
+
33
+ <pre>[Inputs]
34
+ {food items*: separated by comma}
35
+
36
+ [Targets]
37
+ title: {TITLE} &lt;section>
38
+ ingredients: {INGREDIENTS: separated by &lt;sep>} &lt;section>
39
+ directions: {DIRECTIONS: separated by &lt;sep>}.
40
+ </pre>
41
+
42
+ <p>
43
+ <em>In the cookbooks (a.k.a <a href="https://huggingface.co/datasets/recipe_nlg">dataset</a>), the food items were referred to as NER. </em>
44
+ </p>
45
+ <p>
46
+ In the span of a week, my chefs went from spitting out nonsense to creating masterpieces.
47
+ Their learning rate was exceptionally high and each batch of recipes was better than the last. <br />
48
+ In their final exam, they achieved <a href="https://huggingface.co/flax-community/t5-recipe-generation#evaluation">high scores</a> 💯 in a
49
+ standardized industry test and established this restaurant 🍲. Please tell your friends and family about us!
50
+ We create each recipe with a smile on our faces 🤗 Everyone at the restaurant is grateful for the generous support of
51
+ HuggingFace and Google for hosting Flax Community week.
52
+ </p>
53
+
54
+ </div>
55
+ """.strip()
notes/Build Ingredients Vocab.ipynb ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 3,
6
+ "metadata": {
7
+ "ExecuteTime": {
8
+ "end_time": "2021-07-14T12:54:01.369853Z",
9
+ "start_time": "2021-07-14T12:49:27.961404Z"
10
+ }
11
+ },
12
+ "outputs": [
13
+ {
14
+ "name": "stderr",
15
+ "output_type": "stream",
16
+ "text": [
17
+ "Using custom data configuration default-fdc6acb780b42528\n"
18
+ ]
19
+ },
20
+ {
21
+ "name": "stdout",
22
+ "output_type": "stream",
23
+ "text": [
24
+ "Downloading and preparing dataset recipe_nlg/default (download: Unknown size, generated: 2.04 GiB, post-processed: Unknown size, total: 2.04 GiB) to /home/rtx/.cache/huggingface/datasets/recipe_nlg/default-fdc6acb780b42528/1.0.0/20c969e1192265af03a7186457bdb4a9109d5d68b92cad04c3ec894d6e5aee61...\n"
25
+ ]
26
+ },
27
+ {
28
+ "data": {
29
+ "application/vnd.jupyter.widget-view+json": {
30
+ "model_id": "",
31
+ "version_major": 2,
32
+ "version_minor": 0
33
+ },
34
+ "text/plain": [
35
+ "HBox(children=(IntProgress(value=1, bar_style='info', max=1), HTML(value='')))"
36
+ ]
37
+ },
38
+ "metadata": {},
39
+ "output_type": "display_data"
40
+ },
41
+ {
42
+ "name": "stdout",
43
+ "output_type": "stream",
44
+ "text": [
45
+ "\r",
46
+ "Dataset recipe_nlg downloaded and prepared to /home/rtx/.cache/huggingface/datasets/recipe_nlg/default-fdc6acb780b42528/1.0.0/20c969e1192265af03a7186457bdb4a9109d5d68b92cad04c3ec894d6e5aee61. Subsequent calls will reuse this data.\n"
47
+ ]
48
+ }
49
+ ],
50
+ "source": [
51
+ "from datasets import load_dataset\n",
52
+ "DATA_DIR = \"~/Downloads/dataset/\"\n",
53
+ "dataset = load_dataset(\"recipe_nlg\", data_dir=DATA_DIR)"
54
+ ]
55
+ },
56
+ {
57
+ "cell_type": "code",
58
+ "execution_count": 10,
59
+ "metadata": {
60
+ "ExecuteTime": {
61
+ "end_time": "2021-07-14T12:58:25.150105Z",
62
+ "start_time": "2021-07-14T12:55:27.486385Z"
63
+ }
64
+ },
65
+ "outputs": [
66
+ {
67
+ "name": "stderr",
68
+ "output_type": "stream",
69
+ "text": [
70
+ "100%|██████████| 2231142/2231142 [02:57<00:00, 12558.59it/s]\n"
71
+ ]
72
+ }
73
+ ],
74
+ "source": [
75
+ "from collections import Counter\n",
76
+ "from tqdm import tqdm\n",
77
+ "ctr = Counter()\n",
78
+ "\n",
79
+ "for row in tqdm(dataset[\"train\"]):\n",
80
+ " for item in row[\"ner\"]:\n",
81
+ " ctr[item] += 1"
82
+ ]
83
+ },
84
+ {
85
+ "cell_type": "code",
86
+ "execution_count": 23,
87
+ "metadata": {
88
+ "ExecuteTime": {
89
+ "end_time": "2021-07-14T13:02:09.315817Z",
90
+ "start_time": "2021-07-14T13:02:09.259046Z"
91
+ }
92
+ },
93
+ "outputs": [],
94
+ "source": [
95
+ "first_500 = list(set([x[0].lower() for x in ctr.most_common()[0:500]]))"
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "code",
100
+ "execution_count": 25,
101
+ "metadata": {
102
+ "ExecuteTime": {
103
+ "end_time": "2021-07-14T13:02:28.864546Z",
104
+ "start_time": "2021-07-14T13:02:28.856279Z"
105
+ }
106
+ },
107
+ "outputs": [
108
+ {
109
+ "data": {
110
+ "text/plain": [
111
+ "443"
112
+ ]
113
+ },
114
+ "execution_count": 25,
115
+ "metadata": {},
116
+ "output_type": "execute_result"
117
+ }
118
+ ],
119
+ "source": [
120
+ "len(first_500)"
121
+ ]
122
+ },
123
+ {
124
+ "cell_type": "code",
125
+ "execution_count": 26,
126
+ "metadata": {
127
+ "ExecuteTime": {
128
+ "end_time": "2021-07-14T13:02:53.656711Z",
129
+ "start_time": "2021-07-14T13:02:53.653868Z"
130
+ }
131
+ },
132
+ "outputs": [],
133
+ "source": [
134
+ "first_100 = sorted(first_500[:100])\n",
135
+ "next_100 = sorted(first_500[100:200])"
136
+ ]
137
+ },
138
+ {
139
+ "cell_type": "code",
140
+ "execution_count": 29,
141
+ "metadata": {
142
+ "ExecuteTime": {
143
+ "end_time": "2021-07-14T13:03:35.640538Z",
144
+ "start_time": "2021-07-14T13:03:35.634368Z"
145
+ }
146
+ },
147
+ "outputs": [],
148
+ "source": [
149
+ "d = {\n",
150
+ " \"first_100\": first_100,\n",
151
+ " \"next_100\": next_100\n",
152
+ "}"
153
+ ]
154
+ },
155
+ {
156
+ "cell_type": "code",
157
+ "execution_count": 31,
158
+ "metadata": {
159
+ "ExecuteTime": {
160
+ "end_time": "2021-07-14T13:03:52.682190Z",
161
+ "start_time": "2021-07-14T13:03:52.679624Z"
162
+ }
163
+ },
164
+ "outputs": [],
165
+ "source": [
166
+ "import json\n",
167
+ "with open(\"config.json\", \"w\") as f:\n",
168
+ " f.write(json.dumps(d))"
169
+ ]
170
+ },
171
+ {
172
+ "cell_type": "code",
173
+ "execution_count": null,
174
+ "metadata": {},
175
+ "outputs": [],
176
+ "source": []
177
+ }
178
+ ],
179
+ "metadata": {
180
+ "kernelspec": {
181
+ "display_name": "Python 3",
182
+ "language": "python",
183
+ "name": "python3"
184
+ },
185
+ "language_info": {
186
+ "codemirror_mode": {
187
+ "name": "ipython",
188
+ "version": 3
189
+ },
190
+ "file_extension": ".py",
191
+ "mimetype": "text/x-python",
192
+ "name": "python",
193
+ "nbconvert_exporter": "python",
194
+ "pygments_lexer": "ipython3",
195
+ "version": "3.7.1"
196
+ },
197
+ "toc": {
198
+ "base_numbering": 1,
199
+ "nav_menu": {},
200
+ "number_sections": true,
201
+ "sideBar": true,
202
+ "skip_h1_title": false,
203
+ "title_cell": "Table of Contents",
204
+ "title_sidebar": "Contents",
205
+ "toc_cell": false,
206
+ "toc_position": {},
207
+ "toc_section_display": true,
208
+ "toc_window_display": false
209
+ }
210
+ },
211
+ "nbformat": 4,
212
+ "nbformat_minor": 2
213
+ }
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ datasets==1.11.0
2
+ transformers==4.9.2
3
+ torch
4
+ Pillow
5
+ requests
utils.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import json
3
+ from PIL import Image
4
+ from io import BytesIO
5
+ import base64
6
+ import requests
7
+
8
+
9
+ def load_image_from_local(image_path, image_resize=None):
10
+ image = Image.open(image_path)
11
+
12
+ if isinstance(image_resize, tuple):
13
+ image = image.resize(image_resize)
14
+ return image
15
+
16
+
17
+ def load_image_from_url(image_url, rgba_mode=False, image_resize=None, default_image=None):
18
+ try:
19
+ image = Image.open(requests.get(image_url, stream=True).raw)
20
+
21
+ if rgba_mode:
22
+ image = image.convert("RGBA")
23
+
24
+ if isinstance(image_resize, tuple):
25
+ image = image.resize(image_resize)
26
+
27
+ except Exception as e:
28
+ image = None
29
+ if default_image:
30
+ image = load_image_from_local(default_image, image_resize=image_resize)
31
+
32
+ return image
33
+
34
+
35
+ def image_to_base64(image_array):
36
+ buffered = BytesIO()
37
+ image_array.save(buffered, format="PNG")
38
+ image_b64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
39
+ return f"data:image/png;base64, {image_b64}"
40
+
41
+
42
+ def load_text(text_path):
43
+ text = ''
44
+ with open(text_path) as f:
45
+ text = f.read()
46
+
47
+ return text
48
+
49
+
50
+ def load_json(json_path):
51
+ jdata = ''
52
+ with open(json_path) as f:
53
+ jdata = json.load(f)
54
+
55
+ return jdata
56
+
57
+
58
+ def local_css(css_path):
59
+ with open(css_path) as f:
60
+ st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
61
+
62
+
63
+ def remote_css(css_url):
64
+ st.markdown(f'<link href="{css_url}" rel="stylesheet">', unsafe_allow_html=True)
65
+
66
+
67
+ def unique_list(seq):
68
+ seen = set()
69
+ seen_add = seen.add
70
+ return [x for x in seq if not (x in seen or seen_add(x))]
71
+
72
+
73
+ def pure_comma_separation(list_str, return_list=True):
74
+ r = unique_list([item.strip() for item in list_str.lower().split(",") if item.strip()])
75
+ # r = list(set([x.strip() for x in list_str.strip().split(',') if len(x.strip()) > 0]))
76
+ if return_list:
77
+ return r
78
+ return ", ".join(r)
utils/__init__.py ADDED
File without changes
utils/api.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import requests
3
+
4
+
5
+ def generate_cook_image(query, app_id, app_key):
6
+ api_url = f"https://api.edamam.com/api/recipes/v2?type=public&q={query}&app_id={app_id}&app_key={app_key}&field=image"
7
+
8
+ try:
9
+ r = requests.get(api_url)
10
+ if r.status_code != 200:
11
+ return None
12
+
13
+ rj = r.json()
14
+ if "hits" not in rj or not len(rj["hits"]) > 0:
15
+ return None
16
+
17
+ data = rj["hits"]
18
+ data = data[random.randint(1, min(5, len(data) - 1))] if len(data) > 1 else data[0]
19
+
20
+ if "recipe" not in data or "image" not in data["recipe"]:
21
+ return None
22
+
23
+ image = data["recipe"]["image"]
24
+ return image
25
+ except Exception as e:
26
+ return None
utils/draw.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import (
2
+ Image,
3
+ ImageDraw
4
+ )
5
+ import textwrap
6
+ from utils.utils import load_image_from_url
7
+ from utils.ext import (
8
+ ingredients as ext_ingredients,
9
+ directions as ext_directions
10
+ )
11
+
12
+
13
+ # from .utils import load_image_from_url
14
+ # from .ext import (
15
+ # ingredients as ext_ingredients,
16
+ # directions as ext_directions
17
+ # )
18
+
19
+
20
+ def generate_food_with_logo_image(bg_path, logo_path, food_url, no_food="asset/frame/no_food.png"):
21
+ bg = Image.open(bg_path)
22
+ width, height = bg.size
23
+
24
+ logo = Image.open(logo_path)
25
+ logo_width, logo_height, logo_ratio, logo_rb, logo_mb = logo.size + (3, -20, 45)
26
+ logo_width, logo_height = (logo_width // logo_ratio, logo_height // logo_ratio)
27
+ logo = logo.resize((logo_width, logo_height))
28
+
29
+ food = load_image_from_url(food_url, rgba_mode=True, default_image=no_food)
30
+
31
+ food_width, food_height = (300, 300)
32
+ food = food.resize((food_width, food_height))
33
+
34
+ bg.paste(food, (0, 0), food)
35
+ bg.paste(logo, (width - logo_width - logo_rb, height - logo_height - logo_mb), logo)
36
+
37
+ return bg
38
+
39
+
40
+ def generate_recipe_image(
41
+ recipe_data,
42
+ bg_path,
43
+ food_logo_ia,
44
+ fonts,
45
+ bg_color="#ffffff"
46
+ ):
47
+ bg = Image.open(bg_path)
48
+ bg.paste(food_logo_ia, (50, 50), food_logo_ia)
49
+ bg_color = Image.new("RGBA", bg.size, bg_color)
50
+ bg_color.paste(bg, mask=bg)
51
+
52
+ im_editable = ImageDraw.Draw(bg_color)
53
+ im_editable.text(
54
+ (418, 30),
55
+ textwrap.fill(recipe_data["title"], 15).replace(" \n", "\n"),
56
+ (61, 61, 70),
57
+ font=fonts["title"],
58
+ )
59
+
60
+ im_editable.text(
61
+ (100, 450),
62
+ "Ingredients",
63
+ (61, 61, 70),
64
+ font=fonts["body_bold"],
65
+ )
66
+ ingredients = recipe_data["ingredients"]
67
+ ingredients = ext_ingredients(ingredients, [], without_mapping=True)
68
+ ingredients = [textwrap.fill(item, 30).replace("\n", "\n ") for item in ingredients]
69
+
70
+ im_editable.text(
71
+ (50, 520),
72
+ "\n".join([f"- {item}" for item in ingredients]),
73
+ (61, 61, 70),
74
+ font=fonts["body"],
75
+ )
76
+
77
+ im_editable.text(
78
+ (700, 450),
79
+ "Directions",
80
+ (61, 61, 70),
81
+ font=fonts["body_bold"],
82
+ )
83
+
84
+ directions = recipe_data["directions"]
85
+ directions = ext_directions(directions)
86
+ directions = [textwrap.fill(item, 70).replace("\n", "\n ").capitalize() for item in directions]
87
+
88
+ im_editable.text(
89
+ (430, 520),
90
+ "\n".join([f"{i + 1}. {item}" for i, item in enumerate(directions)]).strip(),
91
+ (61, 61, 70),
92
+ font=fonts["body"],
93
+ )
94
+ return bg_color
utils/ext.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from utils.utils import replace_regex
3
+ # from .utils import replace_regex
4
+
5
+ DEFAULT_MAP_DICT = {
6
+ " c ": " c. ",
7
+ ", chopped": " (chopped)",
8
+ ", crumbled": " (crumbled)",
9
+ ", thawed": " (thawed)",
10
+ ", melted": " (melted)",
11
+ }
12
+
13
+
14
+ def ingredient(text, map_dict):
15
+ if len(map_dict) > 0:
16
+ map_dict.update(**DEFAULT_MAP_DICT)
17
+ else:
18
+ map_dict = DEFAULT_MAP_DICT
19
+
20
+ text = replace_regex(text, map_dict)
21
+ text = re.sub(r"(\d)\s(\d\/\d)", r" \1+\2 ", text)
22
+ text = " ".join([word.strip() for word in text.split() if word.strip()])
23
+ return text
24
+
25
+
26
+ def ingredients(text_list, item_list, without_mapping=False):
27
+ map_dict = {
28
+ item: f'<span class="text-bold">{item}</span>' for item in list(map(lambda x: x.lower().strip(), item_list))
29
+ }
30
+ text_list = list(map(lambda x: x.lower(), text_list))
31
+
32
+ output = []
33
+ for text in text_list:
34
+ map_dict = map_dict if not without_mapping else {}
35
+ text = ingredient(text, map_dict)
36
+ output.append(text)
37
+
38
+ return output
39
+
40
+
41
+ def directions(text_list):
42
+ text_list = list(map(lambda x: x.lower().capitalize(), text_list))
43
+
44
+ return text_list
utils/st.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+
4
+ def local_css(css_path):
5
+ with open(css_path) as f:
6
+ st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
7
+
8
+
9
+ def remote_css(css_url):
10
+ st.markdown(f'<link href="{css_url}" rel="stylesheet">', unsafe_allow_html=True)
utils/utils.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import json
3
+ from io import BytesIO
4
+ from PIL import Image
5
+ import requests
6
+ import re
7
+
8
+
9
+ def load_image_from_local(image_path, image_resize=None):
10
+ image = Image.open(image_path)
11
+
12
+ if isinstance(image_resize, tuple):
13
+ image = image.resize(image_resize)
14
+ return image
15
+
16
+
17
+ def load_image_from_url(image_url, rgba_mode=False, image_resize=None, default_image=None):
18
+ try:
19
+ image = Image.open(requests.get(image_url, stream=True).raw)
20
+
21
+ if rgba_mode:
22
+ image = image.convert("RGBA")
23
+
24
+ if isinstance(image_resize, tuple):
25
+ image = image.resize(image_resize)
26
+
27
+ except Exception as e:
28
+ image = None
29
+ if default_image:
30
+ image = load_image_from_local(default_image, image_resize=image_resize)
31
+
32
+ return image
33
+
34
+
35
+ def load_text(text_path):
36
+ text = ''
37
+ with open(text_path) as f:
38
+ text = f.read()
39
+
40
+ return text
41
+
42
+
43
+ def load_json(json_path):
44
+ jdata = ''
45
+ with open(json_path) as f:
46
+ jdata = json.load(f)
47
+
48
+ return jdata
49
+
50
+
51
+ def image_to_base64(image_array):
52
+ buffered = BytesIO()
53
+ image_array.save(buffered, format="PNG")
54
+ image_b64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
55
+ return f"data:image/png;base64, {image_b64}"
56
+
57
+
58
+ def unique_list(seq):
59
+ seen = set()
60
+ seen_add = seen.add
61
+ return [x for x in seq if not (x in seen or seen_add(x))]
62
+
63
+
64
+ def pure_comma_separation(list_str, return_list=True):
65
+ r = unique_list([item.strip() for item in list_str.lower().split(",") if item.strip()])
66
+ if return_list:
67
+ return r
68
+ return ", ".join(r)
69
+
70
+
71
+ def replace_regex(text, map_dict):
72
+ pattern = "|".join(map(re.escape, map_dict.keys()))
73
+ return re.sub(pattern, lambda m: map_dict[m.group()], str(text))