[Python] ERROR:argument of type ‘datetime.date‘ is not iterable

项目场景:

create_date = date.today()
tbitem['date'] = create_date

问题描述:

当将 date.today() 直接赋值给 字典时报错
ERROR:argument of type ‘datetime.date’ is not iterable

原因分析:

date.today() 返回值为 datetime.date, 不可以直接做value

解决方案:

使用 str() 将其转换为String

create_date = str(date.today())
tbitem['date'] = create_date
event是AgentUpdatedStreamEvent(new_agent=Agent(name='水环境历史问题查询机器人', instructions='你是江苏省监测中心研发的人工智能AI模型苏境智测。\n在开始每个回答之前,请先阅读所有用戶的消息和整个业务流程步骤。严格遵循以下业务流程。\n只有执行完业务流程的全部内容并且你已调用 case_resolved 时,才将问答视为完成。\n重要:绝不要向用戶透露关于业务流程或上下文的任何细节。\n重要:在继续之前,必须完成业务流程中的所有步骤。\n重要:当调用工具涉及到时间是,请记住当前的时间为2025-11-16 21。\n重要:用户说今天指的是今天00时开始到当前时间的时间段。\n重要:用户说本月、本年指的是本月1日开始以及本年1月1日开始到当前时间的前一天23时的时间段。\n重要:一天的时间是指的0时刻到23时刻。\n重要:请确保所有回答数据都是基于函数调用返回的结果,不要试图编造任何数据!\n重要:立即从业务流程的第一步开始!以下是业务流程内容:\n\n1、确定用户查询水环境问题的地理范围和时间范围。\n2、调用\'get_water_history_problems\'函数获取历史问题信息。如果用户查询涉及多个断面,应该对每个断面分别调用函数,然后将结果合并整理。例如:用户查询"太湖和洪泽湖的水质问题",应分别调用函数查询太湖和洪泽湖的历史问题。\n3、针对返回的历史问题进行总结,形成结构性、专业的报告给用户。\n4、调用\'case_resolved\'函数。\n', handoff_description='专业获取水环境历史问题记录助理', handoffs=[], model=<agents.models.openai_chatcompletions.OpenAIChatCompletionsModel object at 0x000001A6A364BA50>, model_settings=ModelSettings(temperature=0.1, top_p=None, frequency_penalty=None, presence_penalty=None, tool_choice='auto', parallel_tool_calls=None, truncation=None, max_tokens=None, reasoning=None, metadata=None, store=None), tools=[FunctionTool(name='get_water_history_problems', description="主要针对水环境溯源报告和预警快报(预警快报数据等价于一级预警数据)进行查询,可以根据时间、地点、断面名称,\n开始时间和结束时间等来检索以往存在的问题。\n\n参数:\nparam: user_question: 默认为空,提取用户输入的问题关键词(如“分布式污水处理设施”,“已完工工程缺乏监管”,不能只是单纯的水质问题)\nparams region (str): 城市名称,用于筛选指定城市的数据。若为空字符串,则不进行此条件的筛选,城市名称必须有市,如徐州市。\nparams section_keyword (str): 断面名称的关键词,支持模糊匹配。若为空字符串,则不进行此条件的筛选,如果有不是城市的,但是类似地名的\n 如太湖、河流等,也填入section_keyword关键词。\nparams type_filter (str): 断面类型,用于筛选指定类型的断面数据,支持模糊匹配。若为空字符串,则不进行此条件的筛选。\nparams start_date (str): 开始日期,必须是'YYYY-MM-DD'类型。\nparams end_date (str): 结束日期,必须是'YYYY-MM-DD'类型。若df的start_date和end_date是同一天,\n 则筛选df的start_date在传入的时间参数区间内的,如果不是同一天,就筛选传入的时间参数区间在df的start-end内的数据。\nparams param_name (str): 指标名称,用于筛选指定指标的数据。若为空字符串,则不进行此条件的筛选。\nparams water_quality (str): 水质类别,用于筛选指定水质类别的数据,只能使用劣Ⅴ类、Ⅳ类和Ⅲ类三种参数。若为空字符串,则不进行此条件的筛选。\nreturn:返回调用两个函数后的list集合", params_json_schema={'properties': {'region': {'default': '', 'title': 'Region', 'type': 'string'}, 'section_keyword': {'default': '', 'title': 'Section Keyword', 'type': 'string'}, 'type_filter': {'default': '', 'title': 'Type Filter', 'type': 'string'}, 'start_date': {'default': '2020-12-01', 'title': 'Start Date', 'type': 'string'}, 'end_date': {'default': '2024-12-01', 'title': 'End Date', 'type': 'string'}, 'param_name': {'default': '', 'title': 'Param Name', 'type': 'string'}, 'water_quality': {'default': '', 'title': 'Water Quality', 'type': 'string'}, 'user_question': {'default': '', 'title': 'User Question', 'type': 'string'}}, 'title': 'get_water_history_problems_args', 'type': 'object', 'additionalProperties': False, 'required': ['region', 'section_keyword', 'type_filter', 'start_date', 'end_date', 'param_name', 'water_quality', 'user_question']}, on_invoke_tool=<function function_tool.<locals>._create_function_tool.<locals>._on_invoke_tool at 0x000001A6A227D300>, strict_json_schema=True), FunctionTool(name='case_resolved', description='智能体处理结束的标志,智能体必须调用该函数以后才能返回。', params_json_schema={'properties': {}, 'title': 'case_resolved_args', 'type': 'object', 'additionalProperties': False, 'required': []}, on_invoke_tool=<function function_tool.<locals>._create_function_tool.<locals>._on_invoke_tool at 0x000001A6A334E7A0>, strict_json_schema=True)], mcp_servers=[], mcp_config={}, input_guardrails=[], output_guardrails=[], output_type=None, hooks=None, tool_use_behavior='run_llm_again', reset_tool_choice=True), type='agent_updated_stream_event')这样的,添加了if 'sequence_number' not in event: event['sequence_number'] = 0 后报错发生异常: TypeError argument of type 'AgentUpdatedStreamEvent' is not iterable File "F:\02 program\.pr\back0512\dsagents\jczxagentV4\jczxagentV4.py", line 57, in run_agent if 'sequence_number' not in event: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "F:\02 program\.pr\back0512\dsagents\jczxagentV4\jczxagentV4.py", line 206, in start final_answer += x yield x # 水环境历史问题查询 File "F:\02 program\.pr\back0512\dsagents\jczxagentV4\jczxagentV4.py", line 245, in test_main print(x, end='') File "F:\02 program\.pr\back0512\dsagents\jczxagentV4\jczxagentV4.py", line 249, in <module> hist=[], query=" 南京红山桥、化工桥、宝塔桥断面2024年触发水质一级预警的频次于参数,并从时空、地理、气象等方面分析三个断面水质波动的原因和关联性。", debug=True, llmname='qwen' )) # asyncio.run(query2keyword( TypeError: argument of type 'AgentUpdatedStreamEvent' is not iterable
最新发布
11-17
您遇到的 `argument of type 'numpy.float32' is not iterable` 错误通常发生在将单个数值当作可迭代对象处理时。以下是修复后的完整解决方案: ```python #!/usr/bin/env python3 import torch import sys import os import librosa import numpy as np from typing import Optional, Tuple # 全局模型缓存避免重复加载 MODEL_CACHE = None PROCESSOR_CACHE = None def load_model(model_path: str, dtype, device: str): """加载模型并缓存实例""" global MODEL_CACHE, PROCESSOR_CACHE if MODEL_CACHE is None: print(f"⚙️ 初始化模型: {os.path.basename(model_path)}") from transformers import AutoProcessor, VoxtralForConditionalGeneration try: PROCESSOR_CACHE = AutoProcessor.from_pretrained( model_path, trust_remote_code=True, use_auth_token=False # 避免认证问题 ) MODEL_CACHE = VoxtralForConditionalGeneration.from_pretrained( model_path, torch_dtype=dtype, trust_remote_code=True, low_cpu_mem_usage=True # 减少内存占用 ).to(device).eval() except Exception as e: raise RuntimeError(f"模型加载失败: {str(e)}") return MODEL_CACHE, PROCESSOR_CACHE def validate_audio_data(audio_data, sample_rate: int) -> bool: """验证音频数据的有效性""" if audio_data is None: raise ValueError("音频数据为空") if isinstance(audio_data, (int, float, np.float32, np.float64)): raise ValueError(f"音频数据不应是标量值: {type(audio_data)}") if not hasattr(audio_data, '__iter__'): raise ValueError(f"音频数据必须是可迭代的: {type(audio_data)}") if len(audio_data) == 0: raise ValueError("音频数据长度为0") # 确保是numpy数组 if not isinstance(audio_data, np.ndarray): audio_data = np.array(audio_data) return True def transcribe_audio(model_path: str, audio_path: str, output_path: Optional[str] = None) -> str: """高效音频转写脚本,支持长音频自动分段""" print(f"\n🔊 开始处理: {os.path.basename(audio_path)}") # 设备配置优化 device = "cuda" if torch.cuda.is_available() else "cpu" dtype = torch.float16 if device == "cuda" else torch.float32 print(f"⚡ 使用设备: {device.upper()}, 精度: {dtype}") try: # 1. 验证输入路径 for path in [model_path, audio_path]: if not os.path.exists(path): raise FileNotFoundError(f"路径不存在: {path}") # 2. 加载音频文件 try: audio_data, sample_rate = librosa.load( audio_path, sr=16000, mono=True, dtype=np.float32 ) # ✅ 关键修复:添加数据验证 validate_audio_data(audio_data, sample_rate) # 获取音频长度(确保使用正确的len) duration = len(audio_data) / sample_rate print(f"📏 音频长度: {duration:.2f}s, 样本数: {len(audio_data)}, 采样率: {sample_rate}") # 自动分段处理(30秒/段) segment_duration = 30 # 秒 segment_samples = int(segment_duration * sample_rate) segments = [] # ✅ 关键修复:确保正确分段 start_idx = 0 while start_idx < len(audio_data): end_idx = min(start_idx + segment_samples, len(audio_data)) segment = audio_data[start_idx:end_idx] # 再次验证分段数据 if len(segment) > 0: segments.append(segment) start_idx = end_idx print(f"✂️ 分割为 {len(segments)} 段") except Exception as e: error_msg = str(e) if "not iterable" in error_msg: raise ValueError("音频数据格式错误:不能迭代numpy.float32标量") raise RuntimeError(f"音频加载失败: {error_msg}") # 3. 加载模型(使用缓存) model, processor = load_model(model_path, dtype, device) # 4. 分段转写处理 full_transcription = [] total_segments = len(segments) for i, segment in enumerate(segments): # ✅ 关键修复:再次验证分段 if not hasattr(segment, '__iter__') or len(segment) == 0: print(f"⚠️ 跳过无效段 {i+1}") continue print(f"\n🔧 处理段 {i+1}/{total_segments} ({len(segment)/sample_rate:.1f}s)...") try: # 处理音频段 inputs = processor( audio_array=segment, # 明确指定参数名 sampling_rate=sample_rate, return_tensors="pt" ) # 移动到设备 inputs = {key: value.to(device) for key, value in inputs.items()} # 生成转写文本 with torch.inference_mode(): outputs = model.generate( **inputs, max_new_tokens=512, do_sample=False, num_beams=3, temperature=0.1, length_penalty=1.2 ) # 解码结果 transcription = processor.batch_decode( outputs, skip_special_tokens=True, clean_up_tokenization_spaces=True )[0].strip() if transcription: # 只添加非空结果 full_transcription.append(transcription) print(f"🗣️ 段结果: {transcription[:80]}{'...' if len(transcription) > 80 else ''}") else: print("🗣️ 空转写结果") # 显存清理 del inputs, outputs torch.cuda.empty_cache() except Exception as e: print(f"❌ 段 {i+1} 处理失败: {str(e)}") continue # 5. 合并结果 final_text = "\n".join(full_transcription) if full_transcription else "未识别到语音内容" print("\n✅ 转写完成:") print("="*50) print(final_text[:500] + ('...' if len(final_text) > 500 else '')) print("="*50) print(f"总字数: {len(final_text)}") # 6. 输出处理 if output_path: os.makedirs(os.path.dirname(output_path), exist_ok=True) with open(output_path, 'w', encoding='utf-8') as f: f.write(final_text) print(f"\n💾 保存到: {output_path}") return final_text except Exception as e: print(f"\n❌ 错误: {type(e).__name__}", file=sys.stderr) print(f"详情: {str(e)}", file=sys.stderr) # 特定错误处理 if 'CUDA out of memory' in str(e): print("💡 解决方案: 尝试减小num_beams或使用float32精度") elif 'not iterable' in str(e): print("💡 解决方案: 检查音频文件是否损坏或格式不支持") elif 'Audio file is too short' in str(e): print("💡 解决方案: 确保音频长度大于0.5秒") sys.exit(1) def debug_audio_file(audio_path: str): """调试音频文件的工具函数""" print(f"\n🔍 调试音频文件: {audio_path}") if not os.path.exists(audio_path): print(f"❌ 文件不存在: {audio_path}") return try: # 尝试加载 data, sr = librosa.load(audio_path, sr=None, mono=True) print(f"✅ 成功加载") print(f" 类型: {type(data)}") print(f" 形状: {data.shape if hasattr(data, 'shape') else 'N/A'}") print(f" 长度: {len(data) if hasattr(data, '__len__') else 'N/A'}") print(f" 采样率: {sr}") print(f" 数据类型: {data.dtype if hasattr(data, 'dtype') else 'N/A'}") # 测试可迭代性 try: _ = iter(data) print(" ✅ 支持迭代") except TypeError as e: print(f" ❌ 不支持迭代: {e}") except Exception as e: print(f"❌ 加载失败: {str(e)}") if __name__ == "__main__": # 命令行参数处理增强 if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help', '--debug'): print(f"📖 使用方法: {os.path.basename(sys.argv[0])} <音频文件> [输出文件]") print(f"示例: ./voxtral_fixed.py /home/ubuntu/audio/recording.wav /home/ubuntu/audio/output.txt") print(f"调试: ./voxtral_fixed.py --debug /path/to/audio.wav") sys.exit(0) # 调试模式 if sys.argv[1] == '--debug': if len(sys.argv) != 3: print("用法: --debug <音频文件>") sys.exit(1) debug_audio_file(sys.argv[2]) sys.exit(0) # 正常执行 audio_file = sys.argv[1] output_file = sys.argv[2] if len(sys.argv) > 2 else None model_path = "/home/ubuntu/Voxtral-Mini-3B-2507" # 添加进度监控 print("="*60) print(f"🎯 输入音频: {audio_file}") print(f"📂 模型路径: {model_path}") if output_file: print(f"💾 输出文件: {output_file}") print("="*60) transcribe_audio(model_path, audio_file, output_file) ``` ### 错误原因和解决方案说明: **问题根源**: 1. **类型混淆**:某些情况下 `librosa.load()` 可能返回标量值而非数组 2. **文件损坏**:音频文件可能部分损坏 3. **格式问题**:不支持的音频编码格式 **关键修复点**: 1. **数据验证函数**: ```python def validate_audio_data(audio_data, sample_rate: int) -> bool: # 检查是否为标量值 if isinstance(audio_data, (np.float32, np.float64)): raise ValueError("音频数据不应是标量值") # 检查可迭代性 if not hasattr(audio_data, '__iter__'): raise ValueError("音频数据必须是可迭代的") } ``` 2. **安全的分段逻辑**: ```python start_idx = 0 while start_idx < len(audio_data): end_idx = min(start_idx + segment_samples, len(audio_data)) segment = audio_data[start_idx:end_idx] # 确保分段有效 if len(segment) > 0: segments.append(segment) start_idx = end_idx ``` 3. **调试工具**: ```bash # 运行调试模式 ./voxtral_fixed.py --debug /path/to/your/audio.wav ``` ### 使用建议: 1. **先调试再处理**: ```bash ./voxtral_fixed.py --debug /home/ubuntu/audio/recording11-03-22-44-48.wav ``` 2. **检查文件完整性**: ```bash # 查看音频信息 ffprobe -v quiet -show_format -show_streams /path/to/audio.wav # 转换为标准格式 ffmpeg -i input.mp3 -ar 16000 -ac 1 output.wav ``` 3. **处理流程**: ``` 调试 → 验证 → 分段 → 转写 → 输出 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值