

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Kode Inferensi Kustom dengan Layanan Hosting
<a name="your-algorithms-inference-code"></a>

Bagian ini menjelaskan bagaimana Amazon SageMaker AI berinteraksi dengan wadah Docker yang menjalankan kode inferensi Anda sendiri untuk layanan hosting. Gunakan informasi ini untuk menulis kode inferensi dan membuat gambar Docker. 

**Topics**
+ [Bagaimana SageMaker AI Menjalankan Gambar Inferensi Anda](#your-algorithms-inference-code-run-image)
+ [Bagaimana SageMaker AI Memuat Artefak Model Anda](#your-algorithms-inference-code-load-artifacts)
+ [Bagaimana Kontainer Anda Harus Menanggapi Permintaan Inferensi](#your-algorithms-inference-code-container-response)
+ [Bagaimana Kontainer Anda Harus Menanggapi Permintaan Pemeriksaan Kesehatan (Ping)](#your-algorithms-inference-algo-ping-requests)
+ [Kontrak Kontainer untuk Mendukung Kemampuan Streaming Dua Arah](#your-algorithms-inference-algo-bidi)
+ [Gunakan Private Docker Registry untuk Wadah Inferensi Real-Time](your-algorithms-containers-inference-private.md)

## Bagaimana SageMaker AI Menjalankan Gambar Inferensi Anda
<a name="your-algorithms-inference-code-run-image"></a>

Untuk mengonfigurasi wadah agar dijalankan sebagai executable, gunakan `ENTRYPOINT` instruksi dalam Dockerfile. Perhatikan hal-hal berikut: 
+ Untuk inferensi model, SageMaker AI menjalankan wadah sebagai:

  ```
  docker run image serve
  ```

  SageMaker AI mengganti `CMD` pernyataan default dalam wadah dengan menentukan `serve` argumen setelah nama gambar. `serve`Argumen mengesampingkan argumen yang Anda berikan dengan `CMD` perintah di Dockerfile.

   
+ SageMaker AI mengharapkan semua kontainer berjalan dengan pengguna root. Buat wadah Anda sehingga hanya menggunakan pengguna root. Saat SageMaker AI menjalankan penampung Anda, pengguna yang tidak memiliki akses tingkat root dapat menyebabkan masalah izin.

   
+ Kami menyarankan Anda menggunakan `exec` bentuk `ENTRYPOINT` instruksi:

  ```
  ENTRYPOINT ["executable", "param1", "param2"]
  ```

  Contoh:

  ```
  ENTRYPOINT ["python", "k_means_inference.py"]
  ```

  `exec`Bentuk `ENTRYPOINT` instruksi memulai eksekusi secara langsung, bukan sebagai anak dari. `/bin/sh` Ini memungkinkannya menerima sinyal seperti `SIGTERM` dan `SIGKILL` dari operasi SageMaker API, yang merupakan persyaratan. 

   

  Misalnya, saat Anda menggunakan [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateEndpoint.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateEndpoint.html)API untuk membuat titik akhir, SageMaker AI menyediakan jumlah instans komputasi HTML yang diperlukan oleh konfigurasi titik akhir, yang Anda tentukan dalam permintaan. SageMaker AI menjalankan wadah Docker pada instance tersebut. 

   

  Jika Anda mengurangi jumlah instance yang mendukung titik akhir (dengan memanggil [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UpdateEndpointWeightsAndCapacities.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UpdateEndpointWeightsAndCapacities.html)API), SageMaker AI menjalankan perintah untuk menghentikan wadah Docker pada instance yang sedang dihentikan. Perintah mengirimkan `SIGTERM` sinyal, kemudian mengirimkan `SIGKILL` sinyal tiga puluh detik kemudian.

   

  Jika Anda memperbarui titik akhir (dengan memanggil [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UpdateEndpoint.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_UpdateEndpoint.html)API), SageMaker AI meluncurkan kumpulan instance komputasi HTML lainnya dan menjalankan container Docker yang berisi kode inferensi Anda di dalamnya. Kemudian menjalankan perintah untuk menghentikan kontainer Docker sebelumnya. Untuk menghentikan kontainer Docker, perintah mengirimkan `SIGTERM` sinyal, lalu mengirimkan `SIGKILL` sinyal 30 detik kemudian. 

   
+ SageMaker AI menggunakan definisi kontainer yang Anda berikan dalam [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateModel.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateModel.html)permintaan untuk menyetel variabel lingkungan dan nama host DNS untuk penampung sebagai berikut:

   
  + Ini menetapkan variabel lingkungan menggunakan `ContainerDefinition.Environment` string-to-string peta.
  + Ini menetapkan nama host DNS menggunakan file. `ContainerDefinition.ContainerHostname`

     
+ Jika Anda berencana menggunakan perangkat GPU untuk inferensi model (dengan menentukan instance komputasi ML berbasis GPU dalam `CreateEndpointConfig` permintaan Anda), pastikan container Anda kompatibel. `nvidia-docker` Jangan bundel driver NVIDIA dengan gambar. Untuk informasi selengkapnya`nvidia-docker`, lihat [NVIDIA/NVIDIA-Docker](https://github.com/NVIDIA/nvidia-docker). 

   
+ Anda tidak dapat menggunakan `tini` penginisialisasi sebagai titik masuk Anda dalam wadah SageMaker AI karena dikacaukan oleh argumen `train` dan`serve`.

  

## Bagaimana SageMaker AI Memuat Artefak Model Anda
<a name="your-algorithms-inference-code-load-artifacts"></a>

Dalam permintaan [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateModel.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateModel.html)API Anda, Anda dapat menggunakan `S3DataSource` parameter `ModelDataUrl` atau untuk mengidentifikasi lokasi S3 tempat artefak model disimpan. SageMaker AI menyalin artefak model Anda dari lokasi S3 ke `/opt/ml/model` direktori untuk digunakan oleh kode inferensi Anda. Kontainer Anda memiliki akses hanya-baca ke. `/opt/ml/model` Jangan menulis ke direktori ini.

`ModelDataUrl`Harus menunjuk ke file tar.gz. Jika tidak, SageMaker AI tidak akan mengunduh file. 

Jika Anda melatih model Anda dalam SageMaker AI, artefak model disimpan sebagai file tar terkompresi tunggal di Amazon S3. Jika Anda melatih model Anda di luar SageMaker AI, Anda perlu membuat file tar terkompresi tunggal ini dan menyimpannya di lokasi S3. SageMaker AI mendekompresi file tar ini ke opt/ml/model direktori/sebelum penampung Anda dimulai.

Untuk menerapkan model besar, kami sarankan Anda mengikuti[Menyebarkan model yang tidak terkompresi](large-model-inference-uncompressed.md).

## Bagaimana Kontainer Anda Harus Menanggapi Permintaan Inferensi
<a name="your-algorithms-inference-code-container-response"></a>

Untuk mendapatkan kesimpulan, aplikasi klien mengirimkan permintaan POST ke titik akhir SageMaker AI. SageMaker AI meneruskan permintaan ke wadah, dan mengembalikan hasil inferensi dari wadah ke klien.

Untuk informasi selengkapnya tentang permintaan inferensi yang akan diterima container Anda, lihat tindakan berikut di *Referensi Amazon SageMaker AI API*:
+ [ InvokeEndpoint](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_runtime_InvokeEndpoint.html)
+ [ InvokeEndpointAsync](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_runtime_InvokeEndpointAsync.html)
+ [ InvokeEndpointWithResponseStream](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_runtime_InvokeEndpointWithResponseStream.html)
+ [ InvokeEndpointWithResponseStream](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_runtime_InvokeEndpointWithBidirectionalStream.html)

**Persyaratan untuk wadah inferensi**

Untuk menanggapi permintaan inferensi, kontainer Anda harus memenuhi persyaratan berikut:
+ SageMaker AI menghapus semua `POST` header kecuali yang didukung oleh`InvokeEndpoint`. SageMaker AI mungkin menambahkan header tambahan. Wadah inferensi harus dapat dengan aman mengabaikan header tambahan ini.
+ Untuk menerima permintaan inferensi, penampung harus memiliki server web yang mendengarkan pada port 8080 dan harus menerima `POST` permintaan ke `/invocations` dan `/ping` titik akhir. 
+ Kontainer model pelanggan harus menerima permintaan koneksi soket dalam 250 ms.
+ Kontainer model pelanggan harus menanggapi permintaan dalam waktu 60 detik. Model itu sendiri dapat memiliki waktu pemrosesan maksimum 60 detik sebelum merespons. `/invocations` Jika model Anda akan memakan waktu 50-60 detik waktu pemrosesan, batas waktu soket SDK harus disetel menjadi 70 detik.
+ Wadah model pelanggan yang mendukung streaming dua arah harus:
  + mendukung WebSockets koneksi pada port 8080 ke/secara invocations-bidirectional-stream default.
  + memiliki server web yang mendengarkan pada port 8080 dan harus menerima permintaan POST ke endpoint /ping.
  + Selain pemeriksaan kesehatan kontainer melalui HTTP, kontainer harus merespons dengan Pong Frame per ([RFC6455](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3)), untuk WebSocket Ping Frame dikirim.

**Example fungsi pemanggilan**  
Contoh berikut menunjukkan bagaimana kode dalam wadah Anda dapat memproses permintaan inferensi. Contoh-contoh ini menangani permintaan yang dikirim aplikasi klien dengan menggunakan InvokeEndpoint tindakan.  
FastAp adalah kerangka kerja web untuk membangun APIs dengan Python.  

```
from fastapi import FastAPI, status, Request, Response
. . .
app = FastAPI()
. . .
@app.post('/invocations')
async def invocations(request: Request):
    # model() is a hypothetical function that gets the inference output:
    model_resp = await model(Request)

    response = Response(
        content=model_resp,
        status_code=status.HTTP_200_OK,
        media_type="text/plain",
    )
    return response
. . .
```
Dalam contoh ini, `invocations` fungsi menangani permintaan inferensi yang dikirim SageMaker AI ke titik `/invocations` akhir.
Flask adalah kerangka kerja untuk mengembangkan aplikasi web dengan Python.  

```
import flask
. . .
app = flask.Flask(__name__)
. . .
@app.route('/invocations', methods=["POST"])
def invoke(request):
    # model() is a hypothetical function that gets the inference output:
    resp_body = model(request)
    return flask.Response(resp_body, mimetype='text/plain')
```
Dalam contoh ini, `invoke` fungsi menangani permintaan inferensi yang dikirim SageMaker AI ke titik `/invocations` akhir.

**Example fungsi pemanggilan untuk permintaan streaming**  
Contoh berikut menunjukkan bagaimana kode dalam wadah inferensi Anda dapat memproses permintaan inferensi streaming. Contoh-contoh ini menangani permintaan yang dikirim aplikasi klien dengan menggunakan InvokeEndpointWithResponseStream tindakan.  
Ketika sebuah wadah menangani permintaan inferensi streaming, ia mengembalikan inferensi model sebagai serangkaian bagian secara bertahap saat model menghasilkannya. Aplikasi klien mulai menerima tanggapan segera ketika tersedia. Mereka tidak perlu menunggu model untuk menghasilkan seluruh respons. Anda dapat menerapkan streaming untuk mendukung pengalaman interaktif yang cepat, seperti chatbots, asisten virtual, dan generator musik.  
FastAp adalah kerangka kerja web untuk membangun APIs dengan Python.  

```
from starlette.responses import StreamingResponse
from fastapi import FastAPI, status, Request
. . .
app = FastAPI()
. . .
@app.post('/invocations')
async def invocations(request: Request):
    # Streams inference response using HTTP chunked encoding
    async def generate():
        # model() is a hypothetical function that gets the inference output:
        yield await model(Request)
        yield "\n"

    response = StreamingResponse(
        content=generate(),
        status_code=status.HTTP_200_OK,
        media_type="text/plain",
    )
    return response
. . .
```
Dalam contoh ini, `invocations` fungsi menangani permintaan inferensi yang dikirim SageMaker AI ke titik `/invocations` akhir. Untuk streaming respon, contoh menggunakan `StreamingResponse` kelas dari kerangka Starlette.
Flask adalah kerangka kerja untuk mengembangkan aplikasi web dengan Python.  

```
import flask
. . .
app = flask.Flask(__name__)
. . .
@app.route('/invocations', methods=["POST"])
def invocations(request):
    # Streams inference response using HTTP chunked encoding

    def generate():
        # model() is a hypothetical function that gets the inference output:
        yield model(request)
        yield "\n"
    return flask.Response(
        flask.stream_with_context(generate()), mimetype='text/plain')
. . .
```
Dalam contoh ini, `invocations` fungsi menangani permintaan inferensi yang dikirim SageMaker AI ke titik `/invocations` akhir. Untuk mengalirkan respons, contoh menggunakan `flask.stream_with_context` fungsi dari kerangka Flask.

**Example Contoh fungsi pemanggilan untuk streaming dua arah**  
Contoh berikut menunjukkan bagaimana kode dalam container Anda dapat memproses permintaan dan tanggapan inferensi streaming. Contoh-contoh ini menangani permintaan streaming yang dikirim aplikasi klien dengan menggunakan InvokeEndpointWithBidirectionalStream tindakan.  
Kontainer dengan kemampuan streaming dua arah menangani permintaan inferensi streaming di mana bagian dibuat secara bertahap di klien dan dialirkan ke wadah. Ini mengembalikan inferensi model kembali ke klien sebagai serangkaian bagian saat model menghasilkannya. Aplikasi klien mulai menerima tanggapan segera ketika tersedia. Mereka tidak perlu menunggu permintaan yang dibuat sepenuhnya di klien atau model untuk menghasilkan seluruh respons. Anda dapat menerapkan streaming dua arah untuk mendukung pengalaman interaktif yang cepat, seperti chatbots, asisten AI suara interaktif, dan terjemahan waktu nyata untuk pengalaman yang lebih real-time.  
FastAp adalah kerangka kerja web untuk membangun APIs dengan Python.  

```
import sys
import asyncio
import json
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import JSONResponse
import uvicorn

app = FastAPI()
...
@app.websocket("/invocations-bidirectional-stream")
async def websocket_invoke(websocket: WebSocket):
    """
    WebSocket endpoint with RFC 6455 ping/pong and fragmentation support
    
    Handles:
    - Text messages (JSON) - including fragmented frames
    - Binary messages - including fragmented frames
    - Ping frames (automatically responds with pong)
    - Pong frames (logs receipt)
    - Fragmented frames per RFC 6455 Section 5.4
    """
    await manager.connect(websocket)
    
    # Fragment reassembly buffers per RFC 6455 Section 5.4
    text_fragments = []
    binary_fragments = []
    
    while True:
        # Use receive() to handle all WebSocket frame types
        message = await websocket.receive()
        print(f"Received message: {message}")
        if message["type"] == "websocket.receive":
            if "text" in message:
                # Handle text frames (including fragments)
                text_data = message["text"]
                more_body = message.get("more_body", False)
                
                if more_body:
                    # This is a fragment, accumulate it
                    text_fragments.append(text_data)
                    print(f"Received text fragment: {len(text_data)} chars (more coming)")
                else:
                    # This is the final frame or a complete message
                    if text_fragments:
                        # Reassemble fragmented message
                        text_fragments.append(text_data)
                        complete_text = "".join(text_fragments)
                        text_fragments.clear()
                        print(f"Reassembled fragmented text message: {len(complete_text)} chars total")
                        await handle_text_message(websocket, complete_text)
                    else:
                        # Complete message in single frame
                        await handle_text_message(websocket, text_data)
                
            elif "bytes" in message:
                # Handle binary frames (including fragments)
                binary_data = message["bytes"]
                more_body = message.get("more_body", False)
                
                if more_body:
                    # This is a fragment, accumulate it
                    binary_fragments.append(binary_data)
                    print(f"Received binary fragment: {len(binary_data)} bytes (more coming)")
                else:
                    # This is the final frame or a complete message
                    if binary_fragments:
                        # Reassemble fragmented message
                        binary_fragments.append(binary_data)
                        complete_binary = b"".join(binary_fragments)
                        binary_fragments.clear()
                        print(f"Reassembled fragmented binary message: {len(complete_binary)} bytes total")
                        await handle_binary_message(websocket, complete_binary)
                    else:
                        # Complete message in single frame
                        await handle_binary_message(websocket, binary_data)
                
        elif message["type"] == "websocket.ping":
            # Handle ping frames - RFC 6455 Section 5.5.2
            ping_data = message.get("bytes", b"")
            print(f"Received PING frame with payload: {ping_data}")
            # FastAPI automatically sends pong response
            
        elif message["type"] == "websocket.pong":
            # Handle pong frames
            pong_data = message.get("bytes", b"")
            print(f"Received PONG frame with payload: {pong_data}")
            
        elif message["type"] == "websocket.close":
            # Handle close frames - RFC 6455 Section 5.5.1
            close_code = message.get("code", 1000)
            close_reason = message.get("reason", "")
            print(f"Received CLOSE frame - Code: {close_code}, Reason: '{close_reason}'")
            
            # Send close frame response if not already closing
            try:
                await websocket.close(code=close_code, reason=close_reason)
                print(f"Sent CLOSE frame response - Code: {close_code}")
            except Exception as e:
                print(f"Error sending close frame: {e}")
            break
            
        elif message["type"] == "websocket.disconnect":
            print("Client initiated disconnect")
            break

        else:
            print(f"Received unknown message type: {message['type']}")
            break

                        
async def handle_binary_message(websocket: WebSocket, binary_data: bytes):
    """Handle incoming binary messages (complete or reassembled from fragments)"""
    print(f"Processing complete binary message: {len(binary_data)} bytes")
    
    try:
        # Echo back the binary data
        await websocket.send_bytes(binary_data)
    except Exception as e:
        print(f"Error handling binary message: {e}")

async def handle_text_message(websocket: WebSocket, data: str):
    """Handle incoming text messages"""
    try:
        # Send response back to the same client
        await manager.send_personal_message(data, websocket)
    except Exception as e:
        print(f"Error handling text message: {e}")

def main():
    if len(sys.argv) > 1 and sys.argv[1] == "serve":
        print("Starting server on port 8080...")
        uvicorn.run(app, host="0.0.0.0", port=8080)
    else:
        print("Usage: python app.py serve")
        sys.exit(1)

if __name__ == "__main__":
    main()
```
Dalam contoh ini, `websocket_invoke` fungsi menangani permintaan inferensi yang dikirim SageMaker AI ke titik `/invocations-bidirectional-stream` akhir. Ini menunjukkan penanganan permintaan aliran dan respons aliran kembali ke klien.

## Bagaimana Kontainer Anda Harus Menanggapi Permintaan Pemeriksaan Kesehatan (Ping)
<a name="your-algorithms-inference-algo-ping-requests"></a>

SageMaker AI meluncurkan wadah inferensi baru dalam situasi berikut:
+ Menanggapi`CreateEndpoint`,`UpdateEndpoint`, dan panggilan `UpdateEndpointWeightsAndCapacities` API
+ Membuat patch keamanan
+ Mengganti instance yang tidak sehat

Segera setelah startup kontainer, SageMaker AI mulai mengirim permintaan GET berkala ke `/ping` titik akhir.

Persyaratan paling sederhana pada wadah adalah merespons dengan kode status HTTP 200 dan badan kosong. Ini menunjukkan kepada SageMaker AI bahwa wadah siap menerima permintaan inferensi di titik `/invocations` akhir.

Jika wadah tidak mulai lulus pemeriksaan kesehatan dengan merespons secara konsisten dengan 200s selama 8 menit setelah startup, peluncuran instance baru gagal. Hal ini `CreateEndpoint` menyebabkan kegagalan, meninggalkan titik akhir dalam keadaan gagal. Pembaruan yang diminta oleh `UpdateEndpoint` tidak selesai, patch keamanan tidak diterapkan, dan instance yang tidak sehat tidak diganti.

Sementara bilah minimum adalah wadah mengembalikan 200 statis, pengembang kontainer dapat menggunakan fungsi ini untuk melakukan pemeriksaan lebih dalam. Batas waktu permintaan pada `/ping` upaya adalah 2 detik.

Selain itu, wadah yang mampu menangani permintaan streaming dua arah harus merespons dengan Pong Frame (per WebSocket protokol [RFC6455](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3)) ke Ping Frame. Jika tidak ada Pong Frame yang diterima selama 5 Ping berturut-turut, koneksi ke kontainer akan ditutup oleh platform AI. SageMaker SageMaker Platform AI juga akan menanggapi Ping Frames dari wadah model dengan Pong Frames.

## Kontrak Kontainer untuk Mendukung Kemampuan Streaming Dua Arah
<a name="your-algorithms-inference-algo-bidi"></a>

Jika Anda ingin meng-host container model Anda sebagai titik akhir SageMaker AI yang mendukung kemampuan streaming dua arah, wadah model harus mendukung kontrak di bawah ini:

**1. Label Docker Dua Arah**

Wadah model harus memiliki label Docker yang menunjukkan ke platform SageMaker AI bahwa kemampuan streaming dua arah didukung pada wadah ini.

```
com.amazonaws.sagemaker.capabilities.bidirectional-streaming=true
```

**2. Support WebSocket Connection untuk pemanggilan**

Kontainer model pelanggan yang mendukung streaming dua arah harus mendukung WebSockets koneksi pada port 8080 secara default. `/invocations-bidirectional-stream` 

Jalur ini dapat diganti dengan meneruskan header X-Amzn-SageMaker-Model -Invocation-Path saat menjalankan API. InvokeEndpointWithBidirectionalStream Selain itu, pengguna dapat menentukan string kueri yang akan ditambahkan ke jalur ini dengan meneruskan header X-Amzn-SageMaker-Model -Query-String saat menjalankan API. InvokeEndpointWithBidirectionalStream 

**3. Minta Penanganan Stream**

<Blob>Muatan input InvokeEndpointWithBidirectionalStream API dialirkan sebagai serangkaian PayloadParts, yang hanya merupakan pembungkus potongan biner (“Bytes”:): ******

```
{
   "PayloadPart": { 
      "Bytes": <Blob>,
      "DataType": <String: UTF8 | BINARY>,
      "CompletionState": <String: PARTIAL | COMPLETE>
      "P": <String>
   }
}
```

**3.1. Bingkai Data**

SageMaker AI meneruskan input PayloadParts ke wadah Model sebagai Bingkai WebSocket Data ([RFC6455-Bagian-5.6)](https://datatracker.ietf.org/doc/html/rfc6455#section-5.6)

1. SageMaker AI tidak memeriksa ke dalam potongan biner.

1. Saat menerima masukan PayloadPart
   + SageMaker AI membuat persis satu WebSocket Data Frame dari`PayloadPart.Bytes`, lalu meneruskannya ke wadah model.
   + Jika`PayloadPart.DataType = UTF8`, SageMaker AI membuat Bingkai Data Teks
   + Jika `PayloadPart.DataType` tidak ada atau`PayloadPart.DataType = BINARY`, SageMaker AI membuat Bingkai Data Biner

1. Untuk urutan dengan`PayloadPart.CompletionState = PARTIAL`, dan diakhiri PayloadParts dengan PayloadPart dengan`PayloadPart.CompletionState = COMPLETE`, SageMaker AI menerjemahkannya menjadi pesan WebSocket terfragmentasi [RFC6455-Bagian-5.4](https://datatracker.ietf.org/doc/html/rfc6455#section-5.4): Fragmentasi:
   + Awal PayloadPart dengan `PayloadPart.CompletionState = PARTIAL` akan diterjemahkan ke dalam Bingkai WebSocket Data, dengan FIN sedikit jelas.
   + Selanjutnya PayloadParts dengan `PayloadPart.CompletionState = PARTIAL` akan diterjemahkan ke dalam WebSocket Continuation Frames dengan FIN bit clear.
   + Final PayloadPart dengan `PayloadPart.CompletionState = COMPLETE` akan diterjemahkan ke dalam WebSocket Continuation Frame dengan set bit FIN.

1. SageMaker AI tidak menyandikan atau mendekode potongan biner dari input PayloadPart, byte diteruskan ke wadah model apa adanya.

1. SageMaker AI tidak menggabungkan beberapa input PayloadParts menjadi satu BinaryDataFrame.

1. SageMaker AI tidak memotong satu input PayloadPart menjadi beberapa BinaryDataFrames.

**Contoh: Alur Pesan Terfragmentasi**

```
Client sends:
PayloadPart 1: {Bytes: "Hello ", DataType: "UTF8", CompletionState: "PARTIAL"}
PayloadPart 2: {Bytes: "World", DataType: "UTF8", CompletionState: "COMPLETE"}

Container receives:
Frame 1: Text Data Frame with "Hello " (FIN=0)
Frame 2: Continuation Frame with "World" (FIN=1)
```

**3.2. Bingkai Kontrol**

Selain Data Frames, SageMaker AI juga mengirimkan Control Frames ke wadah model ([RFC6455-Section-5.5](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5)):

1. Tutup Bingkai: SageMaker AI dapat mengirim Close Frame ([RFC6455-Section-5.5.1](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1)) ke wadah model jika koneksi ditutup karena alasan apa pun.

1. Ping Frame: SageMaker AI mengirim Ping Frame ([RFC6455-Section-5.5.2](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2)) setiap 60 detik sekali, wadah model harus merespons dengan Pong Frame. Jika tidak ada Pong Frame ([RFC6455-Section-5.5.3](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3)) yang diterima selama 5 Ping berturut-turut, koneksi akan ditutup oleh AI. SageMaker 

1. Pong Frame: SageMaker AI akan merespons Ping Frames dari wadah model dengan Pong Frames.

**4. Penanganan Stream Respons**

Output dialirkan keluar sebagai serangkaian PayloadParts, ModelStreamErrors atau InternalStreamFailures.

```
{   
   "PayloadPart": { 
      "Bytes": <Blob>,
      "DataType": <String: UTF8 | BINARY>,
      "CompletionState": <String: PARTIAL | COMPLETE>,
   },
   "ModelStreamError": {
      "ErrorCode": <String>,
      "Message": <String>
   },
   "InternalStreamFailure": {
      "Message": <String>
   }
}
```

**4.1. Bingkai Data**

SageMaker AI mengonversi Data Frames yang diterima dari wadah model menjadi output PayloadParts:

1. Saat menerima Bingkai Data WebSocket Teks dari wadah model, SageMaker AI mendapatkan byte mentah dari Bingkai Data Teks, dan membungkusnya menjadi respons PayloadPart, sementara itu disetel. `PayloadPart.DataType = UTF8`

1. Saat menerima Bingkai Data WebSocket Biner dari wadah model, SageMaker AI langsung membungkus byte dari bingkai data menjadi respons PayloadPart, sementara itu ditetapkan. `PayloadPart.DataType = BINARY`

1. Untuk pesan terfragmentasi seperti yang didefinisikan dalam [RFC6455-Section-5.4](https://datatracker.ietf.org/doc/html/rfc6455#section-5.4): Fragmentasi:
   + Data Frame awal dengan FIN bit clear akan diterjemahkan ke dalam PayloadPart with`PayloadPart.CompletionState = PARTIAL`.
   + Bingkai Kelanjutan berikutnya dengan bit FIN jelas akan diterjemahkan ke dalam PayloadParts dengan`PayloadPart.CompletionState = PARTIAL`.
   + Bingkai Kelanjutan akhir dengan set bit FIN akan diterjemahkan ke dalam PayloadPart dengan`PayloadPart.CompletionState = COMPLETE`.

1. SageMaker AI tidak menyandikan atau memecahkan kode byte yang diterima dari wadah model, byte diteruskan ke wadah model apa adanya.

1. SageMaker AI tidak menggabungkan beberapa Data Frames yang diterima dari wadah model menjadi satu respons PayloadPart.

1. SageMaker AI tidak memotong Data Frame yang diterima dari wadah model menjadi beberapa respons PayloadParts.

**Contoh: Aliran Respon Streaming**

```
Container sends:
Frame 1: Text Data Frame with "Generating" (FIN=0)
Frame 2: Continuation Frame with " response..." (FIN=1)

Client receives:
PayloadPart 1: {Bytes: "Generating", DataType: "UTF8", CompletionState: "PARTIAL"}
PayloadPart 2: {Bytes: " response...", DataType: "UTF8", CompletionState: "COMPLETE"}
```

**4.2. Bingkai Kontrol**

SageMaker AI merespons Control Frames berikut dari wadah model:

1. Saat menerima Close Frame ([RFC6455-Section-5.5.1](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1)) dari wadah model, SageMaker AI akan membungkus kode status ([RFC6455-Section-7.4](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4)) dan pesan kegagalan ke dalam, dan mengalirkannya kembali ke ModelStreamError pengguna akhir.

1. Saat menerima Ping Frame ([RFC6455-Section-5.5.2](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2)) dari wadah model, SageMaker AI akan merespons dengan Pong Frame.

1. Pong Frame ([RFC6455-Section-5.5.3](https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3)): Jika tidak ada Pong Frame yang diterima selama 5 Ping berturut-turut, koneksi akan ditutup oleh AI. SageMaker 