All Products
Search
Document Center

Platform For AI:Panduan cepat Model Gallery

Last Updated:May 09, 2026

Model Gallery mengintegrasikan PAI-DLC dan PAI-EAS, menyediakan cara efisien tanpa kode untuk menerapkan dan melatih model bahasa besar (LLM) sumber terbuka. Topik ini menggunakan model Qwen3-0.6B sebagai contoh untuk menunjukkan cara menggunakan Model Gallery. Alur kerja yang sama berlaku untuk model lainnya.

Prasyarat

Gunakan Akun Alibaba Cloud Anda untuk mengaktifkan Platform for AI (PAI) dan membuat ruang kerja. Masuk ke Konsol PAI, pilih Wilayah di pojok kiri atas, lalu selesaikan otorisasi satu klik.

Billing

Contoh dalam panduan ini membuat tugas PAI-DLC dan layanan PAI-EAS menggunakan Sumber daya publik. Sumber daya ini menggunakan metode penagihan bayar sesuai pemakaian. Untuk detail aturan penagihan, lihat Penagihan PAI-DLC dan Penagihan PAI-EAS.

Penerapan model

Terapkan model

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

    image

  2. Konfigurasikan parameter penerapan. Halaman konfigurasi penerapan telah diisi sebelumnya dengan parameter default. Klik Deploy > Confirm. Proses penerapan memerlukan waktu sekitar 5 menit. Penerapan selesai ketika status berubah menjadi In operation.

    Secara default, layanan model menggunakan Sumber daya publik dan metode penagihan bayar sesuai pemakaian.

    image

Panggil model

  1. Pada halaman detail layanan, klik View Call Information untuk mendapatkan Internet Endpoint dan Token.

    Untuk melihat detail pekerjaan penerapan nanti, buka Model Gallery > Job Management > Deployment Jobs di panel navigasi, lalu klik Service name.

    image

  2. Uji layanan model. Anda dapat memanggil model dengan salah satu cara berikut:

    Debugging online

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

    image

    image

    Klien Cherry Studio

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

    Sambungkan ke model Qwen3 yang diterapkan di PAI

    Python SDK

    from openai import OpenAI
    import os
    
    # Jika variabel lingkungan belum disetel, ganti baris berikut dengan Token layanan EAS Anda: token = '<YOUR_EAS_SERVICE_TOKEN>'
    token = os.environ.get("Token")
    # Jangan hapus "/v1" di akhir Internet Endpoint Anda.
    client = OpenAI(
        api_key=token,
        base_url=f'<YOUR_INTERNET_ENDPOINT>/v1',
    )
    
    if token is None:
        print("Harap setel 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}')

Pengingat penting

Layanan model yang dibuat dalam panduan ini menggunakan Sumber daya publik dan ditagih berdasarkan metode bayar sesuai pemakaian. Untuk menghindari biaya tambahan, hentikan atau hapus layanan tersebut jika tidak lagi diperlukan.

image

Penyempurnaan model

Anda dapat meningkatkan performa model dalam domain tertentu dengan melakukan fine-tuning pada set data spesifik domain. Skenario berikut menunjukkan tujuan dan langkah-langkah fine-tuning.

Kasus penggunaan

Di industri logistik, Anda sering perlu mengekstraksi informasi terstruktur—seperti nama penerima, alamat, dan nomor telepon—dari bahasa alami. Model berparameter besar seperti Qwen3-235B-A22B sangat unggul 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. Proses ini juga dikenal sebagai distilasi model.

Pada tugas ini, model Qwen3-0.6B asli mencapai 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"
}

Persiapan data

Untuk menyuling pengetahuan dari model guru (Qwen3-235B-A22B) ke model Qwen3-0.6B untuk tugas ini, pertama-tama gunakan API model guru untuk mengekstraksi alamat penerima menjadi data JSON terstruktur. Menghasilkan data JSON ini bisa memakan waktu. Oleh karena itu, panduan ini menyediakan set data pelatihan sampeltrain.json dan set validasieval.json.

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

Penerapan di produksi

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

Skenario bisnis nyata (direkomendasikan)

Data bisnis nyata lebih mencerminkan skenario bisnis Anda, sehingga model yang telah disempurnakan dapat lebih baik beradaptasi dengan bisnis Anda. Setelah memperoleh data bisnis, Anda perlu mengonversinya secara terprogram menjadi 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 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-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

Ketika data bisnis tidak mencukupi, pertimbangkan untuk 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 disediakan 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 endpoint 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}", "Panggil: {phone}",
]


# Hasilkan nomor telepon gaya 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 asli 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 yang berantakan dari 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 Sampel:")
    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, ekstraksi 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 negara bagian lengkap (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**:
    -   Ekstraksi nama penerima lengkap.
3.  **Penanganan Nomor Telepon**:
    -   Ekstraksi nomor telepon lengkap, pertahankan format aslinya.
4.  **Kode ZIP**:
    -   Ekstraksi 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 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-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 berhasil!")
        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)

Lakukan fine-tuning pada model

  1. Di panel navigasi, klik Model Gallery, temukan kartu Qwen3-0.6B, lalu klik Fine-tune.

    image

  2. Konfigurasikan parameter untuk pekerjaan pelatihan. Anda hanya perlu mengonfigurasi parameter kunci berikut. Biarkan parameter lain pada nilai default-nya.

    • Training Mode: Default-nya 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 set data pelatihan sampel train.json. Kemudian, di halaman konfigurasi, pilih OSS file or directory, klik ikon image untuk memilih bucket, klik Upload File untuk mengunggah set data ke Object Storage Service (OSS), lalu pilih file tersebut.

      image

    • Validate dataset: Pertama, unduh set data validasi sampel eval.json. Kemudian, klik Add validation dataset dan ulangi proses unggah yang digunakan untuk set data pelatihan.

      Set data validasi digunakan selama pelatihan untuk mengevaluasi performa model pada data yang belum pernah dilihat.
    • Model output path: Secara default, layanan menyimpan model yang telah disempurnakan ke jalur OSS. Jika folder tujuan tidak ada, klik Create folder dan tentukan nama folder.

    • Resource Group Type: Pilih Public Resource Group. Pekerjaan fine-tuning ini memerlukan sekitar 5 GB Memori GPU. Konsol secara otomatis menyaring tipe instans yang tersedia untuk 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

      Kemudian, klik Train > OK. Status pekerjaan pelatihan berubah dari Creating ke In operation, yang memulai fine-tuning model.

  3. Monitor pekerjaan pelatihan dan tunggu hingga selesai. Proses fine-tuning memerlukan waktu sekitar 10 menit. Selama proses ini, halaman detail tugas menampilkan log tugas dan kurva metrik. Setelah pekerjaan selesai, layanan menyimpan model yang telah disempurnakan ke folder OSS yang ditentukan.

    Untuk melihat detail pekerjaan nanti, di panel navigasi, klik Model Gallery > Job Management > Training Jobs, lalu klik nama pekerjaan.

    image

    (Opsional) Sesuaikan hiperparameter berdasarkan kurva loss untuk meningkatkan performa model

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

    imageimage

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

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

      Untuk meningkatkan kesesuaian model, Anda dapat meningkatkan parameter num_train_epochs (jumlah epoch pelatihan, yang berkorelasi positif dengan kedalaman pelatihan) atau lora_rank (peringkat matriks peringkat rendah; peringkat yang lebih besar memungkinkan model mempelajari pola yang lebih kompleks tetapi meningkatkan risiko overfitting), lalu latih ulang model.

    • Overfitting: Kurva train_loss terus menurun, sedangkan kurva eval_loss mulai meningkat sebelum pelatihan berakhir.

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

    • Kesesuaian baik: Kurva train_loss dan eval_loss keduanya telah stabil dan mendatar sebelum pelatihan berakhir.

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

Terapkan model yang telah disempurnakan

Di halaman detail pekerjaan pelatihan, klik Deploy untuk membuka pengaturan penerapan. Untuk Resource Type, pilih Public Resources. Menerapkan model 0.6B memerlukan sekitar 5 GB memori GPU. Di bawah Instance Type, hanya spesifikasi yang memenuhi persyaratan ini yang tercantum. Pilih opsi, seperti ecs.gn7i-c8g1.2xlarge, biarkan parameter lain pada nilai default-nya, lalu klik Deploy > OK.

Penerapan memerlukan waktu sekitar 5 menit. Penerapan berhasil setelah status berubah menjadi Running.

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

image

Jika tombol Deploy dinonaktifkan setelah pekerjaan pelatihan selesai, artinya model output masih dalam proses pendaftaran. Tunggu sekitar satu menit.

image

Untuk memanggil model, ikuti langkah-langkah di Panggil model.

Evaluasi model yang telah disempurnakan

Sebelum menerapkan model yang telah disempurnakan ke lingkungan produksi, Anda harus mengevaluasi performanya. Evaluasi ini memastikan model stabil dan akurat, yang membantu mencegah masalah tak terduga setelah penerapan.

Siapkan data uji

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

Data uji Anda tidak boleh mengandung sampel apa pun dari data pelatihan Anda. Hal ini memastikan evaluasi akurat terhadap kemampuan generalisasi model pada data baru dan mencegah skor yang terlalu tinggi akibat menghafal sampel.

Rancang metrik evaluasi

Kriteria evaluasi Anda harus selaras dengan tujuan bisnis Anda. Untuk kasus penggunaan ini, selain memverifikasi bahwa output adalah string JSON yang valid, pastikan pasangan kunci-nilai-nya benar.

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

Evaluasi performa model

Jalankan kode berikut untuk menghitung akurasi model pada set uji.

Kode contoh untuk menguji akurasi model

Catatan: Ganti token dan endpoint placeholder dengan nilai aktual yang Anda peroleh.

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

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

# Jangan hapus sufiks "/v1" setelah URL layanan.
client = OpenAI(
    api_key=token,
    base_url=f'<YOUR_ENDPOINT>/v1',
)

if token is None:
    print("Harap setel 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, ekstraksi 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 negara bagian lengkap (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**:
    -   Ekstraksi nama penerima lengkap.
3.  **Penanganan Nomor Telepon**:
    -   Ekstraksi nomor telepon lengkap, pertahankan format aslinya.
4.  **Kode ZIP**:
    -   Ekstraksi 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 menentukan apakah keduanya 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:
        # Ekstraksi konten pengguna (kecualikan 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)} percakapan...")

    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
            }

            # Ekstraksi 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

            # Ekstraksi 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 %
Akurasi yang Anda amati mungkin berbeda dari hasil dalam panduan ini karena faktor seperti seed acak yang digunakan selama fine-tuning dan sifat stokastik output model besar. Hal ini diharapkan.

Model mencapai akurasi 95.5%, peningkatan signifikan dibandingkan akurasi model Qwen3-0.6B asli sebesar 50%. Hal ini menunjukkan bahwa fine-tuning telah secara substansial meningkatkan kemampuan model untuk mengekstraksi informasi terstruktur untuk entri data logistik.

Panduan ini hanya menggunakan 4 epoch pelatihan untuk mengurangi waktu pelatihan, yang cukup untuk meningkatkan akurasi hingga 95.5%. Anda dapat meningkatkan akurasi lebih lanjut dengan menambah jumlah epoch pelatihan.

Penting

Membuat layanan model dalam panduan ini menggunakan Sumber daya publik, yang ditagih berdasarkan metode bayar sesuai pemakaian. Saat Anda tidak lagi memerlukan layanan tersebut, hentikan atau hapus untuk menghindari biaya tambahan.

image

Referensi

  • Untuk detail fitur Model Gallery seperti Evaluasi dan kompresi, lihat Model Gallery.

  • Untuk detail fitur EAS seperti Auto Scaling, uji stres, dan Pemantauan Peringatan, lihat Ikhtisar EAS.