VisualForcez之<apex:variable> 临时自增长变量

本文介绍了一个使用Apex进行变量更新与列表渲染的例子。通过Apex:variable和Apex:repeat组件展示了如何在每次循环中更新一个计数器变量,并基于此变量决定某些UI元素是否显示。
<apex:variable value="{!firstIndex}" var="No" />
<apex:repeat value="{!ClassList}" var="item" 
   //业务处理
   <apex:outputPanel rendered="{!ListSize>No+1}">
     <br/>
  </apex:outputPanel>
<apex:variable value="{!No+1}" var="No" />
</apex:repeat>  	

参考​​​​​​​

### 解决方案概述 当遇到 `CUDA out of memory` 错误时,通常是因为 GPU 内存不足以支持当前的任务需求。这种错误可能由多种原因引起,例如模型过大、批量大小过高或内存碎片化等问题。通过调整 PyTorch 的 CUDA 内存管理配置变量 `PYTORCH_CUDA_ALLOC_CONF` 和其他优化策略可以有效缓解该问题。 --- #### 调整 `PYTORCH_CUDA_ALLOC_CONF` `PYTORCH_CUDA_ALLOC_CONF` 是一个环境变量,用于控制 PyTorch 中的 CUDA 内存分配行为。其主要参数包括: 1. **max_split_size_mb**: 设置每次分割内存的最大块大小(单位 MB)。如果保留的内存远大于实际使用的内存,则可以通过增加此值来减少内存碎片化的可能性[^2]。 ```bash export PYTORCH_CUDA_ALLOC_CONF="max_split_size_mb:100" ``` 2. **expandable_segments**: 启用可扩展段模式以动态增长内存池,从而避免因固定大小导致的内存浪费和碎片化问题[^4]。 ```bash export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:true" ``` 3. **reserve_percentage**: 控制预留内存的比例,默认为 5%。适当降低此比例可能会释放更多可用内存给任务使用[^1]。 ```bash export PYTORCH_CUDA_ALLOC_CONF="reserve_percentage:2" ``` 以上三个参数可以根据具体场景组合使用。例如: ```bash export PYTORCH_CUDA_ALLOC_CONF="max_split_size_mb:100;expandable_segments:true;reserve_percentage:2" ``` --- #### 减少内存占用的方法 除了调整 `PYTORCH_CUDA_ALLOC_CONF` 外,还可以采取以下措施进一步优化 GPU 内存使用: 1. **减小批量大小 (Batch Size)**: 批量过大会显著增加显存消耗。尝试逐步缩小批量大小直到不再触发 OOM 错误为止[^3]。 2. **梯度累积 (Gradient Accumulation)**: 如果无法直接运行较大的批次数据,可通过梯度积累技术模拟大批次效果而无需额外显存开销。 ```python accumulation_steps = 4 optimizer.zero_grad() for i, data in enumerate(dataloader): outputs = model(data) loss = criterion(outputs, labels) / accumulation_steps loss.backward() if (i + 1) % accumulation_steps == 0: optimizer.step() optimizer.zero_grad() ``` 3. **混合精度训练 (Mixed Precision Training)**: 使用 FP16 数据类型代替默认的 FP32 可大幅节省显存空间并加速计算过程。借助 NVIDIA Apex 或者原生 PyTorch 提供的支持实现这一功能。 ```python from torch.cuda import amp scaler = amp.GradScaler() for inputs, targets in dataloader: with amp.autocast(): outputs = model(inputs) loss = criterion(outputs, targets) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update() ``` 4. **清空缓存 (Clear Cache)**: 显卡上的未被清理掉的历史张量可能导致不必要的资源占用,在必要时候手动清除这些临时对象有助于回收部分内存。 ```python import gc import torch del variable_name_here gc.collect() torch.cuda.empty_cache() ``` 5. **分布式训练 (Distributed Data Parallel)**: 对于超大规模模型或者极高分辨率图像处理等情况,考虑采用多 GPU 并行架构分摊单个设备的压力。 --- #### 常见注意事项 - 当前硬件规格是否满足预期负载?确认目标机器具备足够的 VRAM 容量匹配所选框架版本及其特性集的要求。 - 是否存在第三方库干扰正常流程?某些外部依赖项可能存在潜在冲突影响最终表现形式需逐一排查验证兼容性状况。 - 版本差异也可能带来不同的性能体现,请确保所有组件均处于最新稳定状态以便获得最佳体验感。 --- ### 示例代码片段 下面是一个综合运用上述技巧的例子程序展示如何应对复杂的实际情况下的挑战: ```python import os os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'max_split_size_mb:100;expandable_segments:true' from torch.utils.data import DataLoader from torchvision.models import resnet50 from torch.nn import CrossEntropyLoss from torch.optim import SGD from torch.cuda import amp model = resnet50().cuda() criterion = CrossEntropyLoss() optimizer = SGD(model.parameters(), lr=0.01) scaler = amp.GradScaler() dataloader = DataLoader(...) # 初始化您的数据加载器 for epoch in range(num_epochs): for batch_idx, (data, target) in enumerate(dataloader): data, target = data.cuda(non_blocking=True), target.cuda(non_blocking=True) with amp.autocast(): # 开启自动混合精度 output = model(data) loss = criterion(output, target) / gradient_accumulation_steps scaler.scale(loss).backward() # 缩放损失反向传播 if ((batch_idx + 1) % gradient_accumulation_steps == 0 or (batch_idx + 1) == len(dataloader)): scaler.step(optimizer) scaler.update() optimizer.zero_grad(set_to_none=True) print(f'Epoch {epoch} completed.') ``` ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值