diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..64f23e0770da589d2949e1c24149405f5eda3d68
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,28 @@
+*.7z filter=lfs diff=lfs merge=lfs -text
+*.arrow filter=lfs diff=lfs merge=lfs -text
+*.bin filter=lfs diff=lfs merge=lfs -text
+*.bin.* filter=lfs diff=lfs merge=lfs -text
+*.bz2 filter=lfs diff=lfs merge=lfs -text
+*.ftz filter=lfs diff=lfs merge=lfs -text
+*.gz filter=lfs diff=lfs merge=lfs -text
+*.h5 filter=lfs diff=lfs merge=lfs -text
+*.joblib filter=lfs diff=lfs merge=lfs -text
+*.lfs.* filter=lfs diff=lfs merge=lfs -text
+*.model filter=lfs diff=lfs merge=lfs -text
+*.msgpack filter=lfs diff=lfs merge=lfs -text
+*.onnx filter=lfs diff=lfs merge=lfs -text
+*.ot filter=lfs diff=lfs merge=lfs -text
+*.parquet filter=lfs diff=lfs merge=lfs -text
+*.pb filter=lfs diff=lfs merge=lfs -text
+*.pt filter=lfs diff=lfs merge=lfs -text
+*.pth filter=lfs diff=lfs merge=lfs -text
+*.rar filter=lfs diff=lfs merge=lfs -text
+saved_model/**/* filter=lfs diff=lfs merge=lfs -text
+*.tar.* filter=lfs diff=lfs merge=lfs -text
+*.tflite filter=lfs diff=lfs merge=lfs -text
+*.tgz filter=lfs diff=lfs merge=lfs -text
+*.wasm filter=lfs diff=lfs merge=lfs -text
+*.xz filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
+*.zstandard filter=lfs diff=lfs merge=lfs -text
+*tfevents* filter=lfs diff=lfs merge=lfs -text
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f91a85067f2cd099a0d4d72a356b36027f3d128c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+---
+title: Flask + dev server
+emoji: ⚗️
+colorFrom: gray
+colorTo: gray
+sdk: gradio
+sdk_version: 2.9.1
+python_version: 3.10.4
+app_file: app.py
+models:
+- osanseviero/BigGAN-deep-128
+- t5-small
+datasets:
+- emotion
+license: mit
+pinned: false
+duplicated_from: templates/flask
+---
+
+Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
diff --git a/app.py b/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f888759232c16cced6c464d3f7e31fe7bed896a
--- /dev/null
+++ b/app.py
@@ -0,0 +1,60 @@
+import os
+import requests
+import json
+from io import BytesIO
+
+from flask import Flask, jsonify, render_template, request, send_file
+
+from modules.inference import infer_t5
+from modules.dataset import query_emotion
+
+# https://huggingface.co/settings/tokens
+# https://huggingface.co/spaces/{username}/{space}/settings
+API_TOKEN = os.getenv("BIG_GAN_TOKEN")
+
+app = Flask(__name__)
+
+
+@app.route("/")
+def index():
+ return render_template("index.html")
+
+
+@app.route("/infer_biggan")
+def biggan():
+ input = request.args.get("input")
+
+ output = requests.request(
+ "POST",
+ "https://api-inference.huggingface.co/models/osanseviero/BigGAN-deep-128",
+ headers={"Authorization": f"Bearer {API_TOKEN}"},
+ data=json.dumps(input),
+ )
+
+ return send_file(BytesIO(output.content), mimetype="image/png")
+
+
+@app.route("/infer_t5")
+def t5():
+ input = request.args.get("input")
+
+ output = infer_t5(input)
+
+ return jsonify({"output": output})
+
+
+@app.route("/query_emotion")
+def emotion():
+ start = request.args.get("start")
+ end = request.args.get("end")
+
+ print(start)
+ print(end)
+
+ output = query_emotion(int(start), int(end))
+
+ return jsonify({"output": output})
+
+
+if __name__ == "__main__":
+ app.run(host="0.0.0.0", port=7860)
diff --git a/modules/dataset.py b/modules/dataset.py
new file mode 100644
index 0000000000000000000000000000000000000000..066eb5b131ce4293c9ea9746db923e6b7d03964d
--- /dev/null
+++ b/modules/dataset.py
@@ -0,0 +1,19 @@
+from datasets import load_dataset
+
+dataset = load_dataset("go_emotions", split="train")
+
+emotions = dataset.info.features['labels'].feature.names
+
+def query_emotion(start, end):
+ rows = dataset[start:end]
+ texts, labels = [rows[k] for k in rows.keys()]
+
+ observations = []
+
+ for i, text in enumerate(texts):
+ observations.append({
+ "text": text,
+ "emotion": emotions[labels[i]],
+ })
+
+ return observations
diff --git a/modules/inference.py b/modules/inference.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbf5cce09c4dd0844bb300e7afb161a15f7b0149
--- /dev/null
+++ b/modules/inference.py
@@ -0,0 +1,11 @@
+from transformers import T5Tokenizer, T5ForConditionalGeneration
+
+tokenizer = T5Tokenizer.from_pretrained("t5-small")
+model = T5ForConditionalGeneration.from_pretrained("t5-small")
+
+
+def infer_t5(input):
+ input_ids = tokenizer(input, return_tensors="pt").input_ids
+ outputs = model.generate(input_ids)
+
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7b8d3797e6cb936cb9770418f23e86d753f93dd0
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,6 @@
+datasets==2.*
+flask==2.1.*
+requests==2.27.*
+sentencepiece==0.1.*
+torch==1.11.*
+transformers==4.*
diff --git a/static/index.js b/static/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..da58d658fda06c7aed1a8384db3cd19e5f8f7a3e
--- /dev/null
+++ b/static/index.js
@@ -0,0 +1,126 @@
+if (document.location.search.includes('dark-theme=true')) {
+ document.body.classList.add('dark-theme');
+}
+
+let cursor = 0;
+const RANGE = 5;
+const LIMIT = 16_000;
+
+const textToImage = async (text) => {
+ const inferenceResponse = await fetch(`infer_biggan?input=${text}`);
+ const inferenceBlob = await inferenceResponse.blob();
+
+ return URL.createObjectURL(inferenceBlob);
+};
+
+const translateText = async (text) => {
+ const inferResponse = await fetch(`infer_t5?input=${text}`);
+ const inferJson = await inferResponse.json();
+
+ return inferJson.output;
+};
+
+const queryDataset = async (start, end) => {
+ const queryResponse = await fetch(`query_emotion?start=${start}&end=${end}`);
+ const queryJson = await queryResponse.json();
+
+ return queryJson.output;
+};
+
+const updateTable = async (cursor, range = RANGE) => {
+ const table = document.querySelector('.dataset-output');
+
+ const fragment = new DocumentFragment();
+
+ const observations = await queryDataset(cursor, cursor + range);
+
+ for (const observation of observations) {
+ let row = document.createElement('tr');
+ let text = document.createElement('td');
+ let emotion = document.createElement('td');
+
+ text.textContent = observation.text;
+ emotion.textContent = observation.emotion;
+
+ row.appendChild(text);
+ row.appendChild(emotion);
+ fragment.appendChild(row);
+ }
+
+ table.innerHTML = '';
+
+ table.appendChild(fragment);
+
+ table.insertAdjacentHTML(
+ 'afterbegin',
+ `
+
+ text |
+ emotion |
+
+ `
+ );
+};
+
+const imageGenSelect = document.getElementById('image-gen-input');
+const imageGenImage = document.querySelector('.image-gen-output');
+const textGenForm = document.querySelector('.text-gen-form');
+const tableButtonPrev = document.querySelector('.table-previous');
+const tableButtonNext = document.querySelector('.table-next');
+
+imageGenSelect.addEventListener('change', async (event) => {
+ const value = event.target.value;
+
+ try {
+ imageGenImage.src = await textToImage(value);
+ imageGenImage.alt = value + ' generated from BigGAN AI model';
+ } catch (err) {
+ console.error(err);
+ }
+});
+
+textGenForm.addEventListener('submit', async (event) => {
+ event.preventDefault();
+
+ const textGenInput = document.getElementById('text-gen-input');
+ const textGenParagraph = document.querySelector('.text-gen-output');
+
+ try {
+ textGenParagraph.textContent = await translateText(textGenInput.value);
+ } catch (err) {
+ console.error(err);
+ }
+});
+
+tableButtonPrev.addEventListener('click', () => {
+ cursor = cursor > RANGE ? cursor - RANGE : 0;
+
+ if (cursor < RANGE) {
+ tableButtonPrev.classList.add('hidden');
+ }
+ if (cursor < LIMIT - RANGE) {
+ tableButtonNext.classList.remove('hidden');
+ }
+
+ updateTable(cursor);
+});
+
+tableButtonNext.addEventListener('click', () => {
+ cursor = cursor < LIMIT - RANGE ? cursor + RANGE : cursor;
+
+ if (cursor >= RANGE) {
+ tableButtonPrev.classList.remove('hidden');
+ }
+ if (cursor >= LIMIT - RANGE) {
+ tableButtonNext.classList.add('hidden');
+ }
+
+ updateTable(cursor);
+});
+
+textToImage(imageGenSelect.value)
+ .then((image) => (imageGenImage.src = image))
+ .catch(console.error);
+
+updateTable(cursor)
+ .catch(console.error);
diff --git a/static/style.css b/static/style.css
new file mode 100644
index 0000000000000000000000000000000000000000..6a3c98f8fab848caaaf7b844b24ce23c8c5c8dde
--- /dev/null
+++ b/static/style.css
@@ -0,0 +1,79 @@
+body {
+ --text: hsl(0 0% 15%);
+ padding: 2.5rem;
+ font-family: sans-serif;
+ color: var(--text);
+}
+body.dark-theme {
+ --text: hsl(0 0% 90%);
+ background-color: hsl(223 39% 7%);
+}
+
+main {
+ max-width: 80rem;
+ text-align: center;
+}
+
+section {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+a {
+ color: var(--text);
+}
+
+select, input, button, .text-gen-output {
+ padding: 0.5rem 1rem;
+}
+
+select, img, input {
+ margin: 0.5rem auto 1rem;
+}
+
+form {
+ width: 25rem;
+ margin: 0 auto;
+}
+
+input {
+ width: 70%;
+}
+
+button {
+ cursor: pointer;
+}
+
+.text-gen-output {
+ min-height: 1.2rem;
+ margin: 1rem;
+ border: 0.5px solid grey;
+}
+
+#dataset button {
+ width: 6rem;
+ margin: 0.5rem;
+}
+
+#dataset button.hidden {
+ visibility: hidden;
+}
+
+table {
+ max-width: 40rem;
+ text-align: left;
+ border-collapse: collapse;
+}
+
+thead {
+ font-weight: bold;
+}
+
+td {
+ padding: 0.5rem;
+}
+
+td:not(thead td) {
+ border: 0.5px solid grey;
+}
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..d7121e95522118e40ef0d7217228061d79250406
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,1929 @@
+
+
+
+
+
+ Flask 🤗 Space served with development server
+
+
+
+
+
+ Flask 🤗 Space served with development server
+
+ Image generation from Inference API
+
+ Model:
+ osanseviero/BigGAN-deep-128
+
+
+
+
+
+
+ Text generation from transformers library
+
+ Model:
+ t5-small
+
+
+
+
+ Dataset from datasets library
+
+ Dataset:
+ emotion
+
+
+
+
+
+
+
+
+
+
+