File size: 5,766 Bytes
698316c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
---

library_name: peft
license: other
base_model: Qwen/Qwen3-VL-8B-Instruct
pipeline_tag: image-text-to-text
tags:
- qwen3-vl
- vision-language
- portrait-aesthetics
- aesthetics-evaluation
- lora
- peft
- llama-factory
---


# Portrait Composition Aesthetics Evaluation

This project provides an inference and fusion pipeline for portrait composition aesthetics evaluation. It converts the official test set into multi-prompt prediction inputs, runs prediction with Stage2 LoRA adapters, and fuses multiple prediction files into the final `track_1_test.json`.

## 1. Project Structure

```text

project_root/

  prepare_test_prompt_v2.py          # Build multi-prompt test inputs

  convert_to_answer.py               # Fuse multi-path prediction results

  train_track1_stage1_qwen3vl8b_v1.yaml

  train_track1_stage2_qwen3vl8b_v1.yaml

  qwen3vl8b_r1stage2_seed_ensemble_fast_20260511_112825/

    seed20260511_stage2/             # Stage2 adapter 1

    seed20260512_stage2/             # Stage2 adapter 2

  datasets/

    images/                          # Test images

    original_annotations/

      track_1_test.json              # Official test template

  outputs/

    predictions/                     # Model prediction outputs

    submissions/answers/             # Final submission file

```

For path conventions, see `REPRODUCIBLE_PATHS.md`.

## 2. Environment

Use an environment that supports Qwen3-VL and LoRA inference. LLaMA-Factory is recommended for prediction.

Basic dependencies:

```bash

pip install torch transformers peft accelerate

```

If you use LLaMA-Factory, install it first and make sure `llamafactory-cli` is available.

Base model:

```text

Qwen/Qwen3-VL-8B-Instruct

```

## 3. Prepare Test Data

Place the official test file at:

```text

datasets/original_annotations/track_1_test.json

```

Place test images under:

```text

datasets/images/

```

Generate multi-prompt test inputs:

```bash

python prepare_test_prompt_v2.py \

  --input_json datasets/original_annotations/track_1_test.json \

  --image_dir datasets/images \

  --output_json outputs/predictions/track1_test_convert.json \

  --prompt_variants v1,v2,v3,v4,v6,v7,v8

```

This command generates:

```text

outputs/predictions/track1_test_convert_v1.json

outputs/predictions/track1_test_convert_v2.json

outputs/predictions/track1_test_convert_v3.json

outputs/predictions/track1_test_convert_v4.json

outputs/predictions/track1_test_convert_v6.json

outputs/predictions/track1_test_convert_v7.json

outputs/predictions/track1_test_convert_v8.json

```

## 4. Run Multi-Path Prediction

Use the Stage2 adapters to run prediction on the generated prompt variants:

```text

qwen3vl8b_r1stage2_seed_ensemble_fast_20260511_112825/seed20260511_stage2

qwen3vl8b_r1stage2_seed_ensemble_fast_20260511_112825/seed20260512_stage2

```

If you use LLaMA-Factory, register each test JSON in `dataset_info.json`. Example:

```json

{

  "track1_test_v1": {

    "file_name": "outputs/predictions/track1_test_convert_v1.json",

    "formatting": "sharegpt",

    "columns": {

      "messages": "messages",

      "images": "images"

    }

  }

}

```

Example prediction config:

```yaml

model_name_or_path: Qwen/Qwen3-VL-8B-Instruct

adapter_name_or_path: qwen3vl8b_r1stage2_seed_ensemble_fast_20260511_112825/seed20260511_stage2

template: qwen3_vl_nothink

stage: sft

finetuning_type: lora



dataset_dir: .

eval_dataset: track1_test_v1

do_predict: true

predict_with_generate: true

cutoff_len: 4096

image_max_pixels: 786432

per_device_eval_batch_size: 8

max_new_tokens: 384

do_sample: false

top_p: 1.0

repetition_penalty: 1.02

bf16: true

flash_attn: auto



output_dir: outputs/predictions/seed20260511_v1

```

Run prediction:

```bash

llamafactory-cli train predict_seed20260511_v1.yaml

```

Each prediction run should produce:

```text

outputs/predictions/<run_name>/generated_predictions.jsonl

```

## 5. Fuse Prediction Results

Copy or symlink the official test template to:

```text

outputs/predictions/track_1_test.json

```

Fuse prediction results:

```bash

python convert_to_answer.py \

  --template_json outputs/predictions/track_1_test.json \

  --predictions_jsonl \

    outputs/predictions/seed20260511_v1/generated_predictions.jsonl \

    outputs/predictions/seed20260511_v2/generated_predictions.jsonl \

    outputs/predictions/seed20260511_v3/generated_predictions.jsonl \

    outputs/predictions/seed20260511_v4/generated_predictions.jsonl \

    outputs/predictions/seed20260511_v6/generated_predictions.jsonl \

    outputs/predictions/seed20260511_v7/generated_predictions.jsonl \

    outputs/predictions/seed20260511_v8/generated_predictions.jsonl \

  --weights 1 1 1 1 1 1 1 \

  --best_index 0 \

  --total_score_fusion mean \

  --output_json outputs/submissions/answers/track_1_test.json

```

To fuse results from both Stage2 adapters, add all corresponding `generated_predictions.jsonl` files to `--predictions_jsonl` and provide the same number of values in `--weights`.

## 6. Output

The final result is:

```text

outputs/submissions/answers/track_1_test.json

```

The file preserves the official template structure and fills in the fused:

- `criteria.level`
- `total_score`
- `answer`

## 7. Notes

- All paths are relative to the project root.
- Image paths use the format `datasets/images/<image_name>.jpg`.
- `convert_to_answer.py` supports multi-path prediction fusion, weighted answer voting, majority voting for levels, and mean fusion for `total_score`.
- If the model output is not strict JSON, the fusion script attempts to extract the JSON snippet and answer field from text.