smerkd commited on
Commit
3caebc4
·
verified ·
1 Parent(s): 0bc1e6a

Initial commit

Browse files
.gitattributes CHANGED
@@ -1,35 +1 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
  *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  *.safetensors filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
README.md ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: Qwen/Qwen2.5-VL-7B-Instruct
3
+ library_name: peft
4
+ pipeline_tag: image-text-to-text
5
+ license: cc-by-nc-4.0
6
+ tags:
7
+ - lora
8
+ - peft
9
+ - qwen2_5_vl
10
+ - video
11
+ - video-language-model
12
+ - lab-supervision
13
+ - wet-lab
14
+ - protocol-monitoring
15
+ - error-detection
16
+ - spatial-grounding
17
+ ---
18
+
19
+ # LabOS-VLM-7B
20
+
21
+ LabOS-VLM-7B is a PEFT LoRA adapter for `Qwen/Qwen2.5-VL-7B-Instruct`, fine-tuned on wet-lab supervision tasks from the LabOS JoVE and FineBio datasets and validated on the LSV benchmark. These tasks include protocol monitoring/step prediction, error detection, spatial grounding, protocol generation, and general VQA with first-person and third-person views.
22
+
23
+ The adapter is intended for research on laboratory video-language assistants. It works best with the JSON-style monitoring and benchmark prompts used by the LabOS datasets, for example the public LSV benchmark at [`cong-lab/lsv`](https://huggingface.co/datasets/cong-lab/lsv).
24
+
25
+ ## Adapter Details
26
+
27
+ - Base model: `Qwen/Qwen2.5-VL-7B-Instruct`
28
+ - Adapter repo: `cong-lab/labos-vlm-7b`
29
+ - Adapter type: LoRA via PEFT / MS-SWIFT
30
+ - Rank / alpha / dropout: `32 / 64 / 0.05`
31
+ - Target modules: Qwen language-model projection layers matching `q_proj`, `k_proj`, `v_proj`, `o_proj`, `gate_proj`, `up_proj`, and `down_proj`
32
+ - Training data: `lab_supervision_25k_train.jsonl` / `lab_supervision_25k_val.jsonl`
33
+
34
+ ## Install
35
+
36
+ Install a CUDA-enabled PyTorch stack plus the model runtime dependencies:
37
+
38
+ ```bash
39
+ python -m pip install -r requirements.txt
40
+ ```
41
+
42
+ For Qwen2.5-VL video inference, `flash-attn` is recommended.
43
+
44
+ ## Run With MS-SWIFT
45
+
46
+ ```bash
47
+ swift infer \
48
+ --model Qwen/Qwen2.5-VL-7B-Instruct \
49
+ --adapters cong-lab/labos-vlm-7b \
50
+ --infer_backend pt
51
+ ```
52
+
53
+ For a locally downloaded or modified adapter, replace the adapter ID with a local folder path:
54
+
55
+ ```bash
56
+ swift infer \
57
+ --model Qwen/Qwen2.5-VL-7B-Instruct \
58
+ --adapters ./labos-vlm-7b \
59
+ --infer_backend pt
60
+ ```
61
+
62
+ ## Run With Transformers And PEFT
63
+
64
+ ```python
65
+ from peft import PeftModel
66
+ from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration
67
+
68
+ base_model = "Qwen/Qwen2.5-VL-7B-Instruct"
69
+ adapter = "cong-lab/labos-vlm-7b" # or a path to a local adapter folder
70
+
71
+ processor = AutoProcessor.from_pretrained(base_model)
72
+ model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
73
+ base_model,
74
+ torch_dtype="auto",
75
+ device_map="auto",
76
+ )
77
+ model = PeftModel.from_pretrained(model, adapter)
78
+ ```
79
+
80
+ ## Evaluate On LSV
81
+
82
+ The public LSV benchmark (`cong-lab/lsv`) includes video manifests, prompt loaders, and report generation for step prediction, monitoring-state advancement, and error detection.
83
+
84
+ ```bash
85
+ hf download cong-lab/lsv --repo-type dataset --local-dir ./lsv
86
+ cd lsv
87
+ python -m pip install -r requirements.txt
88
+ python inference.py \
89
+ --model Qwen/Qwen2.5-VL-7B-Instruct \
90
+ --adapter cong-lab/labos-vlm-7b \
91
+ --output runs/labos_vlm_7b \
92
+ --gpus 0
93
+ python generate_report.py \
94
+ --output runs/labos_vlm_7b \
95
+ --report-dir runs/labos_vlm_7b_report
96
+ ```
97
+
98
+ ## Example Monitoring Prompt
99
+
100
+ This adapter was fine-tuned with prompts similar to:
101
+
102
+ ```text
103
+ You are a real-time lab assistant monitoring a scientist's wet-lab procedure from short video windows.
104
+
105
+ The current protocol state/history is provided below. Watch the current window and update the state.
106
+
107
+ Report protocol errors only when supported by the visible time window or state.
108
+
109
+ Compare the protocol order, prior history, and watched window.
110
+
111
+ Identify the main protocol step being performed in this watched video window.
112
+
113
+ STATE:
114
+ {"history":[{"step":"2","tas":0,"tds":0},{"step":"3","tas":30,"tds":30}],"on":"3","protocol":[{"desc":"Take HEK293T cells and culture them to ~70% confluency in a 10 cm dish.","order":1,"step":"1"},{"desc":"In a sterile 1.5 mL tube, mix lentiviral backbone, packaging plasmid, and envelope plasmid.","order":2,"step":"2"},{"desc":"Add transfection reagent and bring to volume with serum-free medium.","order":3,"step":"3"},{"desc":"Incubate the mixture at room temperature for 15 minutes.","order":4,"step":"4"}]}
115
+
116
+ Return the visible protocol step ID for the watched video window.
117
+ ```
118
+
119
+ Run `python generate_monitoring_prompts.py` from this repository to print additional self-contained monitoring examples.
120
+
121
+ ## Training Parameters
122
+
123
+ - Trainer: MS-SWIFT SFT with PEFT LoRA
124
+ - Epochs: `2.0` (best chkpt @1ep)
125
+ - Devices: `8` H100 GPUs
126
+ - Per-device train batch size: `1`
127
+ - Gradient accumulation steps: `4`
128
+ - Effective global train batch size: `32` examples per optimizer step
129
+ - Per-device eval batch size: `1`
130
+ - Learning rate: `1e-4`
131
+ - Scheduler: cosine
132
+ - Warmup ratio: `0.03`
133
+ - Optimizer: `adamw_torch_fused`
134
+ - Weight decay: `0.1`
135
+ - Adam betas: `(0.9, 0.95)`
136
+ - Max gradient norm: `1.0`
137
+ - Precision: `bfloat16`
138
+ - Max sequence length: `4096`
139
+ - Gradient checkpointing: enabled
140
+ - DeepSpeed: ZeRO-2
141
+ - Vision tower and aligner: frozen
142
+ - Evaluation/checkpoint interval: every `250` steps
143
+
144
+ ## Limitations
145
+
146
+ This adapter is intended for research on wet-lab video supervision and should not be used as the sole source of truth for laboratory safety or procedural correctness. Human review remains required for wet-lab execution.
147
+
148
+ ## License
149
+
150
+ This adapter is released for non-commercial research use under the Creative Commons Attribution-NonCommercial 4.0 license (`CC-BY-NC-4.0`), matching the public LSV benchmark license.
151
+
152
+ ## Research Use Only
153
+
154
+ This model is provided for research purposes only and for non-commercial use. It is not intended for clinical decision-making or replacing trained human supervision in real wet-lab procedures.
adapter_config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": null,
6
+ "base_model_name_or_path": "Qwen/Qwen2.5-VL-7B-Instruct",
7
+ "bias": "none",
8
+ "corda_config": null,
9
+ "ensure_weight_tying": false,
10
+ "eva_config": null,
11
+ "exclude_modules": null,
12
+ "fan_in_fan_out": false,
13
+ "inference_mode": true,
14
+ "init_lora_weights": true,
15
+ "layer_replication": null,
16
+ "layers_pattern": null,
17
+ "layers_to_transform": null,
18
+ "loftq_config": {},
19
+ "lora_alpha": 64,
20
+ "lora_bias": false,
21
+ "lora_dropout": 0.05,
22
+ "lora_ga_config": null,
23
+ "megatron_config": null,
24
+ "megatron_core": "megatron.core",
25
+ "modules_to_save": [],
26
+ "peft_type": "LORA",
27
+ "peft_version": "0.19.1",
28
+ "qalora_group_size": 16,
29
+ "r": 32,
30
+ "rank_pattern": {},
31
+ "revision": null,
32
+ "target_modules": "^(model\\.language_model(?=\\.).*\\.(up_proj|k_proj|o_proj|gate_proj|down_proj|q_proj|v_proj))$",
33
+ "target_parameters": null,
34
+ "task_type": "CAUSAL_LM",
35
+ "trainable_token_indices": null,
36
+ "use_bdlora": null,
37
+ "use_dora": false,
38
+ "use_qalora": false,
39
+ "use_rslora": false
40
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:992d28b53a5dbacee5f60be8ef1bfb28b16439750e548e0084cfe6e64b5f6b12
3
+ size 161539464
generate_monitoring_prompts.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Print example LabOS-VLM monitoring prompts.
3
+
4
+ These examples are self-contained and mirror the JSON-style monitoring prompts
5
+ used when fine-tuning the LabOS-VLM-7B LoRA adapter.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ from typing import Any
12
+
13
+
14
+ def compact_json(value: Any) -> str:
15
+ return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
16
+
17
+
18
+ def response_format_block(schema: dict[str, Any]) -> str:
19
+ return "\n".join([
20
+ "Return strict JSON only.",
21
+ f"## Response Format\n{json.dumps(schema, ensure_ascii=False, indent=2, sort_keys=True)}",
22
+ ])
23
+
24
+
25
+ def example_state() -> dict[str, Any]:
26
+ return {
27
+ "protocol_summary": "Demonstration of aseptic pipetting technique.",
28
+ "reagents": ["sample buffer", "cell culture media"],
29
+ "equipment": ["P20 pipette", "sterile tips", "microcentrifuge tube rack"],
30
+ "protocol": [
31
+ {"step": "1", "order": 1, "desc": "Place the tubes in a clean rack."},
32
+ {"step": "2", "order": 2, "desc": "Attach a new sterile pipette tip."},
33
+ {"step": "3", "order": 3, "desc": "Aspirate reagent without touching the tube wall."},
34
+ {"step": "4", "order": 4, "desc": "Dispense reagent into the target tube."},
35
+ ],
36
+ "history": [{"step": "1", "tds": 20, "tas": 20}],
37
+ "on": "2",
38
+ "objects": {},
39
+ }
40
+
41
+
42
+ def render_step_identification_prompt(state: dict[str, Any]) -> str:
43
+ schema = {
44
+ "observed_step_id": "string or null",
45
+ "explanation": "string",
46
+ }
47
+ return "\n\n".join([
48
+ "You are a real-time lab assistant monitoring a scientist's wet-lab procedure from short video windows.",
49
+ "The current protocol state/history is provided below. Watch the current window and update the state.",
50
+ "Report protocol errors only when supported by the visible time window or state.",
51
+ "Ignore irrelevant unknown keys in the state JSON.",
52
+ "Compare the protocol order, prior history, and watched window.",
53
+ "Identify the main protocol step being performed in this watched video window.",
54
+ f"STATE:\n{compact_json(state)}",
55
+ response_format_block(schema),
56
+ "## Question\nWhich protocol step is being performed in this video window?",
57
+ ])
58
+
59
+
60
+ def render_monitoring_delta_prompt(state: dict[str, Any]) -> str:
61
+ schema = {
62
+ "history": [
63
+ {
64
+ "step": "string",
65
+ "tds": "integer seconds spent on this step in the watched window",
66
+ "tas": "integer absolute seconds from the start of the video",
67
+ }
68
+ ],
69
+ "on": "string or null",
70
+ "errors": [
71
+ {
72
+ "type": "skipped_step | wrong_order | wrong_reagent | contamination | other",
73
+ "step": "string or null",
74
+ "description": "string",
75
+ }
76
+ ],
77
+ }
78
+ return "\n\n".join([
79
+ "You are a real-time lab assistant monitoring a scientist's wet-lab procedure from short video windows.",
80
+ "The current protocol state/history is provided below. Watch the current window and update the state.",
81
+ "Report protocol errors only when supported by the visible time window or state.",
82
+ "Ignore irrelevant unknown keys in the state JSON.",
83
+ "Append only the newly observed history entries and update the current step.",
84
+ f"STATE:\n{compact_json(state)}",
85
+ response_format_block(schema),
86
+ "Return an append-style delta update for only the watched video window.",
87
+ ])
88
+
89
+
90
+ def main() -> None:
91
+ state = example_state()
92
+ prompts = [
93
+ ("STEP IDENTIFICATION", render_step_identification_prompt(state)),
94
+ ("MONITORING DELTA", render_monitoring_delta_prompt(state)),
95
+ ]
96
+ for title, prompt in prompts:
97
+ print(f"===== {title} =====")
98
+ print(prompt)
99
+ print()
100
+
101
+
102
+ if __name__ == "__main__":
103
+ main()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ torch
2
+ transformers
3
+ peft
4
+ qwen-vl-utils
5
+ decord
6
+ flash-attn