예제 소스
실시간 XGBoost와 DQN 결합 구조: 거래 AI를 검증하는 법 · 파일 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()