aa
This commit is contained in:
2
.trash/detection_pipeline_data_flow_v2_scene_memory.svg
Normal file
2
.trash/detection_pipeline_data_flow_v2_scene_memory.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 46 KiB |
290
.trash/gen_er_diagram.py
Normal file
290
.trash/gen_er_diagram.py
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate db_schema.svg — an entity-relationship diagram of the alert4k data model.
|
||||||
|
|
||||||
|
Hand-curated layout. Re-run to regenerate the SVG after schema changes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ---- visual constants -------------------------------------------------------
|
||||||
|
HEADER_H = 28
|
||||||
|
ROW_H = 17
|
||||||
|
PAD_X = 10
|
||||||
|
FONT = "font-family='Menlo, Consolas, monospace'"
|
||||||
|
|
||||||
|
# table accent colours
|
||||||
|
C_HUB = "#2c3e7a" # events
|
||||||
|
C_DET = "#1f7a4d" # detection-ish (detections, clip_detections, clip_tracks)
|
||||||
|
C_ID = "#9a4d1f" # identity (object_identities)
|
||||||
|
C_REF = "#6a3d8a" # reference dictionaries (known/tracked objects)
|
||||||
|
C_MOT = "#7a1f3d" # motion / scene infra
|
||||||
|
|
||||||
|
# (label, kind) kind: 'pk','fk','col'
|
||||||
|
def col(label, kind="col"):
|
||||||
|
return (label, kind)
|
||||||
|
|
||||||
|
tables = {
|
||||||
|
"events": {
|
||||||
|
"x": 470, "y": 90, "w": 270, "accent": C_HUB,
|
||||||
|
"subtitle": "ROOT — one row per motion event",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("trigger_ts timestamptz"),
|
||||||
|
col("source_name varchar"),
|
||||||
|
col("motion_score float8"),
|
||||||
|
col("snapshot_path text"),
|
||||||
|
col("clip_path text"),
|
||||||
|
col("frame4k_path text"),
|
||||||
|
col("annotated_frame_path text"),
|
||||||
|
col("description text"),
|
||||||
|
col("false_positive bool"),
|
||||||
|
col("absorbed / san_suppress bool"),
|
||||||
|
col("clip_duration_seconds f4"),
|
||||||
|
col("motion_roi_x1..y2 float"),
|
||||||
|
col("blob_count/total/min/max"),
|
||||||
|
col("pipeline_stage varchar"),
|
||||||
|
col("clip_tracks_version int"),
|
||||||
|
col("scene_background_id → scene_backgrounds", "fk"),
|
||||||
|
col("created_at timestamptz"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"scene_backgrounds": {
|
||||||
|
"x": 70, "y": 70, "w": 250, "accent": C_MOT,
|
||||||
|
"subtitle": "camera calibration backdrop",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("camera_id varchar"),
|
||||||
|
col("image_path text"),
|
||||||
|
col("scene_version_id int"),
|
||||||
|
col("quality_score float"),
|
||||||
|
col("pose_signature text"),
|
||||||
|
col("created_at timestamptz"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"motion_detections": {
|
||||||
|
"x": 70, "y": 420, "w": 250, "accent": C_MOT,
|
||||||
|
"subtitle": "raw MOG2 blobs (motion svc)",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("event_id → events (NULL=unclaimed)", "fk"),
|
||||||
|
col("frame_ts timestamptz"),
|
||||||
|
col("blob_x1..y2 float"),
|
||||||
|
col("area_px int"),
|
||||||
|
col("motion_ratio float"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"detections": {
|
||||||
|
"x": 470, "y": 560, "w": 270, "accent": C_DET,
|
||||||
|
"subtitle": "single-frame GDINO @ trigger",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("event_id → events", "fk"),
|
||||||
|
col("phrase varchar"),
|
||||||
|
col("score float8"),
|
||||||
|
col("cx, cy, w, h (normalized)"),
|
||||||
|
col("created_at"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"clip_tracks": {
|
||||||
|
"x": 840, "y": 70, "w": 280, "accent": C_DET,
|
||||||
|
"subtitle": "one row per ByteTrack track in clip",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("event_id → events", "fk"),
|
||||||
|
col("track_id int"),
|
||||||
|
col("phrase varchar"),
|
||||||
|
col("first_seen_s / last_seen_s"),
|
||||||
|
col("frame_count int"),
|
||||||
|
col("max_score float"),
|
||||||
|
col("path_json text [{t,cx,cy}]"),
|
||||||
|
col("tags jsonb"),
|
||||||
|
col("displacement float"),
|
||||||
|
col("path_metrics real[]"),
|
||||||
|
col("quality_metrics real[]"),
|
||||||
|
col("track_embedding bytea (CLIP)"),
|
||||||
|
col("image_quality / caption_quality"),
|
||||||
|
col("tq_suppress bool"),
|
||||||
|
col("alpha_crop_path text"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"clip_detections": {
|
||||||
|
"x": 840, "y": 540, "w": 280, "accent": C_DET,
|
||||||
|
"subtitle": "per-frame GDINO sampled from clip",
|
||||||
|
"cols": [
|
||||||
|
col("event_id → events", "fk"),
|
||||||
|
col("track_id → clip_tracks (soft)", "fk"),
|
||||||
|
col("frame_time_s real"),
|
||||||
|
col("phrase char(1) code"),
|
||||||
|
col("score real"),
|
||||||
|
col("cx, cy, w, h real"),
|
||||||
|
col("created_at"),
|
||||||
|
col("(no PK since V15 — narrow table)"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"object_identities": {
|
||||||
|
"x": 1230, "y": 360, "w": 290, "accent": C_ID,
|
||||||
|
"subtitle": "JUNCTION — recognition result",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("event_id → events", "fk"),
|
||||||
|
col("detection_idx int"),
|
||||||
|
col("phrase varchar"),
|
||||||
|
col("embedding bytea (CLIP crop)"),
|
||||||
|
col("crop_path text"),
|
||||||
|
col("known_object_id → known_objects", "fk"),
|
||||||
|
col("tracked_object_id → tracked_objects", "fk"),
|
||||||
|
col("clip_track_id → clip_tracks", "fk"),
|
||||||
|
col("identity_type 'detection'|'track'"),
|
||||||
|
col("match_score float8"),
|
||||||
|
col("is_new bool"),
|
||||||
|
col("created_at"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"known_objects": {
|
||||||
|
"x": 1230, "y": 70, "w": 290, "accent": C_REF,
|
||||||
|
"subtitle": "manually registered named objects",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("name varchar (e.g. 'my Honda')"),
|
||||||
|
col("phrase varchar"),
|
||||||
|
col("embedding bytea (CLIP 512f)"),
|
||||||
|
col("thumbnail_path text"),
|
||||||
|
col("notes text"),
|
||||||
|
col("created_at"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"tracked_objects": {
|
||||||
|
"x": 1230, "y": 720, "w": 290, "accent": C_REF,
|
||||||
|
"subtitle": "auto-discovered, clustered cross-event",
|
||||||
|
"cols": [
|
||||||
|
col("id", "pk"),
|
||||||
|
col("pseudo_name varchar UNIQUE"),
|
||||||
|
col("phrase varchar"),
|
||||||
|
col("embedding bytea (EMA-updated)"),
|
||||||
|
col("occurrence_count int"),
|
||||||
|
col("first_seen_ts / last_seen_ts"),
|
||||||
|
col("ground_x/y, world_x_m/y_m"),
|
||||||
|
col("sfm_confidence / confidence_score"),
|
||||||
|
col("identity_status text"),
|
||||||
|
col("best_crop_path / thumbnail_path"),
|
||||||
|
col("created_at"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def table_height(t):
|
||||||
|
return HEADER_H + 14 + ROW_H * len(t["cols"]) + 8
|
||||||
|
|
||||||
|
# anchor helpers — return (x,y) on the edge of a table box
|
||||||
|
def left(t, row=None):
|
||||||
|
y = t["y"] + HEADER_H + 14 + (ROW_H * row + ROW_H // 2 if row is not None else table_height(t)//2)
|
||||||
|
return (t["x"], y)
|
||||||
|
def right(t, row=None):
|
||||||
|
y = t["y"] + HEADER_H + 14 + (ROW_H * row + ROW_H // 2 if row is not None else table_height(t)//2)
|
||||||
|
return (t["x"] + t["w"], y)
|
||||||
|
def top(t):
|
||||||
|
return (t["x"] + t["w"]//2, t["y"])
|
||||||
|
def bottom(t):
|
||||||
|
return (t["x"] + t["w"]//2, t["y"] + table_height(t))
|
||||||
|
|
||||||
|
parts = []
|
||||||
|
W, H = 1580, 980
|
||||||
|
parts.append(f"<svg xmlns='http://www.w3.org/2000/svg' width='{W}' height='{H}' viewBox='0 0 {W} {H}'>")
|
||||||
|
parts.append(f"<rect x='0' y='0' width='{W}' height='{H}' fill='#f7f8fb'/>")
|
||||||
|
|
||||||
|
# title
|
||||||
|
parts.append(f"<text x='30' y='40' {FONT} font-size='24' font-weight='700' fill='#1a1a2e'>"
|
||||||
|
"alert4k — Relational Data Model (PostgreSQL)</text>")
|
||||||
|
parts.append(f"<text x='30' y='62' {FONT} font-size='13' fill='#555'>"
|
||||||
|
"Motion event → clip analysis → per-track CLIP identity → cross-event object clustering. "
|
||||||
|
"Solid = enforced FK · Dashed = soft/logical link.</text>")
|
||||||
|
|
||||||
|
# ---- relationship edges (drawn first, under boxes) -------------------------
|
||||||
|
def _glyph(x, y, dir_x, sym):
|
||||||
|
"""Draw a cardinality glyph at endpoint (x,y). dir_x = +1 if the line
|
||||||
|
extends to the right of the point, -1 if to the left. sym in {'one','many'}."""
|
||||||
|
o = 11 * (1 if dir_x >= 0 else -1) # offset into the line
|
||||||
|
if sym == "one":
|
||||||
|
bx = x + o * 0.55
|
||||||
|
parts.append(f"<path d='M{bx},{y-6} L{bx},{y+6}' stroke='#444' stroke-width='1.6'/>")
|
||||||
|
else: # many — crow's foot fanning into (x,y)
|
||||||
|
parts.append(f"<path d='M{x+o},{y-6} L{x},{y} L{x+o},{y+6} M{x+o},{y} L{x},{y}' "
|
||||||
|
"fill='none' stroke='#444' stroke-width='1.4'/>")
|
||||||
|
|
||||||
|
# (from_anchor, to_anchor, label, dashed)
|
||||||
|
def edge(p1, p2, label, dashed=False, lx=None, ly=None, start="one", end="many"):
|
||||||
|
dash = " stroke-dasharray='6 4'" if dashed else ""
|
||||||
|
midx = (p1[0] + p2[0]) / 2
|
||||||
|
d = f"M{p1[0]},{p1[1]} L{midx},{p1[1]} L{midx},{p2[1]} L{p2[0]},{p2[1]}"
|
||||||
|
parts.append(f"<path d='{d}' fill='none' stroke='#444' stroke-width='1.5'{dash}/>")
|
||||||
|
_glyph(p1[0], p1[1], 1 if midx >= p1[0] else -1, start)
|
||||||
|
_glyph(p2[0], p2[1], 1 if midx >= p2[0] else -1, end)
|
||||||
|
if lx is None: lx = (p1[0] + p2[0]) / 2
|
||||||
|
if ly is None: ly = (p1[1] + p2[1]) / 2
|
||||||
|
parts.append(f"<rect x='{lx-30}' y='{ly-10}' width='60' height='15' fill='#f7f8fb' opacity='0.85'/>")
|
||||||
|
parts.append(f"<text x='{lx}' y='{ly+1}' {FONT} font-size='10.5' fill='#333' text-anchor='middle'>{label}</text>")
|
||||||
|
|
||||||
|
T = tables
|
||||||
|
# events -> children (1:N). events.id is the 'one' side.
|
||||||
|
edge(left(T["events"], 1), right(T["motion_detections"], 1), "1 : N", dashed=False)
|
||||||
|
edge(bottom(T["events"]), top(T["detections"]), "1 : N")
|
||||||
|
edge(right(T["events"], 1), left(T["clip_tracks"], 1), "1 : N")
|
||||||
|
edge(right(T["events"], 5), left(T["clip_detections"], 0), "1 : N")
|
||||||
|
edge(right(T["events"], 9), left(T["object_identities"], 1), "1 : N")
|
||||||
|
# events.scene_background_id -> scene_backgrounds (soft, N:1 from events side)
|
||||||
|
edge(left(T["events"], 16), right(T["scene_backgrounds"], 1), "N : 1", dashed=True,
|
||||||
|
start="many", end="one")
|
||||||
|
|
||||||
|
# clip_detections.track_id -> clip_tracks (soft composite)
|
||||||
|
edge(top(T["clip_detections"]), bottom(T["clip_tracks"]), "N : 1", dashed=True,
|
||||||
|
start="many", end="one")
|
||||||
|
|
||||||
|
# object_identities FKs (N:1 to the reference tables)
|
||||||
|
edge(top(T["object_identities"]), bottom(T["known_objects"]), "N : 1", start="many", end="one")
|
||||||
|
edge(bottom(T["object_identities"]), top(T["tracked_objects"]), "N : 1", start="many", end="one")
|
||||||
|
edge(left(T["object_identities"], 8), right(T["clip_tracks"], 7), "N : 1", start="many", end="one")
|
||||||
|
|
||||||
|
# ---- table boxes -----------------------------------------------------------
|
||||||
|
def kind_color(kind):
|
||||||
|
return {"pk": "#1a1a2e", "fk": "#9a4d1f", "col": "#333"}[kind]
|
||||||
|
|
||||||
|
for name, t in tables.items():
|
||||||
|
h = table_height(t)
|
||||||
|
x, y, w = t["x"], t["y"], t["w"]
|
||||||
|
parts.append(f"<rect x='{x}' y='{y}' width='{w}' height='{h}' rx='8' fill='white' "
|
||||||
|
f"stroke='{t['accent']}' stroke-width='2'/>")
|
||||||
|
parts.append(f"<rect x='{x}' y='{y}' width='{w}' height='{HEADER_H}' rx='8' fill='{t['accent']}'/>")
|
||||||
|
parts.append(f"<rect x='{x}' y='{y+HEADER_H-8}' width='{w}' height='8' fill='{t['accent']}'/>")
|
||||||
|
parts.append(f"<text x='{x+PAD_X}' y='{y+19}' {FONT} font-size='14' font-weight='700' fill='white'>{name}</text>")
|
||||||
|
parts.append(f"<text x='{x+PAD_X}' y='{y+HEADER_H+11}' {FONT} font-size='9.5' fill='#888' font-style='italic'>{t['subtitle']}</text>")
|
||||||
|
cy = y + HEADER_H + 14
|
||||||
|
for i, (label, kind) in enumerate(t["cols"]):
|
||||||
|
ry = cy + ROW_H * i
|
||||||
|
if i % 2 == 1:
|
||||||
|
parts.append(f"<rect x='{x+1}' y='{ry}' width='{w-2}' height='{ROW_H}' fill='#f2f3f7'/>")
|
||||||
|
weight = "700" if kind == "pk" else "400"
|
||||||
|
prefix = "PK " if kind == "pk" else ("FK " if kind == "fk" else " ")
|
||||||
|
deco = " text-decoration='underline'" if kind == "pk" else ""
|
||||||
|
esc = label.replace("&", "&").replace("<", "<").replace(">", "→")
|
||||||
|
parts.append(f"<text x='{x+PAD_X}' y='{ry+12}' {FONT} font-size='10.5' "
|
||||||
|
f"fill='{kind_color(kind)}' font-weight='{weight}'{deco}>"
|
||||||
|
f"<tspan fill='#aa7' font-weight='700'>{prefix}</tspan>{esc}</text>")
|
||||||
|
|
||||||
|
# ---- legend ----------------------------------------------------------------
|
||||||
|
lx, ly = 70, 720
|
||||||
|
parts.append(f"<rect x='{lx}' y='{ly}' width='250' height='150' rx='8' fill='white' stroke='#ccc'/>")
|
||||||
|
parts.append(f"<text x='{lx+12}' y='{ly+22}' {FONT} font-size='13' font-weight='700' fill='#1a1a2e'>Legend</text>")
|
||||||
|
legend = [
|
||||||
|
("PK primary key (underlined)", "#1a1a2e"),
|
||||||
|
("FK foreign key → target", "#9a4d1f"),
|
||||||
|
("─── enforced FK constraint", "#444"),
|
||||||
|
("- - soft / logical link", "#444"),
|
||||||
|
("⊢ = 'one' ⟨ = 'many'", "#444"),
|
||||||
|
("embedding = CLIP ViT-B/32 512f", "#666"),
|
||||||
|
]
|
||||||
|
for i, (txt, c) in enumerate(legend):
|
||||||
|
parts.append(f"<text x='{lx+12}' y='{ly+44+i*18}' {FONT} font-size='10.5' fill='{c}'>{txt}</text>")
|
||||||
|
|
||||||
|
parts.append("</svg>")
|
||||||
|
|
||||||
|
with open("db_schema.svg", "w") as f:
|
||||||
|
f.write("\n".join(parts))
|
||||||
|
print("wrote db_schema.svg")
|
||||||
30
.trash/position_prompts.md
Normal file
30
.trash/position_prompts.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
token: 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
|
||||||
|
|
||||||
|
- front-facing portrait or frontal portrait.
|
||||||
|
- Head-on portrait: person faces directly toward the camera.
|
||||||
|
- Straight-on portrait: neutral, camera directly in front.
|
||||||
|
- Mugshot-style photo: front-facing, often neutral expression, but has a police/ID connotation.
|
||||||
|
- Passport photo or ID photo: front-facing with a plain background and strict framing.
|
||||||
|
- front-facing full-body portrait.
|
||||||
|
- Full-length portrait: shows the person from head to toe.
|
||||||
|
- Straight-on full-body shot: person faces the camera directly.
|
||||||
|
- Head-to-toe portrait: informal but clear.
|
||||||
|
- a straight-on full-body portrait.
|
||||||
|
|
||||||
|
Three-quarter view
|
||||||
|
Person is turned partly sideways, often about 45°, but still visible from the front. This is the normal portrait term.
|
||||||
|
|
||||||
|
Profile view
|
||||||
|
Person is fully sideways, seen from the side.
|
||||||
|
|
||||||
|
Frontal view / straight-on view
|
||||||
|
Person faces camera directly.
|
||||||
|
|
||||||
|
Isometric view
|
||||||
|
Mostly used for objects, architecture, games, diagrams: a 3D-looking view with equal axes/angles, not a normal human portrait pose.
|
||||||
|
|
||||||
|
- a full-body three-quarter portrait
|
||||||
|
- a straight-on full-body portrait in three-quarter view if the body is angled but the person still looks at the camera.
|
||||||
|
- Head-on a full-body three-quarter full-nude-body portrait transparent background
|
||||||
|
- Head-on straight-on full-nude-body portrait transparent background
|
||||||
|
- Head-on straight-on full-body portrait no background
|
||||||
198
a6000-comfy/install_junie_ollama_a6000.sh
Executable file
198
a6000-comfy/install_junie_ollama_a6000.sh
Executable file
@@ -0,0 +1,198 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PRIMARY_BASE="${PRIMARY_BASE:-qwen3-coder:30b}"
|
||||||
|
PRIMARY_NAME="${PRIMARY_NAME:-junie-qwen3-coder-30b-a6000}"
|
||||||
|
|
||||||
|
ALT_BASE="${ALT_BASE:-qwen2.5-coder:32b}"
|
||||||
|
ALT_NAME="${ALT_NAME:-junie-qwen25-coder-32b-a6000}"
|
||||||
|
|
||||||
|
FAST_BASE="${FAST_BASE:-qwen2.5-coder:7b}"
|
||||||
|
FAST_NAME="${FAST_NAME:-junie-qwen25-coder-7b-fast}"
|
||||||
|
|
||||||
|
PRIMARY_CTX="${PRIMARY_CTX:-65536}"
|
||||||
|
ALT_CTX="${ALT_CTX:-32768}"
|
||||||
|
FAST_CTX="${FAST_CTX:-16384}"
|
||||||
|
|
||||||
|
WORKDIR="${WORKDIR:-$HOME/ollama-junie-a6000}"
|
||||||
|
JUNIE_HOME="${JUNIE_HOME:-$HOME/.junie}"
|
||||||
|
JUNIE_PROFILE="${JUNIE_PROFILE:-local-ollama-a6000}"
|
||||||
|
|
||||||
|
mkdir -p "$WORKDIR" "$JUNIE_HOME/models"
|
||||||
|
|
||||||
|
echo "==> Checking Ollama"
|
||||||
|
if ! command -v ollama >/dev/null 2>&1; then
|
||||||
|
echo "==> Installing Ollama"
|
||||||
|
curl -fsSL https://ollama.com/install.sh | sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Configuring Ollama systemd for A6000 long-context use"
|
||||||
|
if systemctl list-unit-files | grep -q '^ollama\.service'; then
|
||||||
|
sudo mkdir -p /etc/systemd/system/ollama.service.d
|
||||||
|
sudo tee /etc/systemd/system/ollama.service.d/a6000.conf >/dev/null <<EOF
|
||||||
|
[Service]
|
||||||
|
Environment="OLLAMA_HOST=127.0.0.1:11434"
|
||||||
|
Environment="OLLAMA_FLASH_ATTENTION=1"
|
||||||
|
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
|
||||||
|
Environment="OLLAMA_KEEP_ALIVE=24h"
|
||||||
|
Environment="OLLAMA_NUM_PARALLEL=1"
|
||||||
|
Environment="OLLAMA_MAX_LOADED_MODELS=1"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable ollama >/dev/null
|
||||||
|
sudo systemctl restart ollama
|
||||||
|
else
|
||||||
|
echo "WARN: ollama.service niet gevonden. Start Ollama handmatig met:"
|
||||||
|
echo 'OLLAMA_HOST=127.0.0.1:11434 OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 OLLAMA_KEEP_ALIVE=24h ollama serve'
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Pulling base models"
|
||||||
|
ollama pull "$PRIMARY_BASE"
|
||||||
|
ollama pull "$ALT_BASE"
|
||||||
|
ollama pull "$FAST_BASE"
|
||||||
|
|
||||||
|
cat > "$WORKDIR/Modelfile.${PRIMARY_NAME}" <<EOF
|
||||||
|
FROM ${PRIMARY_BASE}
|
||||||
|
|
||||||
|
PARAMETER num_ctx ${PRIMARY_CTX}
|
||||||
|
PARAMETER num_predict 4096
|
||||||
|
PARAMETER temperature 0.3
|
||||||
|
PARAMETER top_p 0.9
|
||||||
|
PARAMETER repeat_penalty 1.05
|
||||||
|
|
||||||
|
SYSTEM """
|
||||||
|
You are a senior software-engineering coding agent inside a JetBrains/Junie workflow.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- Be precise, deterministic, and practical.
|
||||||
|
- Prefer small, safe, reviewable changes.
|
||||||
|
- Read surrounding code before proposing edits.
|
||||||
|
- Preserve existing architecture and style.
|
||||||
|
- For code changes, explain intent briefly and produce clean patches.
|
||||||
|
- Do not invent files, APIs, commands, or project structure.
|
||||||
|
- When uncertain, inspect first instead of guessing.
|
||||||
|
- Keep output concise unless a deeper design answer is needed.
|
||||||
|
"""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > "$WORKDIR/Modelfile.${ALT_NAME}" <<EOF
|
||||||
|
FROM ${ALT_BASE}
|
||||||
|
|
||||||
|
PARAMETER num_ctx ${ALT_CTX}
|
||||||
|
PARAMETER num_predict 4096
|
||||||
|
PARAMETER temperature 0.25
|
||||||
|
PARAMETER top_p 0.9
|
||||||
|
PARAMETER repeat_penalty 1.05
|
||||||
|
|
||||||
|
SYSTEM """
|
||||||
|
You are a senior coding assistant optimized for Java, Kotlin, Python, TypeScript, SQL, Linux, Docker, and architecture work.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- Give direct, technically correct answers.
|
||||||
|
- Prefer minimal diffs and commands that can be copied.
|
||||||
|
- Do not hallucinate APIs or project files.
|
||||||
|
- Ask only when blocked; otherwise make a reasonable local change plan.
|
||||||
|
"""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > "$WORKDIR/Modelfile.${FAST_NAME}" <<EOF
|
||||||
|
FROM ${FAST_BASE}
|
||||||
|
|
||||||
|
PARAMETER num_ctx ${FAST_CTX}
|
||||||
|
PARAMETER num_predict 2048
|
||||||
|
PARAMETER temperature 0.2
|
||||||
|
PARAMETER top_p 0.9
|
||||||
|
|
||||||
|
SYSTEM """
|
||||||
|
You are a fast helper model for summarizing, routing, and classifying coding context.
|
||||||
|
Be concise and preserve exact technical details.
|
||||||
|
"""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "==> Creating tuned Ollama models"
|
||||||
|
ollama create "$PRIMARY_NAME" -f "$WORKDIR/Modelfile.${PRIMARY_NAME}"
|
||||||
|
ollama create "$ALT_NAME" -f "$WORKDIR/Modelfile.${ALT_NAME}"
|
||||||
|
ollama create "$FAST_NAME" -f "$WORKDIR/Modelfile.${FAST_NAME}"
|
||||||
|
|
||||||
|
echo "==> Creating Junie CLI custom model profile"
|
||||||
|
cat > "$JUNIE_HOME/models/${JUNIE_PROFILE}.json" <<EOF
|
||||||
|
{
|
||||||
|
"id": "${PRIMARY_NAME}",
|
||||||
|
"baseUrl": "http://localhost:11434/v1/chat/completions",
|
||||||
|
"apiType": "OpenAICompletion",
|
||||||
|
"temperature": 0.3,
|
||||||
|
"extraHeaders": {
|
||||||
|
"X-Custom-Source": "Junie-Ollama-A6000"
|
||||||
|
},
|
||||||
|
"primaryModel": {
|
||||||
|
"id": "${PRIMARY_NAME}",
|
||||||
|
"temperature": 0.3
|
||||||
|
},
|
||||||
|
"fasterModel": {
|
||||||
|
"id": "${FAST_NAME}",
|
||||||
|
"temperature": 0.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "==> Setting Junie CLI default model profile"
|
||||||
|
if command -v python3 >/dev/null 2>&1; then
|
||||||
|
CONFIG="$JUNIE_HOME/config.json" python3 - <<'PY'
|
||||||
|
import json, os, pathlib, shutil
|
||||||
|
|
||||||
|
path = pathlib.Path(os.environ["CONFIG"])
|
||||||
|
profile = "local-ollama-a6000"
|
||||||
|
|
||||||
|
if path.exists():
|
||||||
|
backup = path.with_suffix(".json.bak")
|
||||||
|
shutil.copy2(path, backup)
|
||||||
|
try:
|
||||||
|
data = json.loads(path.read_text())
|
||||||
|
except Exception:
|
||||||
|
data = {}
|
||||||
|
else:
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
data["model"] = profile
|
||||||
|
data["model-default-locations"] = True
|
||||||
|
|
||||||
|
path.write_text(json.dumps(data, indent=2) + "\n")
|
||||||
|
PY
|
||||||
|
else
|
||||||
|
echo "WARN: python3 ontbreekt; zet handmatig in ~/.junie/config.json:"
|
||||||
|
echo '{ "model": "local-ollama-a6000", "model-default-locations": true }'
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Preloading primary model"
|
||||||
|
curl -s http://127.0.0.1:11434/api/generate \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"model\":\"${PRIMARY_NAME}\",\"prompt\":\"\",\"keep_alive\":-1}" >/dev/null || true
|
||||||
|
|
||||||
|
echo "==> Testing OpenAI-compatible endpoint"
|
||||||
|
curl -s http://127.0.0.1:11434/v1/chat/completions \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"model\": \"${PRIMARY_NAME}\",
|
||||||
|
\"messages\": [{\"role\":\"user\",\"content\":\"Return exactly: OK\"}],
|
||||||
|
\"stream\": false
|
||||||
|
}" | sed 's/,/,\n/g' | head -40
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Done."
|
||||||
|
echo
|
||||||
|
echo "Models:"
|
||||||
|
ollama list | grep -E "${PRIMARY_NAME}|${ALT_NAME}|${FAST_NAME}" || true
|
||||||
|
echo
|
||||||
|
echo "Check GPU load with:"
|
||||||
|
echo " ollama ps"
|
||||||
|
echo " watch -n 1 nvidia-smi"
|
||||||
|
echo
|
||||||
|
echo "Junie CLI:"
|
||||||
|
echo " cd /path/to/project"
|
||||||
|
echo " junie --model ${JUNIE_PROFILE}"
|
||||||
|
echo
|
||||||
|
echo "IntelliJ AI Assistant:"
|
||||||
|
echo " Settings > Tools > AI Assistant > Providers & API keys > Ollama"
|
||||||
|
echo " Host: http://localhost:11434"
|
||||||
|
echo " Model: ${PRIMARY_NAME}"
|
||||||
BIN
gfpgan/weights/detection_Resnet50_Final.pth
Normal file
BIN
gfpgan/weights/detection_Resnet50_Final.pth
Normal file
Binary file not shown.
59
position.md
59
position.md
@@ -1,59 +0,0 @@
|
|||||||
token: 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
|
|
||||||
how is a photo called where the person faces front, straight lookign into the camera
|
|
||||||
Een paar seconden nagedacht
|
|
||||||
|
|
||||||
That’s usually called a front-facing portrait or frontal portrait.
|
|
||||||
|
|
||||||
More specific terms:
|
|
||||||
|
|
||||||
Head-on portrait: person faces directly toward the camera.
|
|
||||||
Straight-on portrait: neutral, camera directly in front.
|
|
||||||
Mugshot-style photo: front-facing, often neutral expression, but has a police/ID connotation.
|
|
||||||
Passport photo or ID photo: front-facing with a plain background and strict framing.
|
|
||||||
|
|
||||||
For normal use, I’d say: a straight-on portrait.
|
|
||||||
|
|
||||||
and with full top till down
|
|
||||||
Een seconde nagedacht
|
|
||||||
|
|
||||||
That’s called a front-facing full-body portrait.
|
|
||||||
|
|
||||||
Also common:
|
|
||||||
|
|
||||||
Full-length portrait: shows the person from head to toe.
|
|
||||||
Straight-on full-body shot: person faces the camera directly.
|
|
||||||
Head-to-toe portrait: informal but clear.
|
|
||||||
|
|
||||||
Best phrase: a straight-on full-body portrait.
|
|
||||||
|
|
||||||
and when isotopic ( i think is the word) facing?
|
|
||||||
|
|
||||||
I think you mean either isometric or three-quarter view. I’ll pin down the naming so you can use the right prompt/photo term.
|
|
||||||
|
|
||||||
Nagedacht gedurende 4s
|
|
||||||
|
|
||||||
You probably mean isometric, but for a person/photo that is usually not the right word.
|
|
||||||
|
|
||||||
Use these terms:
|
|
||||||
|
|
||||||
Three-quarter view
|
|
||||||
Person is turned partly sideways, often about 45°, but still visible from the front. This is the normal portrait term.
|
|
||||||
|
|
||||||
Profile view
|
|
||||||
Person is fully sideways, seen from the side.
|
|
||||||
|
|
||||||
Frontal view / straight-on view
|
|
||||||
Person faces camera directly.
|
|
||||||
|
|
||||||
Isometric view
|
|
||||||
Mostly used for objects, architecture, games, diagrams: a 3D-looking view with equal axes/angles, not a normal human portrait pose.
|
|
||||||
|
|
||||||
For your case, say:
|
|
||||||
|
|
||||||
a full-body three-quarter portrait
|
|
||||||
or
|
|
||||||
a straight-on full-body portrait in three-quarter view if the body is angled but the person still looks at the camera.
|
|
||||||
|
|
||||||
Head-on a full-body three-quarter full-nude-body portrait transparent background
|
|
||||||
Head-on straight-on full-nude-body portrait transparent background
|
|
||||||
Head-on straight-on full-body portrait no background
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
# Qwen-Image-Edit Rapid-AIO v23 — headless edit API (tour / MI50)
|
|
||||||
|
|
||||||
Runs Phr00t's **Rapid-AIO NSFW v23** (the same tune as the gradio app) as a
|
|
||||||
**Q8 GGUF** on the AMD Instinct **MI50 32GB** (`tour`, gfx906, ROCm 5.7,
|
|
||||||
torch 2.3.1), served by ComfyUI behind a thin FastAPI throughput endpoint:
|
|
||||||
**image + prompt in → edited PNG out**.
|
|
||||||
|
|
||||||
## Layout on `tour`
|
|
||||||
```
|
|
||||||
/media/tour/APPS/comfyui/
|
|
||||||
venv/ torch 2.3.1+rocm5.7 + ComfyUI deps
|
|
||||||
ComfyUI/ backend + ComfyUI-GGUF custom node
|
|
||||||
models/unet/Qwen-Rapid-NSFW-v23_Q8_0.gguf (21.8 GB)
|
|
||||||
models/text_encoders/qwen_2.5_vl_7b_fp8_scaled.safetensors (9.4 GB)
|
|
||||||
models/vae/qwen_image_vae.safetensors (0.25 GB)
|
|
||||||
api/ edit_api.py + workflow + scripts
|
|
||||||
```
|
|
||||||
|
|
||||||
## Run
|
|
||||||
```bash
|
|
||||||
# 1) backend (terminal 1)
|
|
||||||
/media/tour/APPS/comfyui/api/run_comfyui.sh
|
|
||||||
# 2) API (terminal 2)
|
|
||||||
/media/tour/APPS/comfyui/api/start_api.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use
|
|
||||||
```bash
|
|
||||||
curl -s -X POST http://192.168.1.160:8500/edit \
|
|
||||||
-F image=@car.png \
|
|
||||||
-F 'prompt=put the car on a beach at sunset' \
|
|
||||||
-F seed=-1 -F steps=4 \
|
|
||||||
-o out.png
|
|
||||||
```
|
|
||||||
Form fields: `prompt` (required), `seed` (-1 = random), `steps` (4),
|
|
||||||
`cfg` (1.0), `sampler_name` (euler_ancestral), `scheduler` (beta),
|
|
||||||
`max_area` (px, 0 = server default ~1MP). Response headers expose
|
|
||||||
`X-Seed`, `X-Width`, `X-Height`.
|
|
||||||
|
|
||||||
Settings match Phr00t's v23 recommendation: **euler_ancestral / beta, 4 steps,
|
|
||||||
CFG 1**. Output size tracks the input aspect ratio, scaled to `MAX_AREA`.
|
|
||||||
|
|
||||||
## Performance (MI50, gfx906, 4 steps)
|
|
||||||
Compute-bound — the 20.8GB unet stays resident; only the text encoder swaps.
|
|
||||||
| Output budget | Latency |
|
|
||||||
|---------------|---------|
|
|
||||||
| 0.59 MP | ~110 s |
|
|
||||||
| 0.79 MP (default) | ~140 s |
|
|
||||||
| 1.0 MP | ~180 s |
|
|
||||||
|
|
||||||
## Gotchas (why it's built this way)
|
|
||||||
- **ComfyUI pinned to `v0.3.77`.** `master` imports `comfy_kitchen`, which needs
|
|
||||||
`torch.library.custom_op` (torch ≥ 2.4). gfx906/ROCm-5.7 tops out at the proven
|
|
||||||
`torch 2.3.1+rocm5.7`, so newer ComfyUI won't import. v0.3.77 is the newest tag
|
|
||||||
that still has `TextEncodeQwenImageEditPlus` without that dependency.
|
|
||||||
- **`--use-split-cross-attention`** (in `run_comfyui.sh`) is required: the default
|
|
||||||
pytorch attention path OOMs a 20B edit model on 32GB. Split attention chunks the
|
|
||||||
attention matmul so it fits.
|
|
||||||
- The audio custom-node import errors in the ComfyUI log (`libcudart.so.13`) are
|
|
||||||
harmless — a CUDA `torchaudio` got pulled in; image editing doesn't use it.
|
|
||||||
|
|
||||||
## Manage (local machine)
|
|
||||||
From this machine, use the `deploy_api.sh` script:
|
|
||||||
```bash
|
|
||||||
cd tour-comfy
|
|
||||||
./deploy_api.sh deploy tour # sync files and (re)start services
|
|
||||||
./deploy_api.sh stop tour # stop and disable services
|
|
||||||
./deploy_api.sh status tour # check service status and logs
|
|
||||||
```
|
|
||||||
|
|
||||||
## Manage (on `tour`)
|
|
||||||
```bash
|
|
||||||
sudo bash /media/tour/APPS/comfyui/api/deploy.sh # (re)install and start services
|
|
||||||
sudo bash /media/tour/APPS/comfyui/api/stop.sh # stop and disable services
|
|
||||||
```
|
|
||||||
|
|
||||||
### Logs
|
|
||||||
```bash
|
|
||||||
journalctl -u comfyui-backend -f
|
|
||||||
journalctl -u comfyui-api -f
|
|
||||||
```
|
|
||||||
@@ -9,6 +9,9 @@ realistic, transparent background
|
|||||||
1 female nude.
|
1 female nude.
|
||||||
realistic.
|
realistic.
|
||||||
|
|
||||||
|
# Feminine NO BG
|
||||||
|
1 female nude.
|
||||||
|
realistic, transparent background
|
||||||
|
|
||||||
# Upscale HQ Feminine
|
# Upscale HQ Feminine
|
||||||
high quality.
|
high quality.
|
||||||
|
|||||||
@@ -2034,3 +2034,39 @@ SyntaxError: broken PNG file (chunk b'END\xae')
|
|||||||
2026-06-19 23:45:09,379 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
2026-06-19 23:45:09,379 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
2026-06-19 23:45:09,379 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
2026-06-19 23:45:09,379 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
2026-06-19 23:45:09,379 - INFO - API URL: http://127.0.0.1:8500/edit
|
2026-06-19 23:45:09,379 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 03:36:11,495 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 03:36:11,495 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 03:36:11,495 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 03:46:05,968 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 03:46:05,968 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 03:46:05,968 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 04:34:43,767 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 04:34:43,767 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 04:34:43,767 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 05:23:14,220 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 05:23:14,220 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 05:23:14,220 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 05:47:31,635 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 05:47:31,635 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 05:47:31,635 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 15:24:51,866 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 15:24:51,866 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 15:24:51,866 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 15:42:57,259 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 15:42:57,259 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 15:42:57,259 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 16:14:06,428 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 16:14:06,428 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 16:14:06,428 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 16:17:07,087 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 16:17:07,088 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 16:17:07,088 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-20 16:20:59,203 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-20 16:20:59,204 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-20 16:20:59,204 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-21 00:11:13,229 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-21 00:11:13,229 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-21 00:11:13,229 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
2026-06-21 04:05:41,577 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
|
||||||
|
2026-06-21 04:05:41,578 - INFO - Output directory: /mnt/zim/tour-comfy/output
|
||||||
|
2026-06-21 04:05:41,578 - INFO - API URL: http://127.0.0.1:8500/edit
|
||||||
|
|||||||
Reference in New Issue
Block a user