Expose real train artifacts in dashboard
This commit is contained in:
@@ -169,6 +169,13 @@ type AcceptancePayload = {
|
||||
run_id?: string;
|
||||
created_at?: string;
|
||||
checks?: Array<{ name: string; passed: boolean }>;
|
||||
artifacts?: {
|
||||
train_root?: string;
|
||||
best_weight?: string | null;
|
||||
results_csv?: string | null;
|
||||
predict_outputs?: string[];
|
||||
heatmap_outputs?: string[];
|
||||
};
|
||||
model_family_readiness?: {
|
||||
passed: boolean;
|
||||
warnings: Array<{ name: string; passed: boolean }>;
|
||||
@@ -367,6 +374,11 @@ function formatBytes(value?: number) {
|
||||
return `${next.toFixed(unit > 1 ? 2 : 0)} ${units[unit]}`;
|
||||
}
|
||||
|
||||
function fileName(path?: string | null) {
|
||||
if (!path) return "";
|
||||
return path.split("/").filter(Boolean).pop() ?? path;
|
||||
}
|
||||
|
||||
function useData() {
|
||||
const [catalog, setCatalog] = useState<Catalog | null>(null);
|
||||
const [gpus, setGpus] = useState<GpuPayload | null>(null);
|
||||
@@ -1195,6 +1207,7 @@ function App() {
|
||||
<span>最近验收:{acceptance?.created_at ?? "尚未运行"} {acceptance?.run_id ? `#${acceptance.run_id}` : ""}</span>
|
||||
<span>真实数据:{realAcceptance?.created_at ?? "尚未运行"} {realAcceptance?.run_id ? `#${realAcceptance.run_id}` : ""},通过 {realAcceptance?.checks?.filter((item) => item.passed).length ?? 0}/{realAcceptance?.checks?.length ?? 0}</span>
|
||||
<span>真实短训:{realTrainAcceptance?.created_at ?? "尚未运行"} {realTrainAcceptance?.run_id ? `#${realTrainAcceptance.run_id}` : ""},通过 {realTrainAcceptance?.checks?.filter((item) => item.passed).length ?? 0}/{realTrainAcceptance?.checks?.length ?? 0}</span>
|
||||
<AcceptanceArtifactLinks artifacts={realTrainAcceptance?.artifacts} />
|
||||
<span>深度验收:{deepAcceptance?.created_at ?? "尚未运行"} {deepAcceptance?.run_id ? `#${deepAcceptance.run_id}` : ""},通过 {deepAcceptance?.checks?.filter((item) => item.passed).length ?? 0}/{deepAcceptance?.checks?.length ?? 0}</span>
|
||||
<span>模型族 readiness:{acceptance?.model_family_readiness?.checks?.filter((item) => item.passed).length ?? 0}/{acceptance?.model_family_readiness?.checks?.length ?? 0},warnings {acceptance?.model_family_readiness?.warnings?.length ?? 0}</span>
|
||||
</>
|
||||
@@ -1595,6 +1608,27 @@ function ResultBrowser({
|
||||
);
|
||||
}
|
||||
|
||||
function AcceptanceArtifactLinks({ artifacts }: { artifacts?: AcceptancePayload["artifacts"] }) {
|
||||
if (!artifacts) return null;
|
||||
const links = [
|
||||
artifacts.best_weight && { label: "best.pt", path: artifacts.best_weight, kind: "weight" },
|
||||
artifacts.results_csv && { label: "loss csv", path: artifacts.results_csv, kind: "curve" },
|
||||
...(artifacts.predict_outputs ?? []).slice(0, 2).map((path, index) => ({ label: `predict ${index + 1}`, path, kind: "segmentation" })),
|
||||
...(artifacts.heatmap_outputs ?? []).slice(0, 4).map((path, index) => ({ label: `heatmap ${index + 1}`, path, kind: "heatmap" }))
|
||||
].filter(Boolean) as Array<{ label: string; path: string; kind: string }>;
|
||||
if (!links.length) return null;
|
||||
return (
|
||||
<div className="acceptanceArtifacts">
|
||||
{links.map((item) => (
|
||||
<a key={`${item.label}-${item.path}`} href={`${API_BASE}/api/artifacts/${item.path}`} target="_blank" rel="noreferrer" title={item.path}>
|
||||
<span>{item.label}</span>
|
||||
<small>{item.kind} · {fileName(item.path)}</small>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function DatasetQuality({ validation }: { validation: DatasetValidation }) {
|
||||
return (
|
||||
<div className="qualityBox">
|
||||
|
||||
@@ -681,6 +681,31 @@ textarea {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.acceptanceArtifacts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.acceptanceArtifacts a {
|
||||
min-width: 0;
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
padding: 8px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--line);
|
||||
background: #101310;
|
||||
color: var(--ink);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.acceptanceArtifacts span,
|
||||
.acceptanceArtifacts small {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.taskCheckList {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user