게시판Qwen2.5-VL 차트 LoRA: PNG로 매수·매도·유지 학습하기예제 소스

예제 소스

Qwen2.5-VL 차트 LoRA: PNG로 매수·매도·유지 학습하기 · 파일 59개

train_and_evaluate_qwen_chart_lora.py

"""
Qwen 차트 LoRA 학습이 성공한 뒤 Account 규칙 백테스트를 실행한다.

학습 또는 평가가 실패하면 즉시 비정상 종료한다. 평가 프로그램은 어댑터
해시별 체크포인트를 사용하므로 중단 후 같은 명령으로 재개할 수 있다.
"""

from __future__ import annotations

import argparse
import shutil
import subprocess
import sys
from pathlib import Path

from evaluate_qwen_chart_lora import adapter_fingerprint


def _run(command: list[str]) -> None:
    print("+", " ".join(command), flush=True)
    subprocess.run(command, check=True)


def main() -> None:
    parser = argparse.ArgumentParser(description="Qwen 차트 LoRA 학습 후 수익률 평가")
    parser.add_argument("--steps", type=int, default=200)
    parser.add_argument("--save-every", type=int, default=50)
    parser.add_argument("--model", type=Path, default=Path("models/Qwen2.5-VL-3B-Instruct"))
    parser.add_argument("--adapter", type=Path, default=Path("cache/qwen_chart_lora"))
    parser.add_argument("--csv", type=Path, default=Path("cache/market_extreme_labels.csv"))
    parser.add_argument("--chart-dir", type=Path, default=Path("chart"))
    parser.add_argument(
        "--eval-output-root",
        type=Path,
        default=Path("cache/qwen_chart_lora/eval"),
    )
    parser.add_argument("--start-bar", type=int, default=300)
    parser.add_argument("--end-bar", type=int, default=None)
    parser.add_argument("--eval-max-bars", type=int, default=None)
    parser.add_argument("--initial-krw", type=float, default=5_000_000.0)
    parser.add_argument("--max-pixels", type=int, default=512 * 512)
    parser.add_argument("--eval-save-every", type=int, default=25)
    parser.add_argument(
        "--snapshot-root",
        type=Path,
        default=None,
        help="모델별 LoRA 보존 위치 (기본: <adapter>/snapshots)",
    )
    parser.add_argument(
        "--skip-train",
        action="store_true",
        help="현재 어댑터를 학습하지 않고 평가만 실행",
    )
    args = parser.parse_args()

    python = sys.executable
    if not args.skip_train:
        _run(
            [
                python,
                "-u",
                "train_qwen_chart_lora.py",
                "--steps",
                str(args.steps),
                "--save-every",
                str(args.save_every),
                "--model",
                str(args.model),
                "--out",
                str(args.adapter),
                "--csv",
                str(args.csv),
                "--chart-dir",
                str(args.chart_dir),
                "--max-pixels",
                str(args.max_pixels),
            ]
        )

    fingerprint = adapter_fingerprint(args.adapter)
    snapshot_root = args.snapshot_root or (args.adapter / "snapshots")
    snapshot = snapshot_root / fingerprint[:16]
    snapshot.mkdir(parents=True, exist_ok=True)
    for source in args.adapter.iterdir():
        if source.is_file():
            shutil.copy2(source, snapshot / source.name)
    print(f"[SNAPSHOT] {snapshot} sha256={fingerprint}", flush=True)

    evaluate = [
        python,
        "-u",
        "evaluate_qwen_chart_lora.py",
        "--model",
        str(args.model),
        "--adapter",
        str(snapshot),
        "--csv",
        str(args.csv),
        "--chart-dir",
        str(args.chart_dir),
        "--output-root",
        str(args.eval_output_root),
        "--start-bar",
        str(args.start_bar),
        "--initial-krw",
        str(args.initial_krw),
        "--max-pixels",
        str(args.max_pixels),
        "--save-every",
        str(args.eval_save_every),
    ]
    if args.end_bar is not None:
        evaluate.extend(["--end-bar", str(args.end_bar)])
    if args.eval_max_bars is not None:
        evaluate.extend(["--max-bars", str(args.eval_max_bars)])
    _run(evaluate)


if __name__ == "__main__":
    main()