Spaces:
Running
Running
Add fp16→fp32 fallback for vision encoder WebGPU compatibility
Browse files- js/constants.js +154 -84
- js/model.js +31 -3
js/constants.js
CHANGED
|
@@ -4,7 +4,10 @@
|
|
| 4 |
* Ported from hf_space/constants.py.
|
| 5 |
*/
|
| 6 |
|
|
|
|
| 7 |
// Prompts
|
|
|
|
|
|
|
| 8 |
export const INTERPRET_PROMPT =
|
| 9 |
"Provide a comprehensive clinical interpretation of this fetal ultrasound " +
|
| 10 |
"image. Identify all visible anatomical structures, describe the fetal " +
|
|
@@ -21,7 +24,10 @@ export const CLASSIFY_PROMPT =
|
|
| 21 |
"What anatomical view or structure does it show? " +
|
| 22 |
'Return a JSON object with "label" as the classification.';
|
| 23 |
|
|
|
|
| 24 |
// Classification -> Detection / Segmentation class mapping
|
|
|
|
|
|
|
| 25 |
export const CLASSIFY_TO_DETECT = {
|
| 26 |
huvf: "abdomen, arm, head, legs",
|
| 27 |
huvb: "abdomen, arm, head, legs",
|
|
@@ -58,20 +64,39 @@ export const SPECIFIC_CLS_LABELS = new Set([
|
|
| 58 |
"V sign", "X sign", "liver",
|
| 59 |
]);
|
| 60 |
|
| 61 |
-
//
|
|
|
|
|
|
|
|
|
|
| 62 |
export const KEYWORD_FALLBACK = [
|
| 63 |
-
[["cerebel","cervellet","ventric","thalm","bpd",
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
[["
|
| 68 |
-
|
| 69 |
-
[["
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
[["
|
| 73 |
-
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
];
|
| 76 |
|
| 77 |
export const DEFAULT_DETECT_CLASSES = "abdomen, arm, head, legs";
|
|
@@ -86,103 +111,145 @@ export function keywordLookup(text) {
|
|
| 86 |
return null;
|
| 87 |
}
|
| 88 |
|
| 89 |
-
//
|
|
|
|
|
|
|
|
|
|
| 90 |
export const FIELD_WEIGHTS = {
|
| 91 |
-
biometric_measurements: 3.0,
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
};
|
| 96 |
|
| 97 |
export const CLASS_KEYWORDS = {
|
| 98 |
-
Brain:["brain","cerebr","cerebellum","cortex","vermis",
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
};
|
| 120 |
|
| 121 |
export const CO_OCCURRENCE_GROUPS = [
|
| 122 |
-
["brain",["Brain","CSP","LV"],["Brain"],["nt_nasal"]],
|
| 123 |
-
["cardiac",["cardiac","thorax"],["cardiac","thorax"],[]],
|
| 124 |
-
["nt_nasal",["NT","nasal_bone","nasal_skin","nasal_tip"],["NT"],["brain","crl"]],
|
| 125 |
-
["crl",["B","CRL","H","NB"],null,["nt_nasal"]],
|
| 126 |
-
["doppler",["artery","liver","stomach","vein"],["artery","liver","stomach","vein"],[]],
|
| 127 |
-
["pelvimetry",["fetal_head","pubic_symphysis"],["fetal_head","pubic_symphysis"],[]],
|
| 128 |
-
["body_full",["abdomen","arm","head","legs"],null,[]],
|
| 129 |
-
["femur",["legs"],null,[]],
|
| 130 |
];
|
| 131 |
|
| 132 |
export const GROUP_ALIASES = {
|
| 133 |
-
brain:["bpd","biparietal"," hc ","head circumference",
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
};
|
| 142 |
|
| 143 |
export const PLANE_TO_GROUP = {
|
| 144 |
-
"trans-thalamic":"brain",transthalamic:"brain",
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
"
|
| 149 |
-
|
| 150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
};
|
| 152 |
|
| 153 |
export const NEGATIVE_MEASUREMENT_PATTERNS = [
|
| 154 |
-
"not measurable","not visible","cannot be measured",
|
| 155 |
-
"
|
|
|
|
| 156 |
];
|
| 157 |
|
|
|
|
| 158 |
// Routing group map
|
|
|
|
|
|
|
| 159 |
export const ROUTING_GROUP_MAP = {
|
| 160 |
-
brain:["Brain, CSP, LV","Brain"],
|
| 161 |
-
cardiac:["cardiac, thorax","cardiac, thorax"],
|
| 162 |
-
nt_nasal:["NT, nasal_bone, nasal_skin, nasal_tip","NT"],
|
| 163 |
-
crl:["B, CRL, H, NB",null],
|
| 164 |
-
doppler:["artery, liver, stomach, vein","artery, liver, stomach, vein"],
|
| 165 |
-
pelvimetry:["fetal_head, pubic_symphysis","fetal_head, pubic_symphysis"],
|
| 166 |
-
body_pose:["abdomen, arm, head, legs",null],
|
| 167 |
-
femur:["legs",null],
|
| 168 |
-
crl_kp:["CRL_KP, ScaleBarKpoints",null],
|
| 169 |
-
nt_kp:["NTKpoints, ScaleBarKpoints",null],
|
| 170 |
};
|
| 171 |
|
| 172 |
-
//
|
|
|
|
|
|
|
|
|
|
| 173 |
const _RAW_PALETTE = [
|
| 174 |
-
"#E6194B","#3CB44B","#FFE119","#4363D8","#F58231",
|
| 175 |
-
"#911EB4","#42D4F4","#F032E6","#BFEF45","#FABED4",
|
| 176 |
-
"#469990","#DCBEFF","#9A6324","#FFFAC8","#800000",
|
| 177 |
-
"#AAFFC3","#808000","#FFD8B1","#000075","#A9A9A9",
|
| 178 |
];
|
| 179 |
|
| 180 |
const ALL_CLASSES_SORTED = [
|
| 181 |
-
"AB","B","Brain","C","CRL","CRL_KP","CSP","DP","G","H","LV",
|
| 182 |
-
"MDS","MLS","MX","NB","NT","NTAPS","NTKpoints","RBP",
|
| 183 |
-
"ScaleBar","ScaleBarKpoints",
|
| 184 |
-
"abdomen","arm","artery","cardiac",
|
| 185 |
-
"
|
|
|
|
|
|
|
| 186 |
].sort();
|
| 187 |
|
| 188 |
export const CLASS_COLORS = {};
|
|
@@ -192,7 +259,10 @@ ALL_CLASSES_SORTED.forEach((cls, i) => {
|
|
| 192 |
|
| 193 |
export { _RAW_PALETTE };
|
| 194 |
|
|
|
|
| 195 |
// Inference settings
|
|
|
|
|
|
|
| 196 |
export const TEMPERATURE = 0.1;
|
| 197 |
export const MAX_NEW_TOKENS = 1024;
|
| 198 |
export const COORD_SCALE = 1000;
|
|
|
|
| 4 |
* Ported from hf_space/constants.py.
|
| 5 |
*/
|
| 6 |
|
| 7 |
+
// ---------------------------------------------------------------------------
|
| 8 |
// Prompts
|
| 9 |
+
// ---------------------------------------------------------------------------
|
| 10 |
+
|
| 11 |
export const INTERPRET_PROMPT =
|
| 12 |
"Provide a comprehensive clinical interpretation of this fetal ultrasound " +
|
| 13 |
"image. Identify all visible anatomical structures, describe the fetal " +
|
|
|
|
| 24 |
"What anatomical view or structure does it show? " +
|
| 25 |
'Return a JSON object with "label" as the classification.';
|
| 26 |
|
| 27 |
+
// ---------------------------------------------------------------------------
|
| 28 |
// Classification -> Detection / Segmentation class mapping
|
| 29 |
+
// ---------------------------------------------------------------------------
|
| 30 |
+
|
| 31 |
export const CLASSIFY_TO_DETECT = {
|
| 32 |
huvf: "abdomen, arm, head, legs",
|
| 33 |
huvb: "abdomen, arm, head, legs",
|
|
|
|
| 64 |
"V sign", "X sign", "liver",
|
| 65 |
]);
|
| 66 |
|
| 67 |
+
// ---------------------------------------------------------------------------
|
| 68 |
+
// Keyword-based mapping (ordered specific-first)
|
| 69 |
+
// ---------------------------------------------------------------------------
|
| 70 |
+
|
| 71 |
export const KEYWORD_FALLBACK = [
|
| 72 |
+
[["cerebel", "cervellet", "ventric", "thalm", "bpd",
|
| 73 |
+
"banana", "holopros", "cisterna", "fossa", "csp", "cavum",
|
| 74 |
+
"septum pellucidum", "lateral ventricle"],
|
| 75 |
+
"Brain, CSP, LV", "Brain"],
|
| 76 |
+
[["brain"],
|
| 77 |
+
"Brain, CSP, LV", "Brain"],
|
| 78 |
+
[["cardiac", "thorax", "thorac", "thoric", "thorcic",
|
| 79 |
+
"aort", "heart", "stenos", "chamber", "valve"],
|
| 80 |
+
"cardiac, thorax", "cardiac, thorax"],
|
| 81 |
+
[["fetal head", "fetal_head", "cervix", "cervic", "cervex", "pubic", "symphys",
|
| 82 |
+
"pelvimetr", "angle of progression"],
|
| 83 |
+
"fetal_head, pubic_symphysis", "fetal_head, pubic_symphysis"],
|
| 84 |
+
[["femur", "femoral", "fetal.femur", "fetal-femur"],
|
| 85 |
+
"legs", null],
|
| 86 |
+
[["nasal", "nuchal", "translucen"],
|
| 87 |
+
"NT, nasal_bone, nasal_skin, nasal_tip", "NT"],
|
| 88 |
+
[["crl", "crown", "rump"],
|
| 89 |
+
"B, CRL, H, NB", null],
|
| 90 |
+
[["liver", "stomach", "vein", "artery"],
|
| 91 |
+
"artery, liver, stomach, vein", "artery, liver, stomach, vein"],
|
| 92 |
+
[["abdomen", "abdom"],
|
| 93 |
+
"abdomen", null],
|
| 94 |
+
[["arm"],
|
| 95 |
+
"abdomen, arm", null],
|
| 96 |
+
[["head"],
|
| 97 |
+
"head", null],
|
| 98 |
+
[["leg"],
|
| 99 |
+
"abdomen, legs", null],
|
| 100 |
];
|
| 101 |
|
| 102 |
export const DEFAULT_DETECT_CLASSES = "abdomen, arm, head, legs";
|
|
|
|
| 111 |
return null;
|
| 112 |
}
|
| 113 |
|
| 114 |
+
// ---------------------------------------------------------------------------
|
| 115 |
+
// Per-class keyword scoring for interpretation-first mapping
|
| 116 |
+
// ---------------------------------------------------------------------------
|
| 117 |
+
|
| 118 |
export const FIELD_WEIGHTS = {
|
| 119 |
+
biometric_measurements: 3.0,
|
| 120 |
+
imaging_plane: 2.5,
|
| 121 |
+
anatomical_structures: 1.0,
|
| 122 |
+
fetal_orientation: 0.5,
|
| 123 |
+
normality_assessment: 0.5,
|
| 124 |
+
gestational_age: 0.3,
|
| 125 |
+
image_quality: 0.0,
|
| 126 |
+
clinical_recommendations: 0.3,
|
| 127 |
};
|
| 128 |
|
| 129 |
export const CLASS_KEYWORDS = {
|
| 130 |
+
Brain: ["brain", "cerebr", "cerebellum", "cortex", "vermis",
|
| 131 |
+
"falx", "interhemispheric", "cranial", "intracranial",
|
| 132 |
+
"parieto-occipital", "frontal lobe", "occipital"],
|
| 133 |
+
CSP: ["septum pellucidum", "cavum", "csp", "midline echo"],
|
| 134 |
+
LV: ["lateral ventricle", "ventricl", "choroid plexus",
|
| 135 |
+
"ventriculomegaly"],
|
| 136 |
+
cardiac: ["heart", "cardiac", "chamber", "four chamber",
|
| 137 |
+
"4-chamber", "valve", "myocard", "atri",
|
| 138 |
+
"foramen ovale", "interventricular", "aort", "aortic"],
|
| 139 |
+
thorax: ["thorax", "thorac", "thoric", "thorcic", "chest",
|
| 140 |
+
"lung", "pleural", "rib cage", "diaphragm", "mediastin"],
|
| 141 |
+
NT: ["nuchal translucen", "nuchal fold", "nuchal",
|
| 142 |
+
" nt ", " nt,", "nt_", "nt "],
|
| 143 |
+
nasal_bone: ["nasal bone", "nasal bridge"],
|
| 144 |
+
nasal_skin: ["nasal skin"],
|
| 145 |
+
nasal_tip: ["nasal tip"],
|
| 146 |
+
CRL: ["crown-rump", "crown rump", "crl"],
|
| 147 |
+
B: [],
|
| 148 |
+
H: [],
|
| 149 |
+
NB: [],
|
| 150 |
+
artery: ["artery", "arter", "umbilical arter"],
|
| 151 |
+
liver: ["liver", "hepat"],
|
| 152 |
+
stomach: ["stomach", "gastric", "stomach bubble"],
|
| 153 |
+
vein: ["vein", "venous", "vena cava", "umbilical vein"],
|
| 154 |
+
fetal_head: ["cervix", "cervic", "cervical length"],
|
| 155 |
+
pubic_symphysis: ["pubic", "symphys", "pelvimetr"],
|
| 156 |
+
abdomen: ["abdomen", "abdomin", "abdom", "ac_plane"],
|
| 157 |
+
arm: ["arm", "upper limb", "humerus"],
|
| 158 |
+
head: ["skull", "calvar", "biparietal", "fetal head", "head", "neck"],
|
| 159 |
+
legs: ["femur", "femoral", "thigh", "lower limb",
|
| 160 |
+
"lower extremit", "tibia", "legs", "leg "],
|
| 161 |
};
|
| 162 |
|
| 163 |
export const CO_OCCURRENCE_GROUPS = [
|
| 164 |
+
["brain", ["Brain", "CSP", "LV"], ["Brain"], ["nt_nasal"]],
|
| 165 |
+
["cardiac", ["cardiac", "thorax"], ["cardiac", "thorax"], []],
|
| 166 |
+
["nt_nasal", ["NT", "nasal_bone", "nasal_skin", "nasal_tip"], ["NT"], ["brain", "crl"]],
|
| 167 |
+
["crl", ["B", "CRL", "H", "NB"], null, ["nt_nasal"]],
|
| 168 |
+
["doppler", ["artery", "liver", "stomach", "vein"], ["artery", "liver", "stomach", "vein"], []],
|
| 169 |
+
["pelvimetry", ["fetal_head", "pubic_symphysis"], ["fetal_head", "pubic_symphysis"], []],
|
| 170 |
+
["body_full", ["abdomen", "arm", "head", "legs"], null, []],
|
| 171 |
+
["femur", ["legs"], null, []],
|
| 172 |
];
|
| 173 |
|
| 174 |
export const GROUP_ALIASES = {
|
| 175 |
+
brain: ["bpd", "biparietal", " hc ", "head circumference",
|
| 176 |
+
"v sign", "x sign", "trans-thalamic", "trans-cerebellar",
|
| 177 |
+
"transventricular", "transcerebellar"],
|
| 178 |
+
crl: ["first trimester", "dating scan", "embryo",
|
| 179 |
+
"sagittal profile"],
|
| 180 |
+
femur: [" fl ", "femur length", "fl_plane", "fl plane", "fl "],
|
| 181 |
+
body_full: ["abdominal circumference", " ac ", "ac_plane",
|
| 182 |
+
"ac plane", "fetal pose", "body habitus",
|
| 183 |
+
"no_plane", "no plane"],
|
| 184 |
+
doppler: ["doppler", "flow", "waveform", "pulsatility",
|
| 185 |
+
"resistance index", "stomach bubble",
|
| 186 |
+
"hepatic", "ductus venosus", "umbilical arter",
|
| 187 |
+
"umbilical vein"],
|
| 188 |
+
nt_nasal: ["first trimester screen", "aneuploidy", "trisomy",
|
| 189 |
+
"down syndrome"],
|
| 190 |
+
pelvimetry: ["pelvimetry", "pelvic", "birth canal",
|
| 191 |
+
"vaginal delivery"],
|
| 192 |
+
cardiac: ["echocardiogra", "outflow tract", "aortic arch", "aorta"],
|
| 193 |
};
|
| 194 |
|
| 195 |
export const PLANE_TO_GROUP = {
|
| 196 |
+
"trans-thalamic": "brain", transthalamic: "brain",
|
| 197 |
+
"trans-cerebellar": "brain", transcerebellar: "brain",
|
| 198 |
+
transventricular: "brain", biparietal: "brain",
|
| 199 |
+
"four chamber": "cardiac", "4-chamber": "cardiac",
|
| 200 |
+
"4 chamber": "cardiac", "outflow tract": "cardiac",
|
| 201 |
+
"three vessel": "cardiac", aortic: "cardiac",
|
| 202 |
+
nuchal: "nt_nasal",
|
| 203 |
+
"longitudinal view of femur": "femur", "femur length": "femur",
|
| 204 |
+
"abdominal circumference": "body_full", "ac plane": "body_full",
|
| 205 |
+
"crown-rump": "crl", "crown rump": "crl",
|
| 206 |
+
doppler: "doppler", waveform: "doppler",
|
| 207 |
+
"abdominal organ": "doppler", "stomach bubble": "doppler",
|
| 208 |
+
"cervical length": "pelvimetry",
|
| 209 |
};
|
| 210 |
|
| 211 |
export const NEGATIVE_MEASUREMENT_PATTERNS = [
|
| 212 |
+
"not measurable", "not visible", "cannot be measured",
|
| 213 |
+
"unable to measure", "not assessed", "not obtained",
|
| 214 |
+
"not clearly", "inadequate",
|
| 215 |
];
|
| 216 |
|
| 217 |
+
// ---------------------------------------------------------------------------
|
| 218 |
// Routing group map
|
| 219 |
+
// ---------------------------------------------------------------------------
|
| 220 |
+
|
| 221 |
export const ROUTING_GROUP_MAP = {
|
| 222 |
+
brain: ["Brain, CSP, LV", "Brain"],
|
| 223 |
+
cardiac: ["cardiac, thorax", "cardiac, thorax"],
|
| 224 |
+
nt_nasal: ["NT, nasal_bone, nasal_skin, nasal_tip", "NT"],
|
| 225 |
+
crl: ["B, CRL, H, NB", null],
|
| 226 |
+
doppler: ["artery, liver, stomach, vein", "artery, liver, stomach, vein"],
|
| 227 |
+
pelvimetry: ["fetal_head, pubic_symphysis", "fetal_head, pubic_symphysis"],
|
| 228 |
+
body_pose: ["abdomen, arm, head, legs", null],
|
| 229 |
+
femur: ["legs", null],
|
| 230 |
+
crl_kp: ["CRL_KP, ScaleBarKpoints", null],
|
| 231 |
+
nt_kp: ["NTKpoints, ScaleBarKpoints", null],
|
| 232 |
};
|
| 233 |
|
| 234 |
+
// ---------------------------------------------------------------------------
|
| 235 |
+
// Color palette for annotation rendering
|
| 236 |
+
// ---------------------------------------------------------------------------
|
| 237 |
+
|
| 238 |
const _RAW_PALETTE = [
|
| 239 |
+
"#E6194B", "#3CB44B", "#FFE119", "#4363D8", "#F58231",
|
| 240 |
+
"#911EB4", "#42D4F4", "#F032E6", "#BFEF45", "#FABED4",
|
| 241 |
+
"#469990", "#DCBEFF", "#9A6324", "#FFFAC8", "#800000",
|
| 242 |
+
"#AAFFC3", "#808000", "#FFD8B1", "#000075", "#A9A9A9",
|
| 243 |
];
|
| 244 |
|
| 245 |
const ALL_CLASSES_SORTED = [
|
| 246 |
+
"AB", "B", "Brain", "C", "CRL", "CRL_KP", "CSP", "DP", "G", "H", "LV",
|
| 247 |
+
"MDS", "MLS", "MX", "NB", "NT", "NTAPS", "NTKpoints", "RBP",
|
| 248 |
+
"ScaleBar", "ScaleBarKpoints",
|
| 249 |
+
"abdomen", "arm", "artery", "cardiac",
|
| 250 |
+
"fetal_head", "head", "legs", "liver",
|
| 251 |
+
"nasal_bone", "nasal_skin", "nasal_tip",
|
| 252 |
+
"pubic_symphysis", "stomach", "thorax", "vein",
|
| 253 |
].sort();
|
| 254 |
|
| 255 |
export const CLASS_COLORS = {};
|
|
|
|
| 259 |
|
| 260 |
export { _RAW_PALETTE };
|
| 261 |
|
| 262 |
+
// ---------------------------------------------------------------------------
|
| 263 |
// Inference settings
|
| 264 |
+
// ---------------------------------------------------------------------------
|
| 265 |
+
|
| 266 |
export const TEMPERATURE = 0.1;
|
| 267 |
export const MAX_NEW_TOKENS = 1024;
|
| 268 |
export const COORD_SCALE = 1000;
|
js/model.js
CHANGED
|
@@ -46,11 +46,17 @@ export async function loadModel(onProgress, device = "webgpu") {
|
|
| 46 |
console.log(`[FADA] Loading model on device=${device}...`);
|
| 47 |
activeDevice = device;
|
| 48 |
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
revision: MODEL_REVISION,
|
| 51 |
dtype: {
|
| 52 |
embed_tokens: "q4",
|
| 53 |
-
vision_encoder:
|
| 54 |
decoder_model_merged: "q4",
|
| 55 |
},
|
| 56 |
device: device,
|
|
@@ -66,8 +72,30 @@ export async function loadModel(onProgress, device = "webgpu") {
|
|
| 66 |
}
|
| 67 |
},
|
| 68 |
});
|
| 69 |
-
console.log("[FADA] Model loaded successfully on", device);
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
onProgress?.({ status: "ready" });
|
| 72 |
})();
|
| 73 |
|
|
|
|
| 46 |
console.log(`[FADA] Loading model on device=${device}...`);
|
| 47 |
activeDevice = device;
|
| 48 |
|
| 49 |
+
// Use fp32 for vision_encoder on WASM (no fp16 benefit) or try fp16 on WebGPU with fallback
|
| 50 |
+
const visionDtype = device === "wasm" ? "fp32" : "fp16";
|
| 51 |
+
if (device === "wasm") {
|
| 52 |
+
console.log("[FADA] WASM backend selected, using fp32 for vision encoder");
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
const buildModelConfig = (vDtype) => ({
|
| 56 |
revision: MODEL_REVISION,
|
| 57 |
dtype: {
|
| 58 |
embed_tokens: "q4",
|
| 59 |
+
vision_encoder: vDtype,
|
| 60 |
decoder_model_merged: "q4",
|
| 61 |
},
|
| 62 |
device: device,
|
|
|
|
| 72 |
}
|
| 73 |
},
|
| 74 |
});
|
|
|
|
| 75 |
|
| 76 |
+
try {
|
| 77 |
+
model = await Qwen3_5ForConditionalGeneration.from_pretrained(
|
| 78 |
+
MODEL_ID,
|
| 79 |
+
buildModelConfig(visionDtype)
|
| 80 |
+
);
|
| 81 |
+
} catch (err) {
|
| 82 |
+
const isFp16Error =
|
| 83 |
+
visionDtype === "fp16" &&
|
| 84 |
+
err?.message?.toLowerCase().includes("does not support fp16");
|
| 85 |
+
|
| 86 |
+
if (isFp16Error) {
|
| 87 |
+
console.warn("[FADA] FP16 not supported on this device, retrying with FP32 vision encoder...");
|
| 88 |
+
onProgress?.({ status: "loading", file: "model", note: "FP16 not supported, loading vision encoder in FP32 mode..." });
|
| 89 |
+
model = await Qwen3_5ForConditionalGeneration.from_pretrained(
|
| 90 |
+
MODEL_ID,
|
| 91 |
+
buildModelConfig("fp32")
|
| 92 |
+
);
|
| 93 |
+
} else {
|
| 94 |
+
throw err;
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
console.log("[FADA] Model loaded successfully on", device);
|
| 99 |
onProgress?.({ status: "ready" });
|
| 100 |
})();
|
| 101 |
|