# Docker Space Pertama Anda: Generasi Teks dengan T5

Pada bagian-bagian berikut, Anda akan mempelajari dasar-dasar pembuatan Docker Space, konfigurasinya, dan penerapan kode Anda ke dalamnya. Kami akan membuat Space **Text Generation** dengan Docker yang akan digunakan untuk mendemonstrasikan model [google/flan-t5-small](https://huggingface.co/google/flan-t5-small), yang dapat menghasilkan teks berdasarkan beberapa teks masukan, dengan menggunakan FastAPI sebagai server.

Anda dapat menemukan versi lengkap dari yang di-host ini [di sini](https://huggingface.co/spaces/DockerTemplates/fastapi_t5).

## Buat Space Docker baru

Kita akan mulai dengan [membuat Space baru](https://huggingface.co/new-space) dan memilih **Docker** sebagai SDK kita.

Hugging Face Spaces adalah repositori Git, yang berarti Anda dapat bekerja pada Space Anda secara bertahap (dan kolaboratif) dengan mendorong commit. Lihat panduan [Mulai dengan Repositori](./repositories-getting-started) untuk mempelajari cara membuat dan mengedit file sebelum melanjutkan. Jika Anda lebih suka bekerja dengan UI, Anda juga dapat melakukan pekerjaan tersebut langsung di browser.

Memilih **Docker** sebagai SDK saat [membuat Space baru](https://huggingface.co/new-space) akan menginisialisasi Docker Space Anda dengan mengatur properti `sdk` menjadi `docker` di blok YAML file `README.md` Anda.

```yaml
sdk: docker
```

Anda dapat mengubah port aplikasi default Space Anda dengan mengatur properti `app_port` di blok YAML file `README.md` Anda. Port default adalah `7860`.

```yaml
app_port: 7860
```

## Tambahkan dependensi

Untuk Space **Text Generation**, kita akan membangun aplikasi FastAPI yang menampilkan model generasi teks bernama Flan T5. Untuk inferensi model, kita akan menggunakan [🤗 Transformers pipeline](https://huggingface.co/docs/transformers/pipeline_tutorial) untuk memakai model tersebut. Kita perlu memulai dengan menginstal beberapa dependensi. Hal ini dapat dilakukan dengan membuat file **requirements.txt** di repositori kita, dan menambahkan dependensi berikut ke dalamnya:

```
fastapi==0.74.*
requests==2.27.*
sentencepiece==0.1.*
torch==1.11.*
transformers==4.*
uvicorn[standard]==0.17.*
```

Dependensi ini akan diinstal dalam Dockerfile yang akan kita buat nanti.

## Buat aplikasi

Mari kita mulai prosesnya dengan aplikasi FastAPI dummy untuk memastikan bahwa kita dapat membuat endpoint yang berfungsi. Langkah pertama adalah membuat file aplikasi, dalam hal ini kita akan menamainya `main.py`.

```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World!"}
```

## Buat Dockerfile

Langkah utama untuk Docker Space adalah membuat Dockerfile. Anda dapat membaca lebih lanjut tentang Dockerfile [di sini](https://docs.docker.com/get-started/). Meskipun kami menggunakan FastAPI dalam tutorial ini, Dockerfile memberikan fleksibilitas besar bagi pengguna, memungkinkan Anda membangun generasi baru demo ML. Mari kita tulis Dockerfile untuk aplikasi kami

```Dockerfile
# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
# you will also find guides on how best to write your Dockerfile

FROM python:3.9

# The two following lines are requirements for the Dev Mode to be functional
# Learn more about the Dev Mode at https://huggingface.co/dev-mode-explorers
RUN useradd -m -u 1000 user
WORKDIR /app

COPY --chown=user ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt

COPY --chown=user . /app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]

```

Saat perubahan disimpan, Space akan dibangun ulang dan demo Anda seharusnya sudah aktif setelah beberapa detik! [Di sini](https://huggingface.co/spaces/DockerTemplates/fastapi_dummy) adalah contoh hasil pada tahap ini.

### Menguji secara lokal

**Tips untuk pengguna lanjutan (dapat dilewati):** Jika Anda mengembangkan secara lokal, ini adalah waktu yang tepat untuk melakukan `docker build` dan `docker run` untuk debug secara lokal, tetapi lebih mudah lagi untuk mendorong perubahan ke Hub dan melihat hasilnya!

```bash
docker build -t fastapi .
docker run  -it -p 7860:7860 fastapi
```

Jika Anda memiliki [Secrets](spaces-sdks-docker#secret-management), Anda dapat menggunakan `docker buildx` dan meneruskan secrets tersebut sebagai build arguments

```bash
export SECRET_EXAMPLE="my_secret_value"
docker buildx build --secret id=SECRET_EXAMPLE,env=SECRET_EXAMPLE -t fastapi .
```

dan jalankan dengan `docker run` dengan meneruskan rahasia sebagai variabel lingkungan

```bash
export SECRET_EXAMPLE="my_secret_value"
docker run -it -p 7860:7860 -e SECRET_EXAMPLE=$SECRET_EXAMPLE fastapi
```

## Menambahkan beberapa ML ke aplikasi kami

Seperti yang disebutkan sebelumnya, idenya adalah menggunakan model Flan T5 untuk generasi teks. Kita akan menambahkan beberapa HTML dan CSS untuk bidang input, jadi mari buat direktori bernama static dengan file `index.html`, `style.css`, dan `script.js`. Saat ini, struktur file Anda seharusnya terlihat seperti ini:

```bash
/static
/static/index.html
/static/script.js
/static/style.css
Dockerfile
main.py
README.md
requirements.txt
```

Mari kita lewati semua langkah untuk membuatnya berfungsi. Kami akan melewati beberapa detail CSS dan HTML. Anda dapat menemukan seluruh kode di tab Files and versions dari Space [DockerTemplates/fastapi_t5](https://huggingface.co/spaces/DockerTemplates/fastapi_t5).

1. Tulis endpoint FastAPI untuk melakukan inferensi

Kita akan menggunakan `pipeline` dari `transformers` untuk memuat model [google/flan-t5-small](https://huggingface.co/google/flan-t5-small). Kita akan mengatur endpoint bernama `infer_t5` yang menerima input dan menghasilkan keluaran dari panggilan inferensi

```python
from transformers import pipeline

pipe_flan = pipeline("text2text-generation", model="google/flan-t5-small")

@app.get("/infer_t5")
def t5(input):
    output = pipe_flan(input)
    return {"output": output[0]["generated_text"]}
```

2. Tulis `index.html` untuk memiliki formulir sederhana yang berisi kode halaman.

```html
<main>
  <section id="text-gen">
    <h2>Text generation using Flan T5</h2>
    <p>
      Model:
      <a
        href="https://huggingface.co/google/flan-t5-small"
        rel="noreferrer"
        target="_blank"
        >google/flan-t5-small
      </a>
    </p>
    <form class="text-gen-form">
      <label for="text-gen-input">Text prompt</label>
      <input
        id="text-gen-input"
        type="text"
        value="German: There are many ducks"
      />
      <button id="text-gen-submit">Submit</button>
      <p class="text-gen-output"></p>
    </form>
  </section>
</main>
```

3. Pada file `main.py`, pasang file statis dan tampilkan file html di rute akar

```python
app.mount("/", StaticFiles(directory="static", html=True), name="static")

@app.get("/")
def index() -> FileResponse:
    return FileResponse(path="/app/static/index.html", media_type="text/html")
```

4. Pada file `script.js`, buat agar menangani permintaan

```javascript
const textGenForm = document.querySelector(".text-gen-form");

const translateText = async (text) => {
  const inferResponse = await fetch(`infer_t5?input=${text}`);
  const inferJson = await inferResponse.json();

  return inferJson.output;
};

textGenForm.addEventListener("submit", async (event) => {
  event.preventDefault();

  const textGenInput = document.getElementById("text-gen-input");
  const textGenParagraph = document.querySelector(".text-gen-output");

  textGenParagraph.textContent = await translateText(textGenInput.value);
});
```

5. Beri izin ke direktori yang tepat

Seperti dibahas dalam [Bagian Izin](./spaces-sdks-docker#permissions), container berjalan dengan user ID 1000. Artinya, Space mungkin menghadapi masalah izin. Misalnya, `transformers` mengunduh dan meng-cache model di path di bawah path `HF_HOME`. Cara termudah untuk menyelesaikan ini adalah dengan membuat user dengan izin yang tepat dan menggunakannya untuk menjalankan aplikasi container. Kita dapat melakukan ini dengan menambahkan baris berikut ke `Dockerfile`.

```Dockerfile
# Switch to the "user" user
USER user

# Set home to the user's home directory
ENV HOME=/home/user \
	PATH=/home/user/.local/bin:$PATH
```

`Dockerfile` akhir harus terlihat seperti ini:

```Dockerfile

# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
# you will also find guides on how best to write your Dockerfile

FROM python:3.9

# The two following lines are requirements for the Dev Mode to be functional
# Learn more about the Dev Mode at https://huggingface.co/dev-mode-explorers
RUN useradd -m -u 1000 user
WORKDIR /app

COPY --chown=user ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt

COPY --chown=user . /app

USER user

ENV HOME=/home/user \
	PATH=/home/user/.local/bin:$PATH

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
```

Berhasil! Aplikasi Anda seharusnya sudah berfungsi sekarang! Lihat [DockerTemplates/fastapi_t5](https://huggingface.co/spaces/DockerTemplates/fastapi_t5) untuk melihat hasil akhirnya.

Apa sebuah perjalanan! Harap diingat bahwa Docker Spaces memberikan Anda banyak kebebasan, sehingga Anda tidak terbatas untuk menggunakan FastAPI. Dari [Go Endpoint](https://huggingface.co/spaces/DockerTemplates/test-docker-go) hingga [Shiny App](https://huggingface.co/spaces/DockerTemplates/shiny-with-python), batasnya adalah bulan! Lihat [beberapa contoh resmi](./spaces-sdks-docker-examples). Anda juga dapat meningkatkan Space Anda ke GPU jika diperlukan 😃

## Debugging

Anda dapat men-debug Space Anda dengan memeriksa log **Build** dan **Container**. Klik tombol **Open Logs** untuk membuka modal.

Jika semuanya berjalan lancar, Anda akan melihat `Pushing Image` dan `Scheduling Space` pada tab **Build**

Pada tab **Container**, Anda akan melihat status aplikasi, dalam hal ini, `Uvicorn running on http://0.0.0.0:7860`

Selain itu, Anda dapat mengaktifkan Dev Mode pada Space Anda. Dev Mode memungkinkan Anda terhubung ke Space yang sedang berjalan melalui VSCode atau SSH. Pelajari lebih lanjut di sini: https://huggingface.co/dev-mode-explorers

## Baca Selengkapnya

- [Ruang Docker](spaces-sdks-docker)
- [Daftar contoh Docker Spaces](spaces-sdks-docker-examples)

