All Products
Search
Document Center

Platform For AI:Panduan Cepat Model Gallery

Last Updated:Mar 01, 2026

Model Gallery mengintegrasikan Platform for AI (PAI)-DLC dan PAI-EAS, menyediakan solusi tanpa kode untuk menerapkan dan melatih model bahasa besar (LLM) sumber terbuka secara efisien. Panduan ini menggunakan model Qwen3-0.6B untuk menunjukkan prosesnya. Langkah-langkah yang sama berlaku untuk model lain.

Prasyarat

Aktifkan Platform for AI (PAI) dan buat ruang kerja menggunakan Akun Alibaba Cloud Anda. Untuk melakukannya, login ke Konsol PAI, pilih Wilayah di pojok kiri atas, lalu aktifkan layanan tersebut menggunakan otorisasi satu klik.

Penagihan

Contoh dalam panduan ini menggunakan Sumber daya publik untuk membuat task PAI-DLC dan layanan PAI-EAS. Sumber daya ini ditagih berdasarkan skema bayar sesuai penggunaan. Untuk informasi lebih lanjut tentang aturan penagihan, lihat penagihan DLC dan penagihan EAS.

Penerapan model

Terapkan model

  1. Login ke Konsol PAI. Di panel navigasi sebelah kiri, klik Model Gallery. Cari Qwen3-0.6B dan klik Deploy.

    image

  2. Konfigurasikan parameter penerapan. Halaman penerapan mencakup parameter default. Klik Deploy > OK. Proses penerapan memerlukan waktu sekitar 5 menit. Penerapan berhasil ketika status berubah menjadi In operation.

    Secara default, layanan ini menggunakan Sumber daya publik dan ditagih berdasarkan skema bayar sesuai penggunaan.

    image

Panggil model

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

    Untuk melihat detail task penerapan nanti, navigasikan ke Model Gallery > Job Management > Deployment Jobs, lalu klik Service name.

    image

  2. Uji layanan model. Anda dapat memanggil model menggunakan salah satu metode berikut:

    Debugging online

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

    image

    Gunakan klien Cherry Studio

    Cherry Studio adalah klien chat model besar populer yang mengintegrasikan fitur MCP, sehingga memungkinkan Anda dengan mudah berchat dengan model besar.

    Hubungkan ke model Qwen3 yang diterapkan di PAI

    Gunakan Python SDK

    from openai import OpenAI
    import os
    
    # Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan token layanan EAS Anda: token = 'YTA1NTEzMzY3ZTY4Z******************'
    token = os.environ.get("Token")
    # Jangan hapus "/v1" di akhir URL layanan.
    client = OpenAI(
        api_key=token,
        base_url=f'Your service URL/v1',
    )
    
    if token is None:
        print("Harap konfigurasikan variabel lingkungan Token atau tetapkan 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}')

Pengingat penting

Layanan model dalam panduan ini dibuat menggunakan Sumber daya publik, yang ditagih berdasarkan skema bayar sesuai penggunaan. Untuk menghindari biaya tambahan, hentikan atau hapus layanan setelah selesai digunakan.

image

Penyempurnaan model

Untuk meningkatkan performa model dalam domain tertentu, Anda dapat melakukan fine-tuning pada dataset dari domain tersebut. Bagian ini menggunakan skenario berikut untuk menunjukkan tujuan dan langkah-langkah fine-tuning model.

Kasus penggunaan

Di industri logistik, Anda sering perlu mengekstraksi informasi terstruktur (seperti penerima, alamat, dan nomor telepon) dari bahasa alami. Model besar seperti Qwen3-235B-A22B berkinerja 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 menyempurnakan model yang lebih kecil, seperti Qwen3-0.6B. Proses ini juga dikenal sebagai distilasi model.

Untuk tugas ekstraksi informasi terstruktur yang sama, model Qwen3-0.6B asli mencapai akurasi 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"
}

Persiapkan data

Untuk menyuling pengetahuan dari model guru (Qwen3-235B-A22B) ke model Qwen3-0.6B untuk tugas ini, pertama-tama Anda perlu menggunakan API model guru untuk mengekstraksi informasi alamat penerima ke dalam data JSON terstruktur. Menghasilkan data ini bisa memakan waktu. Oleh karena itu, topik ini menyediakan contoh training dataset train.json dan validation set eval.json yang dapat Anda unduh dan gunakan langsung.

Dalam distilasi model, model yang lebih besar dikenal sebagai model guru. Data yang digunakan dalam panduan ini dihasilkan secara sintetis oleh model besar dan tidak mengandung informasi pengguna sensitif apa pun.

Peluncuran

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

Skema bisnis nyata (direkomendasikan)

Data bisnis nyata lebih mencerminkan skenario bisnis Anda, dan model yang telah disempurnakan dapat lebih baik beradaptasi dengan bisnis Anda. Setelah Anda mendapatkan data bisnis, Anda perlu mengonversinya secara terprogram ke dalam file JSON dengan format berikut.

[
    {
        "instruction": "Anda adalah asisten ahli untuk mengekstraksi JSON terstruktur dari informasi pengiriman AS. Kunci JSON 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 Rico 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 Rico\", \"zip_code\": \"00680\", \"phone\": \"(640) 486-5927\"}"
    },
    {
        "instruction": "Anda adalah asisten ahli untuk mengekstraksi JSON terstruktur dari informasi pengiriman AS. Kunci JSON 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 memandu 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

Ketika data bisnis tidak mencukupi, pertimbangkan untuk menggunakan model untuk augmentasi data. 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 memberi label.

# -*- 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 titik akhir API yang kompatibel dengan DashScope.
# Jika Anda menggunakan layanan kompatibel OpenAI yang berbeda, ubah base_url.
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", "U.S. Virgin Islands", "Northern Mariana Islands"
]

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

# Templat 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"""Silakan 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.

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 kemungkinan penanda blok kode markdown.
        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 yang berantakan dari informasi alamat AS."""
    # Pilih negara bagian secara acak.
    state = random.choice(us_states)

    # Gunakan LLM untuk menghasilkan informasi 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 contoh pertama.
        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, pertahankan 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 Lengkap Negara Bagian",
  "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 kemungkinan penanda blok kode markdown.
        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 saat 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 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! Memproses {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 mengeksekusi 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)

Penyempurnaan model

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

    image

  2. Konfigurasikan parameter task pelatihan. Konfigurasikan parameter kunci berikut dan biarkan yang lain pada nilai defaultnya.

    • Training Mode: Default adalah SFT (Supervised Fine-Tuning), yang menggunakan metode fine-tuning LoRA.

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

      image

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

      Validation dataset digunakan selama pelatihan untuk mengevaluasi performa model pada data yang belum pernah dilihat.
    • Model output path: Secara default, model yang telah disempurnakan disimpan ke OSS. Jika direktori OSS kosong, klik Create folder dan tentukan direktori.

    • Resource Group Type: Pilih Public Resource Group. Task fine-tuning ini membutuhkan sekitar 5 GB Memori GPU. Konsol telah memfilter spesifikasi sumber daya yang tersedia untuk memenuhi persyaratan ini. Pilih spesifikasi 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

      Klik Train > OK. Status task pelatihan berubah menjadi Creating. Ketika status berubah menjadi In operation, proses fine-tuning model dimulai.

  3. Lihat task pelatihan dan tunggu hingga selesai. Proses fine-tuning model memerlukan waktu sekitar 10 menit. Selama fine-tuning, halaman detail task menampilkan log dan kurva metrik. Setelah pelatihan selesai, model yang telah disempurnakan disimpan ke direktori OSS yang ditentukan.

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

    image

    (Opsional) Sesuaikan hyperparameter berdasarkan grafik loss untuk meningkatkan performa model

    Di halaman detail task, Anda dapat melihat kurva train_loss (mencerminkan loss set pelatihan) dan kurva eval_loss (mencerminkan 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 num_train_epochs (jumlah epoch pelatihan, yang berkorelasi positif dengan kedalaman pelatihan) atau sedikit meningkatkan lora_rank (peringkat matriks peringkat rendah; peringkat yang lebih besar memungkinkan model mempelajari tugas yang lebih kompleks tetapi meningkatkan risiko overfitting) lalu melatih ulang model untuk meningkatkan kecocokannya dengan data pelatihan.

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

      Anda dapat mengurangi num_train_epochs atau sedikit mengurangi lora_rank lalu melatih ulang model untuk mencegah overfitting.

    • Good fit: Kurva train_loss dan eval_loss telah stabil dan datar. Saat model mencapai kondisi ini, Anda dapat melanjutkan.

Terapkan model yang telah disempurnakan

Di halaman detail job pelatihan, klik tombol Deploy untuk membuka halaman konfigurasi penerapan. Atur Resource Type ke Public Resources. Menerapkan model 0.6B membutuhkan sekitar 5 GB Memori GPU. Dropdown Resource Type telah difilter untuk menampilkan spesifikasi yang memenuhi persyaratan ini. Pilih spesifikasi seperti ecs.gn7i-c8g1.2xlarge. Pertahankan parameter lain pada pengaturan default, lalu klik Deploy > OK.

Proses penerapan memerlukan waktu sekitar 5 menit. Ketika status berubah menjadi Running, penerapan berhasil.

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

image

Jika tombol Deploy dinonaktifkan setelah task pelatihan berhasil, artinya model output masih dalam proses pendaftaran. Tunggu sekitar 1 menit.

image

Langkah-langkah selanjutnya untuk memanggil model sama seperti yang dijelaskan di bagian Panggil model.

Verifikasi performa model yang telah disempurnakan

Sebelum menerapkan model yang telah disempurnakan ke lingkungan produksi, evaluasi performanya secara sistematis untuk memastikan stabilitas dan akurasi serta menghindari masalah tak terduga setelah penerapan.

Persiapkan data uji

Persiapkan test dataset yang tidak tumpang tindih dengan data pelatihan untuk menguji performa model. Topik ini menyediakan test set yang diunduh otomatis saat Anda menjalankan kode uji akurasi di bawah ini.

Data uji tidak boleh tumpang tindih dengan data pelatihan. Ini memastikan refleksi yang lebih akurat terhadap kemampuan generalisasi model pada data baru dan menghindari skor yang terlalu tinggi akibat memorisasi sampel.

Rancang metrik evaluasi

Kriteria evaluasi harus selaras erat dengan tujuan bisnis aktual Anda. Dalam contoh solusi ini, selain memeriksa apakah string JSON yang dihasilkan valid, Anda juga harus memeriksa apakah pasangan kunci-nilai yang sesuai benar.

Anda perlu mendefinisikan metrik evaluasi secara terprogram. Untuk implementasi metrik evaluasi dalam contoh ini, lihat metode compare_address_info dalam kode uji akurasi di bawah ini.

Verifikasi performa model yang telah disempurnakan

Jalankan kode uji berikut, yang akan menghasilkan akurasi model pada test set.

Kode contoh untuk menguji akurasi model

Catatan: Ganti Token dan Endpoint dengan nilai dari layanan Anda.

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

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

# Jangan hapus akhiran "/v1" setelah URL layanan.
client = OpenAI(
    api_key=token,
    base_url=f'<Your_Service_URL>/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, pertahankan 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 Lengkap Negara Bagian",
  "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 kedua 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)} item data 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 penundaan 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 dalam fine-tuning model dan sifat stokastik output model besar, akurasi yang Anda capai mungkin berbeda dari hasil dalam topik ini. Hal ini normal.

Akurasi sebesar 95,5%, peningkatan signifikan dibandingkan akurasi 50% model Qwen3-0.6B asli. Ini menunjukkan bahwa model yang telah disempurnakan telah meningkatkan kemampuannya secara signifikan dalam mengekstraksi informasi terstruktur di ranah logistik.

Untuk mengurangi waktu pelatihan, panduan ini hanya menggunakan 4 epoch pelatihan, yang sudah meningkatkan akurasi menjadi lebih dari 90%. Anda dapat lebih meningkatkan akurasi dengan menambah jumlah epoch pelatihan.

Pengingat penting

Layanan model dalam panduan ini dibuat menggunakan Sumber daya publik, yang ditagih berdasarkan skema bayar sesuai penggunaan. Untuk menghindari biaya tambahan, hentikan atau hapus layanan setelah selesai digunakan.

image

Referensi

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

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