# @title 🎭 Maggie VL: Flexible Storyteller (Text & Image)
import json, os, torch
from PIL import Image
from transformers import Qwen3VLForConditionalGeneration, AutoProcessor
def cek_vram(label):
# Mendapatkan total kapasitas dan memori kosong dari Driver GPU
t = torch.cuda.get_device_properties(0).total_memory / (1024**3)
r = torch.cuda.memory_reserved() / (1024**3)
a = torch.cuda.memory_allocated() / (1024**3)
f = t - r # Memori yang benar-benar belum disentuh siapapun
print(f"--- {label} ---")
print(f"Total VRAM GPU : {t:.2f} GB")
print(f"VRAM Dipesan : {r:.2f} GB (Kekuasaan PyTorch)")
print(f"VRAM Terpakai : {a:.2f} GB (Isi Data/Model)")
print(f"VRAM Kosong-Melompong: {f:.2f} GB (Sisa Tak Tersentuh)")
cek_vram("Sebelum Generate")
# 1. KONFIGURASI (Ubah di sini)
PROMPT_BARU = """
cerita abad pertengahan edisi deluxe.
"""
IMAGE_PATH = "" #"/content/maggie_512.jpg" # Isi misal: "gudang_kain.jpg" kalau ada
RESET_HISTORY = False
MODEL_ID = "Heouzen/Huihui-Qwen3-VL-8B-Instruct-FP8-abliterated"
# 1. Mendeteksi otomatis folder tempat script/notebook ini berada saat ini
CURRENT_DIR = os.getcwd()
# 2. Menggabungkan path folder saat ini dengan nama file JSON
FILE = os.path.join(CURRENT_DIR, "maggie_history_cerita.json")
# Opsional: Print untuk memastikan alamatnya sudah benar
print(f"📁 Lokasi file JSON saat ini: {FILE}")
SYSTEM_INS = """
Maggie adalah gadis berusia 19 tahun, putri Edward (46) dan Eliza (43). Edward merupakan pedagang kain dengan toko menengah, cukup mampu bersaing dengan para pedagang lainnnya tapi bukan dengan pedagang yang besar. Usaha itu dijalankan bersama istrinya, Maggie, dan beberapa pegawai.
Keluarga Maggie bukan bangsawan, namun cukup untuk hidup di kelas menengah ke atas di Kerajaan Dravalor.
maggie memiliki paras yang sangat cantik, rambut pirang platina, tinggi badan 165cm, dan berat 45kg. badan yang ramping.
Gunakan gaya bahasa naratif sesuai dengan setting kerajaan abad pertengahan. Jangan pakai bahasa gaul modern.
gunakan nama orang era medieval. ceritakan seperti novel dewasa.
"""
# 2. LOAD MODEL (Hidden & Smart)
if 'model' not in globals():
gpu = torch.cuda.get_device_name(0) if torch.cuda.is_available() else "CPU"
print(f"⏳ Menyiapkan mesin di {gpu}...")
model = Qwen3VLForConditionalGeneration.from_pretrained(
MODEL_ID, device_map="auto", torch_dtype="auto", trust_remote_code=True, low_cpu_mem_usage=True
)
processor = AutoProcessor.from_pretrained(MODEL_ID)
#clear_output()
print(f"✅ {gpu} SIAP!")
# 3. LOGIKA MULTIMODAL
if RESET_HISTORY and os.path.exists(FILE): os.remove(FILE)
msg = json.load(open(FILE)) if os.path.exists(FILE) else [
{"role": "system", "content": [{"type": "text", "text": SYSTEM_INS}]}
]
# Siapkan Konten User
u_content = []
img = None
if IMAGE_PATH and os.path.exists(IMAGE_PATH):
img = Image.open(IMAGE_PATH).convert("RGB")
u_content.append({"type": "image", "image": img})
u_content.append({"type": "text", "text": PROMPT_BARU})
msg.append({"role": "user", "content": u_content})
# 4. INFERENCE
LIMIT_INGATAN = 4 # Mengingat 1 tanya-jawab terakhir + yang sedang berjalan
# Logika Pemangkasan: Selalu bawa Index 0 (System) + Pesan-pesan terbaru
if len(msg) > (LIMIT_INGATAN + 1):
msg_minimal = [msg[0]] + msg[-(LIMIT_INGATAN + 1):]
else:
msg_minimal = msg
'''
# --- 👇 TAMBAHKAN BARIS INI UNTUK BUKTI 👇 ---
print("\n" + "▼"*50)
print("🔍 BUKTI DATA YANG DIBACA OLEH GPU (msg_minimal):")
# Kita print menggunakan format JSON agar rapi dan mudah dibaca
print(json.dumps(msg_minimal, indent=4))
print("▲"*50 + "\n")
# --- 👆 SAMPAI SINI 👆 ---
'''
print(f"Jumlah Parameter: {model.num_parameters():,}")
# Processor butuh template gabungan
prompt_text = processor.apply_chat_template(msg_minimal, tokenize=False, add_generation_prompt=True)
inputs = processor(text=[prompt_text], images=[img] if img else None, padding=True, return_tensors="pt").to(model.device)
print(f"✍️ {torch.cuda.get_device_name(0)} sedang menyusun adegan...")
with torch.no_grad():
out_ids = model.generate(**inputs, max_new_tokens=1024, temperature=0.7, top_p=0.9, do_sample=True, repetition_penalty=1.2, eos_token_id=processor.tokenizer.eos_token_id, pad_token_id=processor.tokenizer.pad_token_id)
# Potong output agar hanya teks asisten yang muncul
resp = processor.batch_decode(out_ids[:, inputs.input_ids.shape[1]:], skip_special_tokens=True)[0]
# 5. HASIL & SAVE
print("\n" + "="*50 + f"\n[CERITA BARU]:\n\n{resp}\n" + "="*50)
# Simpan teks saja ke history (biar JSON gak bengkak gara-gara data gambar)
msg[-1] = {"role": "user", "content": [{"type": "text", "text": f"[User sent an image] {PROMPT_BARU}" if img else PROMPT_BARU}]}
msg.append({"role": "assistant", "content": [{"type": "text", "text": resp}]})
json.dump(msg, open(FILE, "w"), indent=4)
torch.cuda.empty_cache()
cek_vram("Setelah Generate & Clean")
- Downloads last month
- 72
Model tree for Heouzen/Huihui-Qwen3-VL-8B-Instruct-FP8-abliterated
Base model
Qwen/Qwen3-VL-8B-Instruct