Giter Site home page Giter Site logo

Comments (20)

wangning08115 avatar wangning08115 commented on September 27, 2024 1

又经过几轮测试, 发现和 自己电脑内存大小有关, 我找个8GB电脑, 那么内存上到3GB,无任务时候,内存就下来到了600MB;
我本机32GB内存, 因此内存占用上去后4-5GB, 无任务时候完全无法下降到1GB内。

也就是 电脑内存大,他就不回收了,电脑内存小 他无任务时候就回收了。

from paddlesharp.

wangning08115 avatar wangning08115 commented on September 27, 2024 1

内存不足的时候,无任务,内存能下降到500MB内

image

from paddlesharp.

sdcb avatar sdcb commented on September 27, 2024

看看你的代码是怎么写的?这个数字出乎我的意料,怀疑是使用方式有区别

from paddlesharp.

wangning08115 avatar wangning08115 commented on September 27, 2024

还有更出乎预料的: 内存达到了5GB, 运行不到2天。

image

代码:
` try
{
//string result = "";
string image_path = parameter.Image;
FileInfo fileInfo = new FileInfo(image_path);
string imageFolder = fileInfo.DirectoryName;
Bitmap inputBitmap = (Bitmap)Bitmap.FromFile(parameter.Image);
image_path = $"{imageFolder}\{fileInfo.Name.Md5()}-standard-format.jpg";
inputBitmap.Save(image_path, System.Drawing.Imaging.ImageFormat.Jpeg);
inputBitmap.Dispose();
TraceLog.Common.Debug($"OcrText 图像转换 {image_path}");
TraceLog.Common.Debug($"OcrText PaddlexOcrApi.Rec Start");
FullOcrModel model = null;
if (ModelTypes.EqualsTo("ChineseV3")) model = LocalFullModels.ChineseV3;
else model = LocalFullModels.EnglishV3;

                PaddleOcrResult tempResult = null;
                using (PaddleOcrAll all = new PaddleOcrAll(model)
                {
                    AllowRotateDetection = true, /* 允许识别有角度的文字 */
                    Enable180Classification = false, /* 允许识别旋转角度大于90度的文字 */

                })
                {
                    byte[] imageData = File.ReadAllBytes(image_path);
                    using (Mat src = Cv2.ImDecode(imageData, ImreadModes.Color))
                    {
                        tempResult = all.Run(src);
                    }
                }
                //test
                TraceLog.Common.Debug($"OcrText PaddlexOcrApi.Rec End");
                //result = result.Replace("\\", "\\\\"); //临时修复一下json格式,这个是C++内部的问题,小事情,先简单修理,如果C++修改了,这里就要删除

                //OcrJson ocrJson = JsonConvert.DeserializeObject<OcrJson>(result);
                string getNum图像识别置信度 = Num图像识别置信度.ToString("#0.000");
                //不信任的原始text,低于信任值的也正常追加大text
                StringBuilder sbDisTrustText = new StringBuilder();
                sbDisTrustText.AppendLine($"[Trust={getNum图像识别置信度}]");
                //把不信任的text会自动处理为加入-横岗分割的string,这样不会参与正则匹配,但是又能带过去细节数据
                StringBuilder sbNormalText = new StringBuilder();
                sbNormalText.AppendLine($"[Trust={getNum图像识别置信度}]");

                //纯文字 只有换行 没有其他掺杂 字符
                StringBuilder sbPlainText = new StringBuilder();
                if (tempResult != null && tempResult.Regions != null)
                {
                    foreach (var item in tempResult.Regions)
                    {
                        string getScore = item.Score.ToDouble().ToString("#0.000");
                        sbDisTrustText.AppendLine($"[Trust={getScore}] {item.Text}");
                        if (item.Score > Num图像识别置信度)
                        {
                            sbNormalText.AppendLine($"[TrustOK={getScore}] {item.Text}");
                        }
                        else
                        {
                            //置信度低的数据会被标记为特殊字符
                            sbNormalText.AppendLine($"[TrustNO={getScore}] {string.Join("-", item.Text.ToCharArray())}");
                        }

                        sbPlainText.AppendLine(item.Text);
                    }
                }
                ocrResult.Success = true;
                ocrResult.OriginalPaddleOcrResult = tempResult;
                ocrResult.DisTrustText = sbDisTrustText.ToString();
                ocrResult.NormalText = sbNormalText.ToString();
                ocrResult.NormalText = Fix识别字符修正字典(ocrResult.NormalText);
                ocrResult.PlainText = sbPlainText.ToString();

                ocrRecord.EngineOriginalText = ocrResult.EngineOriginalText;
                ocrRecord.DisTrustText = ocrResult.DisTrustText;
                ocrRecord.NormalText = ocrResult.NormalText;
                ocrRecord.ElapsedTime = (DateTime.Now - ocrResult.OcrStartDate).Value.TotalSeconds;
                ocrRecord.OcrRecordStatusID = 1;
            }
            catch (Exception ex)
            {
                ocrRecord.OcrRecordStatusID = 0;
                ocrRecord.Info = $"发生错误:{ex.Message}";
                ocrResult.Info = ex.Message;
                TraceLog.OcrApiServer.Error(ex);
            }`

from paddlesharp.

wangning08115 avatar wangning08115 commented on September 27, 2024

@sdcb 我感觉写法和你的 test 中的 一样的, 我就是copy过来,简单改下就用了。

我参考的下边的代码:
`public async Task FastCheckOCR()
{
FullOcrModel model = LocalFullModels.EnglishV3;

        byte[] sampleImageData;
        string sampleImageUrl = @"https://visualstudio.microsoft.com/wp-content/uploads/2021/11/Home-page-extension-visual-updated.png";
        using (HttpClient http = new HttpClient())
        {
            _console.WriteLine("Download sample image from: " + sampleImageUrl);
            sampleImageData = await http.GetByteArrayAsync(sampleImageUrl);
        }

        using (PaddleOcrAll all = new PaddleOcrAll(model)
        {
            AllowRotateDetection = true, /* 允许识别有角度的文字 */
            Enable180Classification = false, /* 允许识别旋转角度大于90度的文字 */
        })
        {
            // Load local file by following code:
            // using (Mat src2 = Cv2.ImRead(@"C:\test.jpg"))
            using (Mat src = Cv2.ImDecode(sampleImageData, ImreadModes.Color))
            {
                PaddleOcrResult result = all.Run(src);
                _console.WriteLine("Detected all texts: \n" + result.Text);
                foreach (PaddleOcrResultRegion region in result.Regions)
                {
                    _console.WriteLine($"Text: {region.Text}, Score: {region.Score}, RectCenter: {region.Rect.Center}, RectSize:    {region.Rect.Size}, Angle: {region.Rect.Angle}");
                }
            }
        }
    }`

from paddlesharp.

wangning08115 avatar wangning08115 commented on September 27, 2024

发现一个规律, 内存极限 取决于 识别的图片大小的极限, 如果识别一个 2K级别的图, 那么内存能上到4-5GB;
如果一直识别的都是小图,500x500px的 那么内存极限就是1-2GB。

问题是到了极限后, 无任务的时候,内存也不会自己回收。感觉是 OCR引擎内部不回收。

from paddlesharp.

sdcb avatar sdcb commented on September 27, 2024

我觉得这种情况可能是常见的,看起来是百度上游的问题,我不知道如何解决,但我表示继续关注

from paddlesharp.

sdcb avatar sdcb commented on September 27, 2024

所以应该可以说,这个本质是没有内存泄露的,对吧?

from paddlesharp.

wangning08115 avatar wangning08115 commented on September 27, 2024

是的没有溢出, 不过 内存不会自动减低, 也是个事情,内存大户 也得节约着用。

from paddlesharp.

sdcb avatar sdcb commented on September 27, 2024

Closed because confirmed not an issue by client.

from paddlesharp.

n0099 avatar n0099 commented on September 27, 2024

有没有用mkldnn?有的话试试
PaddlePaddle/Paddle#25506
PaddlePaddle/PaddleOCR#429
PaddlePaddle/Paddle#27252

from paddlesharp.

a442509097 avatar a442509097 commented on September 27, 2024

我刚开始如下面代码把PaddleOcrAll和ImDecode写在一起, 导致每次都被调用, 然后内存就一直上涨, 后来把PaddleOcrAll写在初始化里(只调用一次), 就好了很多, 但正如楼主所说1080p左右图片直接就上到1G多内存, 关键是这个内存就无法释放了, 调用GC也不行, 之后还会缓慢增长
FullOcrModel model = LocalFullModels.EnglishV3; PaddleOcrAll paddleOcrAll = new PaddleOcrAll(model, PaddleDevice.Mkldnn()); Mat src = Cv2.ImDecode(image, ImreadModes.Color);
感谢n0099, 解释的很清楚
#46

现在用的解决办法就是, 当空闲时检测到占用内存超过一定数, 就重启应用, 哈哈.

from paddlesharp.

n0099 avatar n0099 commented on September 27, 2024

调用GC也不行

GC.Collect()显然只可能释放托管堆中的资源(LOH碎片化暂且不表),这些都是非托管根本不可能被CLR跟踪或直接控制
另外对于托管资源的内存泄露您可以参考M$FT人CLR gc团队某国人写的 https://github.com/Maoni0/mem-doc

对于阁下的代码

FullOcrModel model = LocalFullModels.EnglishV3;
PaddleOcrAll paddleOcrAll = new PaddleOcrAll(model, PaddleDevice.Mkldnn());
Mat src = Cv2.ImDecode(image, ImreadModes.Color);

您都没加using,那自然实现了IDisposable的类PaddleOcrAllMat所代表的非托管资源永远都不会被释放

后来把PaddleOcrAll写在初始化里(只调用一次), 就好了很多

也就是单例化PaddleOcrAll类实例,我也试过但效果都差不多,如果程序并非一直都在持续使用PaddleOcrAll类实例那还不如用完就Dispose,至少能释放掉paddleinfer本身使用的非托管堆(而paddleocr的mkldnn cache直到进程退出都永远都在)

当空闲时检测到占用内存超过一定数, 就重启应用

建议systmed https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html memorymax

from paddlesharp.

a442509097 avatar a442509097 commented on September 27, 2024

n0099
感谢您的认真回复, 之前对C#还不太熟, 还在奇怪加个using是干嘛的. 哈哈. OCR一次, 内存就夸张的增长应该就是这个问题.

另外PaddleOcrAll类我还是觉得用单例比较好, 因为每次都初始化, 有个问题就是识别速度变慢, 我试过至少多用一倍的时间.

from paddlesharp.

n0099 avatar n0099 commented on September 27, 2024

每次都初始化, 有个问题就是识别速度变慢, 我试过至少多用一倍的时间

您用的paddledevice是哪个?基于cpu的openblas/mkldnn还是基于gpu的cuda/tensorrt?
您测量的是单纯new PaddleOcrAll()的耗时,还是new之后识别图片的耗时diff,亦或两者叠加?建议上 https://github.com/dotnet/BenchmarkDotNet
我在mkldnn下没感觉new有多慢

from paddlesharp.

a442509097 avatar a442509097 commented on September 27, 2024

不大清楚, 我是每次要识别的时候调用一次ocr(byte[] image)方法, 可能cpu不一样吧, 我用的X99平台.
捕获

from paddlesharp.

n0099 avatar n0099 commented on September 27, 2024

https://en.wikipedia.org/wiki/Intel_X99 是主板芯片组,我是说您用的哪个u?
不过这14年的板只支持当时的 https://en.wikipedia.org/wiki/Haswell_(microarchitecture)#Server_processors u,而其又最多只支持当时的avx2

from paddlesharp.

a442509097 avatar a442509097 commented on September 27, 2024

捕获
是的, X99平台缺失一些指令集, 所以一些模拟器游戏表现不行. 我当时想除主频外, 指令集是否也影响这个. 查了一下还真是, 所以如果每次都new PaddleOcrAll(), 就会占用时间.
没事, 无非就是内存占用大了, 反正大碗内存, 等到了一定程度自动重启一下应用就是了.

from paddlesharp.

n0099 avatar n0099 commented on September 27, 2024

所以如果每次都new PaddleOcrAll(), 就会占用时间. 没事, 无非就是内存占用大了, 反正大碗内存, 等到了一定程度自动重启一下应用就是了.

您早就 #37 (comment) 没在每次都new PaddleOcrAll()了除非您调用了多次ocrInit()

from paddlesharp.

a442509097 avatar a442509097 commented on September 27, 2024

没, 就ocrInit()一次, 我上面的话可能没表达清楚, 让您误会了.

from paddlesharp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.