diff --git a/.vscode/launch.json b/.vscode/launch.json index 0961acd46..1d151b1fe 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,15 +25,17 @@ //sys.path 会加入顶层目录,影响模块导入查询路径 "env": { "PYTHONPATH": "${workspaceFolder}" } }, - // 打包命令 + // 开发调试 { - "name": "构建项目", + "name": "开发调试", "type": "debugpy", "request": "launch", - "program": "${workspaceFolder}/build_pypi.py", + "program": "${workspaceFolder}/test/test_create_experiment.py", "console": "integratedTerminal", "justMyCode": true, - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder}", + //sys.path 会加入顶层目录,影响模块导入查询路径 + "env": { "PYTHONPATH": "${workspaceFolder}" } }, // 模拟实验开启 { @@ -69,6 +71,16 @@ "cwd": "${workspaceFolder}", //sys.path 会加入顶层目录,影响模块导入查询路径 "env": { "PYTHONPATH": "${workspaceFolder}" } + }, + // 打包命令 + { + "name": "构建项目", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/build_pypi.py", + "console": "integratedTerminal", + "justMyCode": true, + "cwd": "${workspaceFolder}" } ] } diff --git a/swanlab/__init__.py b/swanlab/__init__.py index b2bbe6a13..5b55d2425 100755 --- a/swanlab/__init__.py +++ b/swanlab/__init__.py @@ -6,6 +6,7 @@ config, Audio, Image, + Text, Run, ) diff --git a/swanlab/data/modules/__init__.py b/swanlab/data/modules/__init__.py index 63eb8a113..22f447eae 100644 --- a/swanlab/data/modules/__init__.py +++ b/swanlab/data/modules/__init__.py @@ -9,7 +9,8 @@ class FloatConvertible(Protocol): - def __float__(self) -> float: ... + def __float__(self) -> float: + ... DataType = Union[float, FloatConvertible, int, BaseType] diff --git a/swanlab/data/modules/text.py b/swanlab/data/modules/text.py index 9bac75bee..435effbf5 100644 --- a/swanlab/data/modules/text.py +++ b/swanlab/data/modules/text.py @@ -2,6 +2,7 @@ from .base import BaseType import os from typing import Union, List +from ..utils.file import get_text_sha256_hash class Text(BaseType): @@ -25,25 +26,29 @@ def get_data(self): # 如果传入的是Text类列表 if isinstance(self.value, list): return self.get_data_list() - else: - # 预处理文本数据 - self.__preprocess(self.value) - # 设置文本数据的保存路径 - save_dir = os.path.join(self.settings.static_dir, self.tag) - save_name = ( - f"{self.caption}-step{self.step}-{self.text_data[:16]}.txt" - if self.caption is not None - else f"text-step{self.step}-{self.text_data[:16]}.txt" - ) - # 如果路径不存在,则创建路径 - if not os.path.exists(save_dir): - os.mkdir(save_dir) - save_path = os.path.join(save_dir, save_name) - - # 保存文本数据写入到指定目录的指定json文件 - self.__save(save_path) - return save_name + # 预处理文本数据 + self.__preprocess(self.value) + + # 获取文本的hash值 + hash_name = get_text_sha256_hash(self.text_data)[:16] + + # 设置文本数据的保存路径 + save_dir = os.path.join(self.settings.static_dir, self.tag) + save_name = ( + f"{self.caption}-step{self.step}-{hash_name}.txt" + if self.caption is not None + else f"text-step{self.step}-{hash_name}.txt" + ) + + # 如果路径不存在,则创建路径 + if not os.path.exists(save_dir): + os.mkdir(save_dir) + save_path = os.path.join(save_dir, save_name) + + # 保存文本数据写入到指定目录的指定json文件 + self.__save(save_path) + return save_name def expect_types(self, *args, **kwargs) -> list: return ["str", "int", "float"] diff --git a/swanlab/data/utils/file.py b/swanlab/data/utils/file.py index 0903ddefd..1245a3d0a 100644 --- a/swanlab/data/utils/file.py +++ b/swanlab/data/utils/file.py @@ -109,3 +109,16 @@ def get_file_hash_pil(image) -> str: image.save(buffer, format="PNG") # 可以选择其他格式,如'JPEG' hash_sha256.update(buffer.getvalue()) return hash_sha256.hexdigest() + + +def get_text_sha256_hash(text): + """计算并返回给定文本的SHA-256哈希值。""" + import hashlib + + # 使用hashlib库创建一个sha256哈希对象 + hash_object = hashlib.sha256() + # 对输入的文本进行编码,因为hashlib需要的是字节对象 + hash_object.update(text.encode()) + # 获取十六进制格式的哈希值 + hex_dig = hash_object.hexdigest() + return hex_dig diff --git a/test/create_experiment.py b/test/create_experiment.py index f3c1f67b3..40dc2feaf 100644 --- a/test/create_experiment.py +++ b/test/create_experiment.py @@ -34,6 +34,7 @@ swanlab.log( { "test/image": swanlab.Image(test_image, caption="test"), + "test/text": swanlab.Text("hello swanlab!", caption="swanlab official"), }, step=epoch, ) diff --git a/vue/src/charts/components/ChartContainer.vue b/vue/src/charts/components/ChartContainer.vue index 56f86c1ce..ff59f4acd 100644 --- a/vue/src/charts/components/ChartContainer.vue +++ b/vue/src/charts/components/ChartContainer.vue @@ -38,6 +38,7 @@ import SLIcon from '@swanlab-vue/components/SLIcon.vue' import { addTaskToBrowserMainThread } from '@swanlab-vue/utils/browser' import LineChart from '../package/LineChart.vue' import AudioChart from '../package/AudioChart.vue' +import TextChart from '../package/TextChart.vue' import UnknownChart from '../package/UnknownChart.vue' import PannelButton from './PannelButton.vue' import { debounce } from '@swanlab-vue/utils/common' @@ -98,6 +99,11 @@ const chartComponent = computed(() => { type: ImageChart, class: 'image-chart' } + case 'text': + return { + type: TextChart, + class: 'text-chart' + } default: return { type: UnknownChart @@ -215,7 +221,8 @@ defineExpose({ // ---------------------------------- 图表样式 ---------------------------------- .audio-chart, -.image-chart { +.image-chart, +.text-chart { @apply col-span-3; } diff --git a/vue/src/charts/components/SlideBar.vue b/vue/src/charts/components/SlideBar.vue index da48a3b77..0cf27c358 100644 --- a/vue/src/charts/components/SlideBar.vue +++ b/vue/src/charts/components/SlideBar.vue @@ -7,14 +7,9 @@ -
{{ $t('common.chart.text-chart.titles.text') }}:
+
+ {{ text }}
+
+
{{ tag }}
+ +{{ title }}
+ ++ + {{ error }} +
+