All Products
Search
Document Center

Platform For AI:Panduan cepat Model Gallery

Last Updated:Jun 12, 2026

Model Gallery mengintegrasikan PAI-DLC dan PAI-EAS untuk mendukung penerapan dan pelatihan model bahasa besar open-source tanpa perlu menulis kode. Topik ini menjelaskan cara menerapkan, melakukan fine-tuning, dan mengevaluasi model Qwen3-0.6B.

1. Prasyarat

Untuk mengaktifkan PAI dan membuat ruang kerja, masuk ke Konsol PAI menggunakan Akun Alibaba Cloud Anda, pilih Wilayah di pojok kiri atas, lalu aktifkan layanan dengan otorisasi satu klik.

2. Penagihan

Contoh dalam topik ini menggunakan Sumber daya publik untuk membuat task PAI-DLC dan layanan PAI-EAS, yang dikenai biaya berdasarkan skema bayar sesuai penggunaan. Untuk detailnya, lihat Penagihan PAI-DLC dan Penagihan PAI-EAS.

3. Penerapan model

3.1 Terapkan model

  1. Masuk ke Konsol PAI. Di panel navigasi sebelah kiri, klik Model Gallery, cari kartu Qwen3-0.6B, lalu klik Deploy.

  2. Halaman konfigurasi telah diisi sebelumnya dengan parameter default. Klik Deploy > Confirm. Proses penerapan membutuhkan waktu sekitar lima menit. Penerapan berhasil ketika status berubah menjadi In operation.

    Secara default, model diterapkan menggunakan Sumber daya publik dan dikenai biaya berdasarkan skema bayar sesuai penggunaan.

    Spesifikasi sumber daya penerapan default adalah ecs.gn7i-c8g1.2xlarge (8 vCPU, 30 GiB, NVIDIA A10 × 1), yang berbiaya sekitar CNY 10,5/jam. Setelah meninjau konfigurasi, klik Deploy di bagian bawah panel.

3.2 Panggil model

  1. Lihat informasi pemanggilan. Di halaman detail layanan, klik View Call Information untuk mendapatkan Internet Endpoint dan Token.

    Untuk melihat detail job penerapan nanti, di panel navigasi sebelah kiri, klik Model Gallery > Job Management > Deployment Jobs. Lalu, klik Service name yang dituju.

    Di kotak dialog invocation information yang muncul, lihat Internet Endpoint dan VPC endpoint masing-masing di tab Shared Gateway dan VPC High-Speed Direct Connection.

  2. Panggil model menggunakan salah satu metode berikut.

    Online debugging

    Beralih ke halaman Online Debugging. Layanan model bahasa besar mendukung Conversation Debugging dan API Debugging.

    Klien Cherry Studio

    Cherry Studio adalah klien populer untuk berinteraksi dengan model bahasa besar. Klien ini mengintegrasikan fitur MCP, yang memungkinkan Anda berdialog dengan model secara mudah.

    Sambungkan ke model Qwen3 yang diterapkan di PAI

    Python SDK

    from openai import OpenAI
    import os
    # Jika Anda belum mengatur variabel lingkungan, Anda dapat langsung memberikan Token layanan Anda. Contoh: token = 'YTA1NTEzMzY3ZTY4Z******************'
    token = os.environ.get("Token")
    # Jangan hapus "/v1" di akhir endpoint.
    client = OpenAI(
        api_key=token,
        base_url=f'<your_endpoint>/v1',
    )
    if token is None:
        print("Harap konfigurasikan variabel lingkungan Token, atau tetapkan nilai token langsung ke variabel token.")
        exit()
    query = 'Hello, who are you?'
    messages = [{'role': 'user', 'content': query}]
    resp = client.chat.completions.create(model='Qwen3-0.6B', messages=messages, max_tokens=512, temperature=0)
    query = messages[0]['content']
    response = resp.choices[0].message.content
    print(f'query: {query}')
    print(f'response: {response}')

3.3 Pengingat penting

Layanan model ini menggunakan Sumber daya publik dan dikenai biaya berdasarkan skema bayar sesuai penggunaan. Untuk menghindari biaya yang tidak perlu, hentikan atau hapus layanan tersebut saat Anda tidak lagi membutuhkannya.

Anda dapat melakukannya di tab Job Management > Deployment Jobs, pada kolom Actions layanan yang dituju.

4. Fine-tuning model

Untuk meningkatkan performa model dalam domain tertentu, Anda dapat melakukan fine-tuning menggunakan set data spesifik domain. Bagian ini menyajikan skenario untuk menunjukkan tujuan dan langkah-langkah fine-tuning model.

4.1 Kasus penggunaan

Di industri logistik, Anda sering perlu mengekstraksi informasi terstruktur (seperti penerima, alamat, dan nomor telepon) dari teks bahasa alami. Model dengan parameter besar, seperti Qwen3-235B-A22B, bekerja baik dalam tugas ini tetapi mahal dan memiliki latensi tinggi. Untuk menyeimbangkan performa dan biaya, Anda dapat terlebih dahulu menggunakan model berparameter besar untuk memberi label data, lalu menggunakan data tersebut untuk melakukan fine-tuning pada model berparameter kecil, seperti Qwen3-0.6B, agar mencapai performa serupa dalam tugas tersebut. Proses ini juga dikenal sebagai distilasi model.

Pada tugas ini, model Qwen3-0.6B asli memiliki akurasi sebesar 50%. Setelah fine-tuning, akurasinya dapat melebihi 90%.

Contoh informasi alamat penerima

Contoh informasi terstruktur

Amina Patel - Nomor telepon (474) 598-1543 - 1425 S 5th St, Apt 3B, Allentown, Pennsylvania 18104

{
    "state": "Pennsylvania",
    "city": "Allentown",
    "zip_code": "18104",
    "street_address": "1425 S 5th St, Apt 3B",
    "name": "Amina Patel",
    "phone": "(474) 598-1543"
}

4.2 Persiapan data

Tugas ini melibatkan distilasi model dari model guru (Qwen3-235B-A22B) ke model Qwen3-0.6B. Pertama, Anda harus menggunakan API model guru untuk mengekstraksi informasi alamat penerima ke dalam data JSON terstruktur. Menghasilkan data JSON ini bisa memakan waktu. Oleh karena itu, artikel ini menyediakan training dataset contohtrain.json dan set validasieval.json yang dapat Anda unduh dan gunakan langsung.

Dalam distilasi model, model dengan lebih banyak parameter disebut model guru. Data yang digunakan dalam artikel ini dihasilkan secara sintetis oleh model besar dan tidak mengandung informasi pengguna sensitif apa pun.

Tayang

Untuk menerapkan solusi ini ke bisnis Anda, kami merekomendasikan Anda menyiapkan data menggunakan metode berikut:

Skema bisnis nyata (direkomendasikan)

Data bisnis nyata lebih mencerminkan skenario bisnis Anda, sehingga model yang telah difine-tuning dapat lebih baik beradaptasi dengan bisnis Anda. Setelah memperoleh data bisnis, Anda perlu mengonversinya secara programatik ke file JSON dalam format berikut.

[
    {
        "instruction": "Anda adalah asisten ahli untuk mengekstraksi JSON terstruktur dari informasi pengiriman AS. Kunci JSON-nya adalah name, street_address, city, state, zip_code, dan phone.  Nama: Isabella Rivera Cruz | 182 Calle Luis Lloréns Torres, Apt 3B, Mayagüez, Puerto Riko 00680 | PONSEL: (640) 486-5927",
        "output": "{\"name\": \"Isabella Rivera Cruz\", \"street_address\": \"182 Calle Luis Lloréns Torres, Apt 3B\", \"city\": \"Mayagüez\", \"state\": \"Puerto Riko\", \"zip_code\": \"00680\", \"phone\": \"(640) 486-5927\"}"
    },
    {
        "instruction": "Anda adalah asisten ahli untuk mengekstraksi JSON terstruktur dari informasi pengiriman AS. Kunci JSON-nya adalah name, street_address, city, state, zip_code, dan phone.  1245 Broadwater Avenue, Apt 3B, Bozeman, Montana 59715Penerima: Aisha PatelP: (429) 763-9742",
        "output": "{\"name\": \"Aisha Patel\", \"street_address\": \"1245 Broadwater Avenue, Apt 3B\", \"city\": \"Bozeman\", \"state\": \"Montana\", \"zip_code\": \"59715\", \"phone\": \"(429) 763-9742\"}"
    }
]

File JSON berisi beberapa sampel pelatihan. Setiap sampel mencakup dua bidang: instruction dan output.

  • instruction: Berisi prompt yang mengarahkan perilaku model besar, beserta data masukan.

  • output: Jawaban standar yang diharapkan, biasanya dihasilkan oleh pakar manusia atau model yang lebih besar seperti qwen3-235b-a22b.

Generasi model

Saat data bisnis tidak mencukupi, pertimbangkan menggunakan model untuk augmentasi data. Hal ini dapat meningkatkan keragaman dan cakupan data. Untuk menghindari kebocoran privasi pengguna, solusi ini menggunakan model untuk menghasilkan sejumlah data alamat virtual. Kode generasi berikut hanya sebagai referensi.

Kode untuk mensimulasikan generasi data bisnis

Untuk menjalankan kode berikut, Anda perlu membuat Kunci API Alibaba Cloud Model Studio. Kode ini menggunakan qwen-plus-latest untuk menghasilkan data bisnis dan qwen3-235b-a22b untuk pelabelan.

# -*- coding: utf-8 -*-
import os
import asyncio
import random
import json
import sys
from typing import List
import platform
from openai import AsyncOpenAI

# Buat instance klien asinkron.
# CATATAN: Skrip ini menggunakan endpoint API kompatibel DashScope.
# Jika Anda menggunakan layanan kompatibel OpenAI lain, ubah base_url-nya.
client = AsyncOpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

# Daftar Negara Bagian dan Wilayah AS.
us_states = [
    "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware",
    "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
    "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
    "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico",
    "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
    "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont",
    "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming", "District of Columbia",
    "Puerto Rico", "Guam", "American Samoa", "Kepulauan Virgin AS", "Kepulauan Mariana Utara"
]

# Template penerima.
recipient_templates = [
    "Kepada: {name}", "Penerima: {name}", "Kirim ke {name}", "Untuk: {name}",
    "ATTN: {name}", "{name}", "Nama: {name}", "Kontak: {name}", "Penerima: {name}"
]

# Template nomor telepon.
phone_templates = [
    "Tel: {phone}", "Tel. {phone}", "Ponsel: {phone}", "Telepon: {phone}",
    "Nomor kontak: {phone}", "Nomor telepon {phone}", "TEL: {phone}", "PONSEL: {phone}",
    "Kontak: {phone}", "P: {phone}", "{phone}", "Hubungi: {phone}",
]


# Hasilkan nomor telepon bergaya AS yang masuk akal.
def generate_us_phone():
    """Menghasilkan nomor telepon AS acak 10 digit dalam format (XXX) XXX-XXXX."""
    area_code = random.randint(201, 999)  # Hindari kode area 0xx, 1xx.
    exchange = random.randint(200, 999)
    line = random.randint(1000, 9999)
    return f"({area_code}) {exchange}-{line}"


# Gunakan LLM untuk menghasilkan informasi penerima dan alamat.
async def generate_recipient_and_address_by_llm(state: str):
    """Menggunakan LLM untuk menghasilkan nama penerima dan detail alamat untuk negara bagian tertentu."""
    prompt = f"""Harap hasilkan informasi penerima untuk lokasi di {state}, AS, termasuk:
1. Nama lengkap bahasa Inggris yang realistis. Upayakan keragaman.
2. Nama kota nyata dalam negara bagian tersebut.
3. Alamat jalan spesifik, seperti nomor dan nama jalan, serta nomor apartemen. Harus realistis.
4. Kode ZIP 5 digit yang sesuai untuk kota atau area tersebut.

Harap kembalikan hanya objek JSON dalam format berikut:
{{"name": "Nama Penerima", "city": "Nama Kota", "street_address": "Alamat Jalan Spesifik", "zip_code": "Kode ZIP"}}

Jangan sertakan teks lain, hanya JSON. Pastikan nama beragam, bukan hanya John Doe.
"""

    try:
        response = await client.chat.completions.create(
            messages=[{"role": "user", "content": prompt}],
            model="qwen-plus-latest",
            temperature=1.5,  # Tingkatkan suhu untuk nama dan alamat yang lebih beragam.
        )

        result = response.choices[0].message.content.strip()
        # Bersihkan penanda blok kode markdown yang mungkin ada.
        if result.startswith('```'):
            result = result.split('\n', 1)[1]
        if result.endswith('```'):
            result = result.rsplit('\n', 1)[0]

        # Coba uraikan JSON.
        info = json.loads(result)
        print(info)
        return info
    except Exception as e:
        print(f"Gagal menghasilkan penerima dan alamat: {e}, menggunakan cadangan.")
        # Mekanisme cadangan.
        backup_names = ["Michael Johnson", "Emily Williams", "David Brown", "Jessica Jones", "Christopher Davis",
                        "Sarah Miller"]
        return {
            "name": random.choice(backup_names),
            "city": "Anytown",
            "street_address": f"{random.randint(100, 9999)} Main St",
            "zip_code": f"{random.randint(10000, 99999)}"
        }


# Hasilkan satu catatan data mentah.
async def generate_record():
    """Menghasilkan satu string gabungan berantakan informasi alamat AS."""
    # Pilih negara bagian secara acak.
    state = random.choice(us_states)

    # Gunakan LLM untuk menghasilkan info penerima dan alamat.
    info = await generate_recipient_and_address_by_llm(state)

    # Format nama penerima.
    recipient = random.choice(recipient_templates).format(name=info['name'])

    # Hasilkan nomor telepon.
    phone = generate_us_phone()
    phone_info = random.choice(phone_templates).format(phone=phone)

    # Susun baris alamat lengkap.
    full_address = f"{info['street_address']}, {info['city']}, {state} {info['zip_code']}"

    # Gabungkan semua komponen.
    components = [recipient, phone_info, full_address]

    # Acak urutan komponen.
    random.shuffle(components)

    # Pilih pemisah acak.
    separators = [' ', ', ', '; ', ' | ', '\t', ' - ', ' // ', '', '  ']
    separator = random.choice(separators)

    # Gabungkan komponen.
    combined_data = separator.join(components)
    return combined_data.strip()


# Hasilkan batch data.
async def generate_batch_data(count: int) -> List[str]:
    """Menghasilkan jumlah catatan data tertentu."""
    print(f"Mulai menghasilkan {count} catatan...")

    # Gunakan semaphore untuk mengontrol konkurensi, misalnya hingga 20 permintaan konkuren.
    semaphore = asyncio.Semaphore(20)

    async def generate_single_record(index):
        async with semaphore:
            try:
                record = await generate_record()
                print(f"Catatan #{index + 1} dihasilkan: {record}")
                return record
            except Exception as e:
                print(f"Gagal menghasilkan catatan #{index + 1}: {e}")
                return None

    # Hasilkan data secara konkuren.
    tasks = [generate_single_record(i) for i in range(count)]

    data = await asyncio.gather(*tasks)

    successful_data = [record for record in data if record is not None]

    return successful_data


# Simpan data ke file.
def save_data(data: List[str], filename: str = "us_recipient_data.json"):
    """Menyimpan data yang dihasilkan ke file JSON."""
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    print(f"Data telah disimpan ke {filename}")


# Fase 1: Produksi Data.
async def produce_data_phase():
    """Menangani generasi data penerima mentah."""
    print("=== Fase 1: Memulai Generasi Data Penerima Mentah ===")

    # Hasilkan 2.000 catatan.
    batch_size = 2000
    data = await generate_batch_data(batch_size)

    # Simpan data.
    save_data(data, "us_recipient_data.json")

    print(f"\nTotal catatan yang dihasilkan: {len(data)}")
    print("\nData Contoh:")
    for i, record in enumerate(data[:3]):  # Tampilkan 3 pertama sebagai contoh.
        print(f"{i + 1}. Data Mentah: {record}\n")

    print("=== Fase 1 Selesai ===\n")
    return True


# Tentukan prompt sistem untuk model ekstraksi.
def get_system_prompt_for_extraction():
    """Mengembalikan prompt sistem untuk tugas ekstraksi informasi."""
    return """Anda adalah asisten ekstraksi informasi profesional yang berspesialisasi dalam mengurai alamat pengiriman AS dari teks tidak terstruktur.

## Deskripsi Tugas
Berdasarkan teks masukan yang diberikan, ekstrak dan hasilkan objek JSON yang berisi enam bidang berikut:
- name: Nama lengkap penerima.
- street_address: Alamat jalan lengkap, termasuk nomor, nama jalan, dan nomor apartemen atau suite apa pun.
- city: Nama kota.
- state: Nama lengkap negara bagian (misalnya, "California", bukan "CA").
- zip_code: Kode ZIP 5 atau 9 digit.
- phone: Nomor telepon kontak lengkap.

## Aturan Ekstraksi
1.  **Penanganan Alamat**:
    -   Identifikasi secara akurat komponen: jalan, kota, negara bagian, dan kode ZIP.
    -   Bidang `state` harus berupa nama resmi lengkap (misalnya, "New York", bukan "NY").
    -   `street_address` harus berisi semua detail sebelum kota, seperti "123 Apple Lane, Apt 4B".
2.  **Identifikasi Nama**:
    -   Ekstrak nama penerima lengkap.
3.  **Penanganan Nomor Telepon**:
    -   Ekstrak nomor telepon lengkap, mempertahankan format aslinya.
4.  **Kode ZIP**:
    -   Ekstrak kode 5 digit atau 9 digit (ZIP+4).

## Format Output
Patuhi secara ketat format JSON berikut. Jangan tambahkan teks penjelasan atau markdown.
{
  "name": "Nama Lengkap Penerima",
  "street_address": "Alamat Jalan Lengkap",
  "city": "Nama Kota",
  "state": "Nama Negara Bagian Lengkap",
  "zip_code": "Kode ZIP",
  "phone": "Nomor Telepon Kontak"
}
"""


# Gunakan LLM untuk memprediksi data terstruktur dari teks mentah.
async def predict_structured_data(raw_data: str):
    """Menggunakan LLM untuk memprediksi data terstruktur dari string mentah."""
    system_prompt = get_system_prompt_for_extraction()

    try:
        response = await client.chat.completions.create(
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": raw_data}
            ],
            model="qwen3-235b-a22b",  # Model kuat direkomendasikan untuk tugas ini.
            temperature=0.0,  # Suhu lebih rendah untuk akurasi ekstraksi yang lebih tinggi.
            response_format={"type": "json_object"},
            extra_body={"enable_thinking": False}
        )

        result = response.choices[0].message.content.strip()

        # Bersihkan penanda blok kode markdown yang mungkin ada.
        if result.startswith('```'):
            lines = result.split('\n')
            for i, line in enumerate(lines):
                if line.strip().startswith('{'):
                    result = '\n'.join(lines[i:])
                    break
        if result.endswith('```'):
            result = result.rsplit('\n```', 1)[0]

        structured_data = json.loads(result)
        return structured_data

    except Exception as e:
        print(f"Gagal memprediksi data terstruktur: {e}, Data mentah: {raw_data}")
        # Kembalikan struktur kosong jika gagal.
        return {
            "name": "",
            "street_address": "",
            "city": "",
            "state": "",
            "zip_code": "",
            "phone": ""
        }


# Fase 2: Konversi Data.
async def convert_data_phase():
    """Membaca data mentah, memprediksi format terstruktur, dan menyimpan sebagai data SFT."""
    print("=== Fase 2: Memulai Konversi Data ke Format SFT ===")

    try:
        print("Membaca file us_recipient_data.json...")
        with open('us_recipient_data.json', 'r', encoding='utf-8') as f:
            raw_data_list = json.load(f)

        print(f"Berhasil membaca {len(raw_data_list)} catatan.")
        print("Mulai memprediksi data terstruktur menggunakan model ekstraksi...")

        # Pesan sistem yang sederhana dan jelas dapat meningkatkan kecepatan pelatihan dan inferensi.
        system_prompt = "Anda adalah asisten ahli untuk mengekstraksi JSON terstruktur dari informasi pengiriman AS. Kunci JSON-nya adalah name, street_address, city, state, zip_code, dan phone."
        output_file = 'us_recipient_sft_data.json'

        # Gunakan semaphore untuk mengontrol konkurensi.
        semaphore = asyncio.Semaphore(10)

        async def process_single_item(index, raw_data):
            async with (semaphore):
                structured_data = await predict_structured_data(raw_data)
                print(f"Memproses catatan #{index + 1}: {raw_data}")

                conversation = {
                        "instruction": system_prompt + '  ' + raw_data,
                        "output": json.dumps(structured_data, ensure_ascii=False)
                }

                return conversation

        print(f"Memulai konversi ke {output_file}...")

        tasks = [process_single_item(i, raw_data) for i, raw_data in enumerate(raw_data_list)]
        conversations = await asyncio.gather(*tasks)

        with open(output_file, 'w', encoding='utf-8') as outfile:
            json.dump(conversations, outfile, ensure_ascii=False, indent=4)

        print(f"Konversi selesai! Diproses {len(raw_data_list)} catatan.")
        print(f"File output: {output_file}")
        print("=== Fase 2 Selesai ===")

    except FileNotFoundError:
        print("Kesalahan: us_recipient_data.json tidak ditemukan.")
        sys.exit(1)
    except json.JSONDecodeError as e:
        print(f"Kesalahan decoding JSON: {e}")
        sys.exit(1)
    except Exception as e:
        print(f"Terjadi kesalahan selama konversi: {e}")
        sys.exit(1)


# Fungsi utama.
async def main():
    print("Memulai pipeline pemrosesan data...")
    print("Program ini akan menjalankan dua fase secara berurutan:")
    print("1. Menghasilkan data penerima AS mentah.")
    print("2. Memprediksi data terstruktur dan mengonversinya ke format SFT.")
    print("-" * 50)

    # Fase 1: Hasilkan data.
    success = await produce_data_phase()

    if success:
        # Fase 2: Konversi data.
        await convert_data_phase()

        print("\n" + "=" * 50)
        print("Semua proses selesai dengan sukses!")
        print("File yang dihasilkan:")
        print("- us_recipient_data.json: Daftar data mentah tidak terstruktur.")
        print("- us_recipient_sft_data.json: Data pelatihan berformat SFT.")
        print("=" * 50)
    else:
        print("Fase generasi data gagal. Menghentikan.")


if __name__ == '__main__':
    # Atur kebijakan loop peristiwa untuk Windows jika diperlukan.
    if platform.system() == 'Windows':
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    # Jalankan korutin utama.
    asyncio.run(main(), debug=False)

4.3 Fine-tune model

  1. Di panel navigasi sebelah kiri, klik Model Gallery. Cari kartu Qwen3-0.6B dan klik Fine-tune.

  2. Konfigurasikan parameter untuk job pelatihan. Konfigurasikan hanya parameter kunci berikut dan pertahankan nilai default untuk yang lainnya.

    • Training Mode: Pilihan default adalah SFT (Supervised Fine-Tuning) menggunakan metode LoRA.

      LoRA adalah teknik fine-tuning efisien yang menghemat sumber daya pelatihan dengan hanya memodifikasi subset parameter model.
    • Training dataset: Pertama, unduh training dataset contoh train.json. Lalu, di halaman konfigurasi, pilih OSS file or directory, klik ikon image untuk memilih bucket, klik Upload File untuk mengunggah dataset yang telah diunduh ke Object Storage Service (OSS), lalu pilih file tersebut.

    • Validate dataset: Pertama, unduh dataset validasi eval.json. Lalu, klik Add validation dataset dan ikuti prosedur yang sama seperti untuk training dataset untuk mengunggah dan memilih file.

      Dataset validasi mengevaluasi performa model pada data yang belum pernah dilihat selama pelatihan.
    • Model output path: Secara default, sistem menyimpan model yang telah difine-tuning ke OSS. Jika direktori OSS target kosong, klik Create folder dan pilih direktori yang baru dibuat.

    • Resource Group Type: Pilih Public Resource Group. Task fine-tuning ini memerlukan sekitar 5 GB Memori GPU. Konsol telah memfilter tipe instans yang memenuhi persyaratan ini. Pilih tipe instans, seperti ecs.gn7i-c16g1.4xlarge.

    • Hyperparameters:

      • learning_rate: Atur ke 0,0005

      • num_train_epochs: Atur ke 4

      • per_device_train_batch_size: Atur ke 8

      • seq_length: Atur ke 512

      Lalu, klik Train > OK. Job pelatihan memasuki status Creating. Saat status berubah menjadi In operation, fine-tuning model dimulai.

  3. Lihat job pelatihan hingga selesai. Proses fine-tuning membutuhkan waktu sekitar 10 menit. Selama waktu ini, halaman detail job menampilkan log dan kurva metrik. Setelah job pelatihan selesai, sistem menyimpan model yang telah difine-tuning ke direktori OSS yang ditentukan.

    Untuk melihat detail job pelatihan nanti, di panel navigasi sebelah kiri, klik Model Gallery > Job Management > Training Jobs, lalu klik nama job.

    (Opsional) Sesuaikan hiperparameter menggunakan kurva loss

    Di halaman detail job, Anda dapat melihat kurva train_loss (loss set pelatihan) dan kurva eval_loss (loss set validasi):

    imageimage

    Anda dapat menggunakan tren nilai loss untuk menilai efektivitas pelatihan model:

    • Underfitting: Kurva train_loss dan eval_loss masih menurun saat pelatihan berakhir.

      Anda dapat meningkatkan parameter num_train_epochs (jumlah epoch pelatihan, yang berkorelasi positif dengan kedalaman pelatihan) atau nilai lora_rank (peringkat matriks peringkat rendah; peringkat yang lebih besar memungkinkan model menangani tugas yang lebih kompleks tetapi meningkatkan risiko overfitting). Lalu, latih ulang model agar lebih sesuai dengan data pelatihan.

    • Overfitting: train_loss terus menurun sementara eval_loss mulai meningkat sebelum pelatihan berakhir.

      Anda dapat mengurangi parameter num_train_epochs atau nilai lora_rank, lalu latih ulang model untuk mencegah overfitting.

    • Good fit: Kurva train_loss dan eval_loss stabil sebelum pelatihan berakhir.

      Saat model mencapai kondisi ini, Anda dapat melanjutkan ke langkah berikutnya.

4.4 Menerapkan model yang telah difine-tuning

Di halaman detail job pelatihan, klik Deploy untuk membuka halaman konfigurasi penerapan. Untuk Resource Type, pilih Public Resources. Menerapkan model 0,6B memerlukan sekitar 5 GB Memori GPU. Daftar di bawah Instance Type secara otomatis menampilkan spesifikasi yang kompatibel. Pilih salah satu, seperti ecs.gn7i-c8g1.2xlarge. Pertahankan parameter lain pada nilai default, lalu klik Deploy > OK.

Penerapan membutuhkan waktu sekitar 5 menit dan selesai saat status berubah menjadi Running.

Untuk melihat detail job pelatihan, di panel navigasi sebelah kiri, klik Model Gallery > Job Management > Training Jobs, lalu klik nama job.
Jika tombol Deploy dinonaktifkan setelah job pelatihan berhasil, artinya model output masih dalam proses pendaftaran. Tunggu sekitar satu menit hingga tombol diaktifkan.

Langkah-langkah untuk memanggil model sama seperti yang dijelaskan dalam 3.2 Panggil model.

4.5 Evaluasi model yang telah difine-tuning

Sebelum menerapkan model yang telah difine-tuning ke lingkungan produksi, evaluasi performanya untuk memastikan stabilitas dan akurasinya. Evaluasi ini membantu mencegah masalah tak terduga setelah penerapan.

Siapkan data uji

Siapkan dataset uji yang tidak tumpang tindih dengan data pelatihan Anda untuk mengevaluasi performa model. Kode uji akurasi di bawah ini secara otomatis mengunduh set uji untuk tujuan ini.

Menggunakan dataset uji yang terpisah dari data pelatihan memastikan penilaian yang tidak bias terhadap kemampuan generalisasi model pada data yang belum pernah dilihat. Praktik ini mencegah skor yang terlalu tinggi akibat mengevaluasi model pada data yang sudah pernah dilihatnya.

Rancang metrik evaluasi

Metrik evaluasi harus selaras erat dengan tujuan bisnis Anda. Untuk studi kasus solusi ini, selain memvalidasi JSON yang dihasilkan, Anda juga harus memverifikasi bahwa pasangan kunci-nilai tersebut benar.

Tentukan metrik evaluasi secara programatik. Untuk implementasi dalam contoh ini, lihat metode compare_address_info dalam kode uji akurasi di bawah ini.

Validasi model yang telah difine-tuning

Jalankan kode uji berikut untuk menghasilkan akurasi model pada set uji.

Uji akurasi model

Catatan: Ganti Token dan endpoint dengan detail pemanggilan yang Anda peroleh sebelumnya.

# pip3 install openai
from openai import AsyncOpenAI
import requests
import json
import asyncio
import os

# Jika variabel lingkungan 'Token' belum diatur, ganti baris berikut dengan token Anda dari Elastic Algorithm Service (EAS): token = 'YTA1NTEzMzY3ZTY4Z******************'
token = os.environ.get("Token")

# Jangan hapus akhiran "/v1" dari endpoint.
client = AsyncOpenAI(
    api_key=token,
    base_url=f'YOUR_ENDPOINT/v1',
)

if token is None:
    print("Harap atur variabel lingkungan 'Token', atau tetapkan token Anda langsung ke variabel 'token'.")
    exit()

system_prompt = """Anda adalah asisten ekstraksi informasi profesional yang berspesialisasi dalam mengurai alamat pengiriman AS dari teks tidak terstruktur.

## Deskripsi Tugas
Berdasarkan teks masukan yang diberikan, ekstrak dan hasilkan objek JSON yang berisi enam bidang berikut:
- name: Nama lengkap penerima.
- street_address: Alamat jalan lengkap, termasuk nomor, nama jalan, dan nomor apartemen atau suite apa pun.
- city: Nama kota.
- state: Nama lengkap negara bagian (misalnya, "California", bukan "CA").
- zip_code: Kode ZIP 5 atau 9 digit.
- phone: Nomor telepon kontak lengkap.

## Aturan Ekstraksi
1.  **Penanganan Alamat**:
    -   Identifikasi secara akurat komponen: jalan, kota, negara bagian, dan kode ZIP.
    -   Bidang `state` harus berupa nama resmi lengkap (misalnya, "New York", bukan "NY").
    -   `street_address` harus berisi semua detail sebelum kota, seperti "123 Apple Lane, Apt 4B".
2.  **Identifikasi Nama**:
    -   Ekstrak nama penerima lengkap.
3.  **Penanganan Nomor Telepon**:
    -   Ekstrak nomor telepon lengkap, mempertahankan format aslinya.
4.  **Kode ZIP**:
    -   Ekstrak kode 5 digit atau 9 digit (ZIP+4).

## Format Output
Patuhi secara ketat format JSON berikut. Jangan tambahkan teks penjelasan atau markdown.
{
  "name": "Nama Lengkap Penerima",
  "street_address": "Alamat Jalan Lengkap",
  "city": "Nama Kota",
  "state": "Nama Negara Bagian Lengkap",
  "zip_code": "Kode ZIP",
  "phone": "Nomor Telepon Kontak"
}
"""

def compare_address_info(actual_address_str, predicted_address_str):
    """Membandingkan dua string JSON yang merepresentasikan informasi alamat untuk melihat apakah identik."""
    try:
        # Uraikan informasi alamat aktual
        if actual_address_str:
            actual_address_json = json.loads(actual_address_str)
        else:
            actual_address_json = {}

        # Uraikan informasi alamat yang diprediksi
        if predicted_address_str:
            predicted_address_json = json.loads(predicted_address_str)
        else:
            predicted_address_json = {}

        # Bandingkan langsung apakah dua objek JSON identik
        is_same = actual_address_json == predicted_address_json

        return {
            "is_same": is_same,
            "actual_address_parsed": actual_address_json,
            "predicted_address_parsed": predicted_address_json,
            "comparison_error": None
        }

    except json.JSONDecodeError as e:
        return {
            "is_same": False,
            "actual_address_parsed": None,
            "predicted_address_parsed": None,
            "comparison_error": f"Kesalahan penguraian JSON: {str(e)}"
        }
    except Exception as e:
        return {
            "is_same": False,
            "actual_address_parsed": None,
            "predicted_address_parsed": None,
            "comparison_error": f"Kesalahan perbandingan: {str(e)}"
        }

async def predict_single_conversation(conversation_data):
    """Memprediksi label untuk satu percakapan."""
    try:
        # Ekstrak konten pengguna (tidak termasuk pesan asisten)
        messages = conversation_data.get("messages", [])
        user_content = None

        for message in messages:
            if message.get("role") == "user":
                user_content = message.get("content", "")
                break

        if not user_content:
            return {"error": "Pesan pengguna tidak ditemukan"}

        response = client.chat.completions.create(
            model="Qwen3-0.6B",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_content}
            ],
            response_format={"type": "json_object"},
            extra_body={
                "enable_thinking": False
            }
        )

        predicted_labels = response.choices[0].message.content.strip()
        return {"prediction": predicted_labels}

    except Exception as e:
        return {"error": f"Prediksi gagal: {str(e)}"}

async def process_batch(batch_data, batch_id):
    """Memproses batch data."""
    print(f"Memproses batch {batch_id}, berisi {len(batch_data)} item...")

    tasks = []
    for i, conversation in enumerate(batch_data):
        task = predict_single_conversation(conversation)
        tasks.append(task)

    results = await asyncio.gather(*tasks, return_exceptions=True)

    batch_results = []
    for i, result in enumerate(results):
        if isinstance(result, Exception):
            batch_results.append({"error": f"Pengecualian: {str(result)}"})
        else:
            batch_results.append(result)

    return batch_results

async def main():
    output_file = "predicted_labels.jsonl"
    batch_size = 20  # Jumlah item yang diproses per batch

    # Baca data uji
    url = 'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251015/yghxco/test.jsonl'
    conversations = []

    try:
        response = requests.get(url)
        response.raise_for_status()  # Periksa apakah permintaan berhasil
        for line_num, line in enumerate(response.text.splitlines(), 1):
            try:
                data = json.loads(line.strip())
                conversations.append(data)
            except json.JSONDecodeError as e:
                print(f"Kesalahan penguraian JSON pada baris {line_num}: {e}")
                continue
    except requests.exceptions.RequestException as e:
        print(f"Kesalahan permintaan: {e}")
        return

    print(f"Berhasil membaca {len(conversations)} percakapan")

    # Proses dalam batch
    all_results = []
    total_batches = (len(conversations) + batch_size - 1) // batch_size

    for batch_id in range(total_batches):
        start_idx = batch_id * batch_size
        end_idx = min((batch_id + 1) * batch_size, len(conversations))
        batch_data = conversations[start_idx:end_idx]

        batch_results = await process_batch(batch_data, batch_id + 1)
        all_results.extend(batch_results)

        print(f"Batch {batch_id + 1}/{total_batches} selesai")

        # Tambahkan jeda kecil untuk menghindari permintaan terlalu cepat
        if batch_id < total_batches - 1:
            await asyncio.sleep(1)

    # Simpan hasil
    same_count = 0
    different_count = 0
    error_count = 0

    with open(output_file, 'w', encoding='utf-8') as f:
        for i, (original_data, prediction_result) in enumerate(zip(conversations, all_results)):
            result_entry = {
                "index": i,
                "original_user_content": None,
                "actual_address": None,
                "predicted_address": None,
                "prediction_error": None,
                "address_comparison": None
            }

            # Ekstrak konten pengguna asli
            messages = original_data.get("messages", [])
            for message in messages:
                if message.get("role") == "user":
                    result_entry["original_user_content"] = message.get("content", "")
                    break

            # Ekstrak informasi alamat aktual (jika ada pesan asisten)
            for message in messages:
                if message.get("role") == "assistant":
                    result_entry["actual_address"] = message.get("content", "")
                    break

            # Simpan hasil prediksi
            if "error" in prediction_result:
                result_entry["prediction_error"] = prediction_result["error"]
                error_count += 1
            else:
                result_entry["predicted_address"] = prediction_result.get("prediction", "")

                # Bandingkan informasi alamat
                comparison_result = compare_address_info(
                    result_entry["actual_address"],
                    result_entry["predicted_address"]
                )
                result_entry["address_comparison"] = comparison_result

                # Hitung hasil perbandingan
                if comparison_result["comparison_error"]:
                    error_count += 1
                elif comparison_result["is_same"]:
                    same_count += 1
                else:
                    different_count += 1

            f.write(json.dumps(result_entry, ensure_ascii=False) + '\n')

    print(f"Semua prediksi selesai! Hasil telah disimpan ke {output_file}")

    # Statistik
    success_count = sum(1 for result in all_results if "error" not in result)
    prediction_error_count = len(all_results) - success_count
    print(f"Jumlah sampel: {success_count}")
    print(f"Tanggapan benar: {same_count}")
    print(f"Tanggapan salah: {different_count}")
    print(f"Akurasi: {same_count * 100 / success_count} %")

if __name__ == "__main__":
    asyncio.run(main())

Output:

Semua prediksi selesai! Hasil telah disimpan ke predicted_labels.jsonl
Jumlah sampel: 400
Tanggapan benar: 382
Tanggapan salah: 18
Akurasi: 95,5 %
Karena seed acak yang digunakan dalam fine-tuning model dan sifat stokastik output model bahasa besar, akurasi yang Anda capai mungkin berbeda dari hasil yang ditunjukkan dalam solusi ini. Variasi ini normal.

Akurasinya 95,5%, peningkatan signifikan dibandingkan akurasi 50% model Qwen3-0.6B asli. Ini menunjukkan bahwa fine-tuning secara substansial meningkatkan performanya dalam ekstraksi informasi terstruktur di domain logistik.

Panduan ini hanya menggunakan 4 epoch pelatihan untuk mengurangi waktu pelatihan, yang meningkatkan akurasi menjadi 95,5%. Anda dapat lebih meningkatkan akurasi dengan menambah jumlah epoch pelatihan.

4.6 Catatan penting

Layanan model dalam topik ini menggunakan Sumber daya publik dan dikenai biaya berdasarkan skema bayar sesuai penggunaan. Saat Anda tidak lagi membutuhkan layanan tersebut, hentikan atau hapus untuk menghindari biaya lebih lanjut.

Dokumen terkait

  • Untuk mempelajari lebih lanjut tentang fitur Model Gallery seperti evaluasi dan kompresi, lihat Model Gallery.

  • Untuk mempelajari lebih lanjut tentang fitur EAS seperti Auto Scaling, uji stres, dan Pemantauan Peringatan, lihat Ikhtisar EAS.