Config' object has no attribute 'get_text_config on 4.49.0 VS 4.46.0 all OK
Author: MegaCocos
Pull request: no

Hello, was using ComfyUI node for BiRefNet models (https://github.com/MoonHugo/ComfyUI-BiRefNet-Hugo) with Transformers 4.46.0 and it was running all perfect. Now, when I upgrade to transformers 4.49.0 it stops with the error "Config' object has no attribute 'get_text_config". If I downgrade back to 4.46.0 version the node works well again. So I stuck on transformers 4.46.0. The case is that ComfyUI when updates, collect 4.49.0 and i need to downgrade every time. Is there any easy way to adapt the code by some manner for not getting the error "Config' object has no attribute 'get_text_config" transformers related when it upgrades from 4.46.0 to 4.49.0? What i need to change? Would be very grateful for your help.

Comments:
@MegaCocos hey!

It is hard to help you without seeing where exactly the error is being triggered. Can you make a small repoducer?

But in any case, I think this issue comes from the ComfyUI not updating the code to support the latest release. You can consider opening another issue in ComfyUI repo to see if maintainer have any solution

Hi, @zucchini-nlp the ComfyUI by itself works well with 4.49.0 as it uses much more different nodes that make use of transformers. The error happens only in that specific node ([the code below, sorry for formatting](https://github.com/MoonHugo/ComfyUI-BiRefNet-Hugo/blob/main/nodes.py)). I opened another [issue](https://github.com/MoonHugo/ComfyUI-BiRefNet-Hugo/issues/20) in the repo of the maintainer, but he says he does not know the reason and that he will investigate meanwhile the only solution is to downgrade to 4.46.0 transformers. I was looking by myself for the solution and it seems that the call for config changed by some way from 4.46.0 to 4.49.0 in transformers, but all my attempts to resolve it failed.

from transformers import AutoModelForImageSegmentation
import torch
from torchvision import transforms
import numpy as np
from PIL import Image
import torch.nn.functional as F
import comfy.model_management as mm
import os

torch.set_float32_matmul_precision(["high", "highest"][0])

transform_image = transforms.Compose(
    [
        transforms.Resize((1024, 1024)),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
    ]
)

current_path  = os.getcwd()

## ComfyUI portable standalone build for Windows 
model_path = os.path.join(current_path, "ComfyUI"+os.sep+"models"+os.sep+"BiRefNet")

def tensor2pil(image):
    return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))

def pil2tensor(image):
    return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)

def resize_image(image):
    image = image.convert('RGB')
    model_input_size = (1024, 1024)
    image = image.resize(model_input_size, Image.BILINEAR)
    return image

colors = ["transparency", "green", "white", "red", "yellow", "blue", "black", "pink", "purple", "brown", "violet", "wheat", "whitesmoke", "yellowgreen", "turquoise", "tomato", "thistle", "teal", "tan", "steelblue", "springgreen", "snow", "slategrey", "slateblue", "skyblue", "orange"]

def get_device_by_name(device):
    """
    "device": (["auto", "cuda", "cpu", "mps", "xpu", "meta"],{"default": "auto"}), 
    """
    if device == 'auto':
        try:
            device = "cpu"
            if torch.cuda.is_available():
                device = "cuda"
            elif torch.backends.mps.is_available():
                device = "mps"
            elif torch.xpu.is_available():
                device = "xpu"
        except:
                raise AttributeError("What's your device(到底用什么设备跑的)？")
    print("\033[93mUse Device(使用设备):", device, "\033[0m")
    return device


class BiRefNet_Hugo:
    def __init__(self):
        pass

    @classmethod
    def INPUT_TYPES(cls):
        
        return {
            "required": {
                "image": ("IMAGE",),
                "model": (["ZhengPeng7/BiRefNet", "ZhengPeng7/BiRefNet_HR", "ZhengPeng7/BiRefNet-portrait"],{"default": "ZhengPeng7/BiRefNet"}),
                "load_local_model": ("BOOLEAN", {"default": False}),
                "background_color_name": (colors,{"default": "transparency"}), 
                "device": (["auto", "cuda", "cpu", "mps", "xpu", "meta"],{"default": "auto"})
            },
            "optional": {
                "local_model_path": ("STRING", {"default":model_path}),
            }
        }

    RETURN_TYPES = ("IMAGE", "MASK",)
    RETURN_NAMES = ("image", "mask",)
    FUNCTION = "background_remove"
    CATEGORY = "🔥BiRefNet"
  
    def background_remove(self, 
                          image, 
                          model,
                          load_local_model,
                          device, 
                          background_color_name, 
                          *args, **kwargs
                          ):
        processed_images = []
        processed_masks = []
       
        device = get_device_by_name(device)
        
        if load_local_model:
            local_model_path = kwargs.get("local_model_path", model_path)
            birefnet = AutoModelForImageSegmentation.from_pretrained(local_model_path,trust_remote_code=True)
        else:
            birefnet = AutoModelForImageSegmentation.from_pretrained(
                model, trust_remote_code=True
            )
        
        birefnet.to(device)
        for image in image:
            orig_image = tensor2pil(image)
            w,h = orig_image.size
            image = resize_image(orig_image)
            im_tensor = transform_image(image).unsqueeze(0)
            im_tensor=im_tensor.to(device)
            with torch.no_grad():
                result = birefnet(im_tensor)[-1].sigmoid().cpu()
            result = torch.squeeze(F.interpolate(result, size=(h,w)))
            ma = torch.max(result)
            mi = torch.min(result)
            result = (result-mi)/(ma-mi)    
            im_array = (result*255).cpu().data.numpy().astype(np.uint8)
            pil_im = Image.fromarray(np.squeeze(im_array))
            if background_color_name == 'transparency':
                color = (0,0,0,0)
                mode = "RGBA"
            else:
                color = background_color_name
                mode = "RGB"
            new_im = Image.new(mode, pil_im.size, color)
            new_im.paste(orig_image, mask=pil_im)
            new_im_tensor = pil2tensor(new_im)
            pil_im_tensor = pil2tensor(pil_im)
            processed_images.append(new_im_tensor)
            processed_masks.append(pil_im_tensor)

        new_ims = torch.cat(processed_images, dim=0)
        new_masks = torch.cat(processed_masks, dim=0)

        return new_ims, new_masks


NODE_CLASS_MAPPINGS = {
    "BiRefNet_Hugo": BiRefNet_Hugo
}

# A dictionary that contains the friendly/humanly readable titles for the nodes
NODE_DISPLAY_NAME_MAPPINGS = {
    "BiRefNet_Hugo": "🔥BiRefNet"
}

@zucchini-nlp Hi, you can use this instead of the comfyui code, it works in 4.48.3 but get same error in 4.49.0
```
from transformers import AutoModelForImageSegmentation
birefnet = AutoModelForImageSegmentation.from_pretrained('ZhengPeng7/BiRefNet_HR', trust_remote_code=True).to('cuda')
```

Hello, @chechaohp, I just did not try it on all the versions of Transformers. Generally in this moment it is the same thing for me to use 4.46.0 o 4.48.3, i just need to turn off the updates and cant use pip install requirements.txt for install, as it installs 4.49.0 by default. If it is only 4.49.0 being non working version, more seems to be a bug than other thing.

Hi @MegaCocos , I do agree that it seems like a bug. I was able to run my code before but could not run it again after I created a new environment, so I figured out it was the latest version, I tried to downgrade it and it works

Ah I see, it's because the remote model's config (https://huggingface.co/ZhengPeng7/BiRefNet_HR/blob/main/birefnet.py) is not a `PreTrainedConfig` which is causing the error

We can't guarantee support to models/configs which are not instances of PreTrained config/model, so I'd suggest to update the hub file to inherit from `PreTrainedConfig`. If you are not the owner, you can open a PR on the hub :)

@zucchini-nlp I have opened an issue https://github.com/ZhengPeng7/BiRefNet/issues/189#issue-2874264525 Is it difficult to implement? Does it suppose big changes in the code?


@zucchini-nlp The owner asks me "Do you mean that I need to change class Config(): -> class Config(PretrainedConfig): in config.py?" https://github.com/ZhengPeng7/BiRefNet/issues/189#issuecomment-2677800342

@MegaCocos yep, that is the needed change

Many thanks! @zucchini-nlp, should I do the update only in HuggingFace or also codes in GitHub if someone uses them in a mixed way?

@ZhengPeng7 If the codes in GH are also loaded with `transformers` in same way, I suggest updating both

It is solved! https://github.com/ZhengPeng7/BiRefNet/issues/189#issuecomment-2677979087 Thank you very much for your help!