From e670609f8ec128987061c956f787fa1f699d39b0 Mon Sep 17 00:00:00 2001 From: zcr Date: Mon, 13 Apr 2026 11:36:10 +0800 Subject: [PATCH] 1 --- docker-compose.yaml | 11 ++- server.py | 144 ++++++++++++++++++++-------------------- utils/new_oss_client.py | 9 +-- 3 files changed, 81 insertions(+), 83 deletions(-) mode change 100644 => 100755 docker-compose.yaml mode change 100644 => 100755 server.py mode change 100644 => 100755 utils/new_oss_client.py diff --git a/docker-compose.yaml b/docker-compose.yaml old mode 100644 new mode 100755 index 0a3f048..ac094a6 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,7 +1,7 @@ services: trellis: - image: zhouchengrong/fida-trellis:latest # 你 commit 的镜像 - container_name: trellis-dev + image: zhouchengrong/fida-trellis-a6000:latest # 你 commit 的镜像 + container_name: FiDA_3D_Trellis restart: unless-stopped environment: - NVIDIA_VISIBLE_DEVICES=all @@ -24,8 +24,5 @@ services: capabilities: [ gpu, compute, utility ] # 移除 video(非必需,减少兼容问题) command: > bash -c " - /opt/conda/envs/trellis/bin/python -c 'import torch; print(torch.__version__, torch.cuda.is_available())' && - /opt/conda/envs/trellis/bin/python server.py - " -# /opt/conda/envs/trellis/bin/python server.py -# tail -f /dev/null + conda run --no-capture-output -n trellis python server.py + " \ No newline at end of file diff --git a/server.py b/server.py old mode 100644 new mode 100755 index 03e79aa..ab20580 --- a/server.py +++ b/server.py @@ -144,11 +144,12 @@ class TrellisAPI(ls.LitAPI): def decode_request(self, request): image_paths = request["image_paths"] + bucket_name = request["bucket_name"] + user_id = request["user_id"] + images = [] for path in image_paths: - bucket = path.split('/')[0] - object_name = path[path.find('/') + 1:] - + bucket, object_name = path.split('/', 1) image = minio_get_image(minio_client, bucket, object_name) images.append(image) @@ -163,6 +164,8 @@ class TrellisAPI(ls.LitAPI): "simplify": request.get("simplify", 0.95), "texture_size": request.get("texture_size", 1024), "fps": request.get("fps", 30), + "bucket_name": bucket_name, + "user_id": user_id } return images, params @@ -202,8 +205,7 @@ class TrellisAPI(ls.LitAPI): glb_info = analyze_mesh(local_glb_path) - local_static_model_image_path = os.path.join("glb_output", generate_unique_name("static_model_image.png")) - static_model_image = self.get_static_model_image(model_path=local_glb_path, output_path=local_static_model_image_path) + static_model_image = self.get_static_model_image(model_path=local_glb_path, params=params) return { "glb_path": minio_glb_path, @@ -214,49 +216,49 @@ class TrellisAPI(ls.LitAPI): def encode_response(self, output): return output - def upload_video(self, outputs, params): - gaussian_name = f"3d_result/video/{params['file_name']}-gaussian.mp4" - radiance_field_name = f"3d_result/video/{params['file_name']}-radiance_field.mp4" - mesh_name = f"3d_result/video/{params['file_name']}-mesh.mp4" - - # gaussian video - video = render_utils.render_video(outputs["gaussian"][0])["color"] - buffer = BytesIO() - imageio.mimsave(buffer, video, format="mp4", fps=params['fps']) - gaussian_video_path = upload_bytes( - buffer.getvalue(), - gaussian_name, - "video/mp4", - ) - - # radiance field video - video = render_utils.render_video(outputs["radiance_field"][0])["color"] - buffer = BytesIO() - imageio.mimsave(buffer, video, format="mp4", fps=params['fps']) - radiance_field_video_path = upload_bytes( - buffer.getvalue(), - radiance_field_name, - "video/mp4", - ) - - # mesh video - video = render_utils.render_video(outputs["mesh"][0])["normal"] - buffer = BytesIO() - imageio.mimsave(buffer, video, format="mp4", fps=params['fps']) - mesh_path = upload_bytes( - buffer.getvalue(), - mesh_name, - "video/mp4", - ) - - return { - "gaussian": gaussian_video_path, - "radiance_field": radiance_field_video_path, - "mesh": mesh_path - } + # def upload_video(self, outputs, params): + # gaussian_name = f"3d_result/video/{params['file_name']}-gaussian.mp4" + # radiance_field_name = f"3d_result/video/{params['file_name']}-radiance_field.mp4" + # mesh_name = f"3d_result/video/{params['file_name']}-mesh.mp4" + # + # # gaussian video + # video = render_utils.render_video(outputs["gaussian"][0])["color"] + # buffer = BytesIO() + # imageio.mimsave(buffer, video, format="mp4", fps=params['fps']) + # gaussian_video_path = upload_bytes( + # buffer.getvalue(), + # gaussian_name, + # "video/mp4", + # ) + # + # # radiance field video + # video = render_utils.render_video(outputs["radiance_field"][0])["color"] + # buffer = BytesIO() + # imageio.mimsave(buffer, video, format="mp4", fps=params['fps']) + # radiance_field_video_path = upload_bytes( + # buffer.getvalue(), + # radiance_field_name, + # "video/mp4", + # ) + # + # # mesh video + # video = render_utils.render_video(outputs["mesh"][0])["normal"] + # buffer = BytesIO() + # imageio.mimsave(buffer, video, format="mp4", fps=params['fps']) + # mesh_path = upload_bytes( + # buffer.getvalue(), + # mesh_name, + # "video/mp4", + # ) + # + # return { + # "gaussian": gaussian_video_path, + # "radiance_field": radiance_field_video_path, + # "mesh": mesh_path + # } def upload_glb(self, outputs, params): - file_name = f"3d_result/glb/{params['file_name']}.glb" + minio_path = f"{params['bucket_name']}/{params['user_id']}/3d_result/{params['file_name']}.glb" local_glb_path = os.path.join("glb_output", generate_unique_name("sample.glb")) out_dir = os.path.dirname(local_glb_path) if out_dir: @@ -275,31 +277,28 @@ class TrellisAPI(ls.LitAPI): ) glb_path = upload_local_file( - local_glb_path, - file_name, - "application/octet-stream", + file_path=local_glb_path, + minio_path=minio_path, + content_type="application/octet-stream" ) return glb_path, local_glb_path - def upload_ply(self, outputs, params): - file_name = f"3d_result/ply/{params['file_name']}.ply" + # def upload_ply(self, outputs, params): + # file_name = f"3d_result/ply/{params['file_name']}.ply" + # + # with tempfile.NamedTemporaryFile(suffix=".ply") as tmp: + # outputs["gaussian"][0].save_ply(tmp.name) + # tmp.seek(0) + # + # ply_path = upload_bytes( + # tmp.read(), + # file_name, + # "application/octet-stream", + # ) + # return {"ply": ply_path} - with tempfile.NamedTemporaryFile(suffix=".ply") as tmp: - outputs["gaussian"][0].save_ply(tmp.name) - tmp.seek(0) - - ply_path = upload_bytes( - tmp.read(), - file_name, - "application/octet-stream", - ) - return {"ply": ply_path} - - def get_static_model_image(self, model_path, output_path): - local_static_model_image_path = os.path.join( - "glb_output", - generate_unique_name("static_model_image.png") - ) + def get_static_model_image(self, model_path, params): + local_static_model_image_path = os.path.join("glb_output", generate_unique_name("static_model_image.png")) print(f"model_path : {model_path}") print(f"local_static_model_image_path :{local_static_model_image_path}") @@ -307,17 +306,18 @@ class TrellisAPI(ls.LitAPI): static_model_image = self.upload_local_file( output_path, - "png" + params['bucket_name'], + params['user_id'], ) print(f"Saved to {static_model_image}") return static_model_image - def upload_local_file(self, local_path, type): + def upload_local_file(self, local_path, bucket_name, user_id): """ 通用上传函数:支持 SVG, PNG, OBJ 等 """ - object_name = f"3d_result/{type}/{uuid.uuid4().hex}.{type}" + object_name = f"{user_id}/3d_result/{uuid.uuid4().hex}.png" if not os.path.exists(local_path): print(f"错误: 文件 {local_path} 不存在") return None @@ -330,13 +330,13 @@ class TrellisAPI(ls.LitAPI): try: minio_client.fput_object( - bucket_name=MINIO_BUCKET, + bucket_name=bucket_name, object_name=object_name, file_path=local_path, content_type=content_type ) print(f"成功上传 [{content_type}]: {object_name}") - return f"{MINIO_BUCKET}/{object_name}" + return f"{bucket_name}/{object_name}" except Exception as e: print(f"上传失败: {e}") return None diff --git a/utils/new_oss_client.py b/utils/new_oss_client.py old mode 100644 new mode 100755 index 4817579..3da03a7 --- a/utils/new_oss_client.py +++ b/utils/new_oss_client.py @@ -76,7 +76,7 @@ def upload_bytes(data_bytes, object_name, content_type): return f"{MINIO_BUCKET}/{object_name}" -def upload_local_file(file_path, object_name, content_type="application/octet-stream"): +def upload_local_file(file_path, minio_path, content_type="application/octet-stream"): """ 将本地磁盘上的文件上传到 MinIO :param file_path: 本地文件路径 (如: 'output/sample.obj') @@ -88,14 +88,15 @@ def upload_local_file(file_path, object_name, content_type="application/octet-st raise FileNotFoundError(f"本地文件未找到: {file_path}") # 使用 fput_object 直接从磁盘流式上传,不占用过多内存 + bucket, object_name = minio_path.split('/', 1) + minio_client.fput_object( - bucket_name=MINIO_BUCKET, + bucket_name=bucket, object_name=object_name, file_path=file_path, content_type=content_type ) - - return f"{MINIO_BUCKET}/{object_name}" + return f"{bucket}/{object_name}" def download_from_minio(object_path, local_path):