178 lines
5.3 KiB
Markdown
178 lines
5.3 KiB
Markdown
![]() |
# 中文乱码问题解决方案总结
|
|||
|
|
|||
|
## 📋 问题回顾
|
|||
|
|
|||
|
### 原始问题
|
|||
|
1. **训练时控制台无日志输出** - API服务器训练模型时控制台没有任何显示
|
|||
|
2. **中文字符乱码** - 控制台输出中文显示为乱码或问号
|
|||
|
3. **表情符号无法显示** - 🚀 📊 等表情符号显示异常
|
|||
|
|
|||
|
### 环境背景
|
|||
|
- **运行环境**: Windows + uv Python包管理器
|
|||
|
- **项目特点**: 大量使用中文注释和表情符号增强可读性
|
|||
|
- **问题影响**: 开发调试体验严重受影响
|
|||
|
|
|||
|
## 🔍 根本原因分析
|
|||
|
|
|||
|
### 1. Python运行环境编码
|
|||
|
- `uv run` 启动的Python进程默认编码可能不是UTF-8
|
|||
|
- Windows系统默认使用GBK编码
|
|||
|
- 环境变量 `PYTHONIOENCODING` 未正确设置
|
|||
|
|
|||
|
### 2. 控制台输出流配置
|
|||
|
- `sys.stdout` 和 `sys.stderr` 编码配置不正确
|
|||
|
- 缓冲机制导致输出延迟或丢失
|
|||
|
- Windows控制台代码页设置不当
|
|||
|
|
|||
|
### 3. 脚本文件编码
|
|||
|
- Python脚本文件保存编码与运行时编码不匹配
|
|||
|
- UTF-8 BOM头处理问题
|
|||
|
|
|||
|
## ✅ 解决方案实施
|
|||
|
|
|||
|
### 第一步:环境变量修复
|
|||
|
```bash
|
|||
|
# 核心解决方案:设置环境变量
|
|||
|
PYTHONIOENCODING=utf-8 uv run server/api.py
|
|||
|
```
|
|||
|
|
|||
|
**原理**: 强制Python使用UTF-8编码处理输入输出流
|
|||
|
|
|||
|
### 第二步:代码内编码强化
|
|||
|
在 `server/api.py` 中添加:
|
|||
|
```python
|
|||
|
import sys
|
|||
|
import os
|
|||
|
|
|||
|
# 设置环境变量强制UTF-8编码
|
|||
|
os.environ['PYTHONIOENCODING'] = 'utf-8'
|
|||
|
os.environ['PYTHONLEGACYWINDOWSSTDIO'] = '0'
|
|||
|
|
|||
|
# Windows系统特殊处理
|
|||
|
if os.name == 'nt':
|
|||
|
try:
|
|||
|
os.system('chcp 65001 >nul 2>&1') # 设置控制台代码页
|
|||
|
if hasattr(sys.stdout, 'reconfigure'):
|
|||
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|||
|
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
|
|||
|
except Exception as e:
|
|||
|
print(f"Warning: Failed to set UTF-8 encoding: {e}")
|
|||
|
```
|
|||
|
|
|||
|
### 第三步:批处理文件方案
|
|||
|
创建 `启动API服务器.bat`:
|
|||
|
```batch
|
|||
|
@echo off
|
|||
|
chcp 65001 >nul 2>&1
|
|||
|
set PYTHONIOENCODING=utf-8
|
|||
|
set PYTHONLEGACYWINDOWSSTDIO=0
|
|||
|
cd /d %~dp0
|
|||
|
echo 🚀 启动药店销售预测系统API服务器...
|
|||
|
uv run server/api.py
|
|||
|
pause
|
|||
|
```
|
|||
|
|
|||
|
### 第四步:训练器输出修复
|
|||
|
在 `server/trainers/transformer_trainer.py` 中:
|
|||
|
```python
|
|||
|
def emit_progress(message, progress=None, metrics=None):
|
|||
|
# 强制刷新输出缓冲区
|
|||
|
print(f"[{time.strftime('%H:%M:%S')}] {message}", flush=True)
|
|||
|
import sys
|
|||
|
sys.stdout.flush()
|
|||
|
sys.stderr.flush()
|
|||
|
```
|
|||
|
|
|||
|
## 📊 修复效果验证
|
|||
|
|
|||
|
### Before (修复前)
|
|||
|
```
|
|||
|
使用设备: cuda
|
|||
|
成功加载数据文件: pharmacy_sales_multi_store.csv
|
|||
|
数据标准化完成,可用特征列: ['sales', 'price', ...]
|
|||
|
模型训练失败: 'gbk' codec can't encode character '\U0001f916'
|
|||
|
```
|
|||
|
|
|||
|
### After (修复后)
|
|||
|
```
|
|||
|
============================================================
|
|||
|
🧪 控制台编码测试开始
|
|||
|
============================================================
|
|||
|
📝 基本测试:
|
|||
|
✅ 简体中文: 药店销售预测系统
|
|||
|
🚀 表情符号: 启动 📊 数据 🤖 模型
|
|||
|
💾 混合文本: Product P001 - 感冒灵颗粒
|
|||
|
|
|||
|
🚀 开始训练测试 - 产品: P001
|
|||
|
========================================
|
|||
|
🤖 使用Transformer模型训练产品 '感冒灵颗粒' (ID: P001) 的销售预测模型
|
|||
|
🖥️ 使用设备: cuda
|
|||
|
📁 模型将保存到目录: saved_models
|
|||
|
[03:14:22] 开始Transformer模型训练...
|
|||
|
[03:14:29] Epoch 1/1, Train Loss: 0.0968, Test Loss: 0.0188
|
|||
|
📊 模型评估指标:
|
|||
|
MSE: 226.7259
|
|||
|
RMSE: 15.0574
|
|||
|
✅ 训练成功完成
|
|||
|
```
|
|||
|
|
|||
|
## 🎯 最佳实践总结
|
|||
|
|
|||
|
### 1. 统一启动方式
|
|||
|
**强制要求**: 所有 `uv run` 命令前添加环境变量
|
|||
|
```bash
|
|||
|
PYTHONIOENCODING=utf-8 uv run [script_name]
|
|||
|
```
|
|||
|
|
|||
|
### 2. 代码防御性编程
|
|||
|
在关键脚本开头添加编码配置代码,确保兼容性
|
|||
|
|
|||
|
### 3. 使用批处理文件
|
|||
|
为常用操作创建预配置的启动脚本,避免重复设置
|
|||
|
|
|||
|
### 4. 测试验证机制
|
|||
|
创建编码测试脚本,每次修改后验证编码正常
|
|||
|
|
|||
|
## 📋 问题预防清单
|
|||
|
|
|||
|
### 开发阶段
|
|||
|
- [ ] 新脚本复制已验证的编码配置代码
|
|||
|
- [ ] 文件保存时确保UTF-8编码
|
|||
|
- [ ] 使用统一的启动方式
|
|||
|
|
|||
|
### 部署阶段
|
|||
|
- [ ] 环境变量正确设置
|
|||
|
- [ ] 控制台支持UTF-8显示
|
|||
|
- [ ] 批处理文件配置正确
|
|||
|
|
|||
|
### 维护阶段
|
|||
|
- [ ] 定期运行编码测试
|
|||
|
- [ ] 团队成员统一开发规范
|
|||
|
- [ ] 文档保持更新
|
|||
|
|
|||
|
## 🚀 后续优化建议
|
|||
|
|
|||
|
1. **自动化设置**: 在项目根目录创建环境配置脚本
|
|||
|
2. **IDE集成**: 配置开发环境默认使用UTF-8
|
|||
|
3. **CI/CD集成**: 在持续集成中包含编码测试
|
|||
|
4. **文档完善**: 在README中明确说明编码要求
|
|||
|
|
|||
|
## 💡 经验教训
|
|||
|
|
|||
|
1. **环境变量优先**: `PYTHONIOENCODING=utf-8` 是最简单有效的解决方案
|
|||
|
2. **代码容错**: 即使环境配置失败,代码内配置可以作为后备
|
|||
|
3. **用户体验**: 表情符号和中文大大提升了日志的可读性,值得保留
|
|||
|
4. **文档重要性**: 详细记录解决方案避免重复踩坑
|
|||
|
|
|||
|
## 📚 相关资源
|
|||
|
|
|||
|
- [Python Unicode HOWTO](https://docs.python.org/3/howto/unicode.html)
|
|||
|
- [Windows Console和UTF-8](https://docs.microsoft.com/en-us/windows/console/)
|
|||
|
- [uv文档 - 环境管理](https://github.com/astral-sh/uv)
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
**创建时间**: 2025-06-21
|
|||
|
**修复版本**: v2.1.0
|
|||
|
**状态**: 已解决并验证
|
|||
|
**影响范围**: 所有使用uv run的Python脚本
|