ThermoQwen TSF 是一款基于大语言模型(LLM)的温跃层深度时间序列预测器。该模型采用 Qwen3-1.7B + LoRA 作为回归模型,通过本地自主水下航行器(AUV)的短观测片段推断未来温跃层中心深度。每个片段包含过去 K 个本地深度-温度/盐度摘要以及季节性背景信息。模型可预测未来 H 个温跃层中心深度 z,其中 z 为绝对温度梯度达到最大值时的深度。
本仓库已封装为 Hugging Face 自定义模型,导出的权重包含 Qwen 主干网络、LoRA 权重以及 TSF 回归头。本模型遵循 Qwen3-1.7B 基础模型的许可协议。
Argo 浮标剖面数据——国际 Argo 计划(https://argo.ucsd.edu),知识共享署名许可(CC-BY)。
引用:Argo (2024). Argo GDAC. SEANOE. https://doi.org/10.17882/42182
NOAA 数据(NCEI Accession 0173210)——源自世界海洋数据库(WOD)CTD/XBT 剖面数据(1960–2017),公共领域。
引用:Chu, P.C., Fan, C. (2018). https://doi.org/10.25921/dgak-7a43
使用的子集区域:东经 110–119°,北纬 9–19°(南海)。
评估集除包含上述公开数据集的预留分割数据外,还包括现场 CTD 测量数据。
q_proj、k_proj、v_proj 和 o_proj 层上应用 LoRA[last_token_pool ; mean_pool]LayerNorm -> Linear(4096, 256) -> GELU -> Dropout -> Linear(256, 64) -> GELU -> Dropout -> Linear(64, H)outputs.pred_depths 输出未来温跃层中心深度(单位:米)用户输入为 JSON 格式的本地观测片段。observations 中的每个元素是单个本地 AUV 观测窗口的精简摘要:
depth:AUV 深度(单位:米),水下深度用负值表示。T_grad:本地采样窗口内的最大绝对温度差。avg_T:本地采样窗口内的平均温度。S_grad:本地采样窗口内的最大绝对盐度差。avg_S:本地采样窗口内的平均盐度。{
"season": "Winter",
"doy": 7,
"doy_sin": 0.1202,
"doy_cos": 0.9927,
"typical_thermocline_depth": "65-125 m",
"horizon": 5,
"observations": [
{"depth": -109.7, "T_grad": 0.6064, "avg_T": 16.46, "S_grad": 0.0075, "avg_S": 34.61},
{"depth": -174.3, "T_grad": 0.1081, "avg_T": 14.44, "S_grad": 0.0048, "avg_S": 34.55}
]
}JSON 数据会被转换为微调过程中使用的相同 Qwen 聊天风格提示词,然后进行分词并传递给自定义模型。下面是一个简单示例。
import json
import torch
from transformers import AutoModel, AutoTokenizer
model_id = "zetian123123/thermo-qwen3-tsf"
sample_json = """
{
"season": "Winter",
"doy": 7,
"doy_sin": 0.1202,
"doy_cos": 0.9927,
"typical_thermocline_depth": "65-125 m",
"horizon": 5,
"observations": [
{"depth": -109.7, "T_grad": 0.6064, "avg_T": 16.46, "S_grad": 0.0075, "avg_S": 34.61},
{"depth": -174.3, "T_grad": 0.1081, "avg_T": 14.44, "S_grad": 0.0048, "avg_S": 34.55},
{"depth": -33.6, "T_grad": 2.7128, "avg_T": 24.29, "S_grad": 0.4870, "avg_S": 34.07}
]
}
"""
def build_prompt(sample):
season = sample["season"]
horizon = int(sample["horizon"])
obs_lines = []
for idx, obs in enumerate(sample["observations"], start=1):
obs_lines.append(
f"Step {idx:2d}: depth={obs['depth']:7.1f}m"
f" T_grad={obs['T_grad']:.4f} avg_T={obs['avg_T']:.2f}"
f" S_grad={obs['S_grad']:.4f} avg_S={obs['avg_S']:.2f}"
)
return (
f"<s><|im_start|>system\n"
f"You are an expert oceanographer. In {season}, predict the thermocline "
f"center depth (depth of maximum temperature gradient) for the next "
f"{horizon} timesteps based on AUV observations.<|im_end|>\n"
f"<|im_start|>user\n"
f"Season: {season} | DOY: {int(sample['doy'])} | "
f"sin={sample['doy_sin']:.4f} | cos={sample['doy_cos']:.4f}\n"
f"In {season}, thermocline typically at "
f"{sample['typical_thermocline_depth']}.\n\n"
f"[AUV Observations - {len(sample['observations'])} steps]\n"
+ "\n".join(obs_lines)
+ f"\n\nPredict thermocline center depth for the next {horizon} timesteps."
f"<|im_end|>\n"
f"<|im_start|>assistant\n"
)
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModel.from_pretrained(model_id, trust_remote_code=True, torch_dtype="auto")
model.eval()
sample = json.loads(sample_json)
prompt = build_prompt(sample)
inputs = tokenizer(
prompt,
add_special_tokens=False,
max_length=1024,
padding="max_length",
truncation=True,
return_tensors="pt",
)
with torch.inference_mode():
outputs = model(**inputs)
print(outputs.pred_depths.squeeze(0).tolist())模型返回:
outputs.logits:归一化深度预测值,范围为 [-1, 1]outputs.pred_depths:反归一化深度值,单位为米深度约定:水深用负值表示,例如 -50 m。
该模型旨在用于基于AUV/CTD观测总结的温跃层深度离线预测研究。它不是独立的导航控制器,未经额外验证,不应用于安全关键的AUV决策。