Team Ai
Apppublic

huggingface/Model_Cards_Writing_Tool

sourceHugging Facemitupdated 2y agoView on Hugging Face
125likes
specific_extraction.py529 linesDownload Raw Back to root
1import re2import streamlit as st3from modelcards import CardData, ModelCard4from markdownTagExtract import tag_checker,listToString,to_markdown5#from specific_extraction import extract_it6 7 8# from persist import persist9#global bytes_data10 11 12################################################################13#### Markdown parser logic #################################14################################################################15 16def file_upload():17    bytes_data = st.session_state.markdown_upload18    return bytes_data19 20 21# Sets up the basics22model_card_md = file_upload()  # this is where the new model card will be read in from23model_card_md = model_card_md#.decode("utf-8")24# Does metadata appear in any other format than this?25metadata_re = re.compile("^---(.*?)---", re.DOTALL)26header_re = re.compile("^\s*# (.*)", re.MULTILINE)27subheader_re = re.compile("^\s*## (.*)", re.MULTILINE)28subsubheader_re = re.compile("^\s*### (.*)", re.MULTILINE)29subsubsubheader_re = re.compile("^\s*#### (.*)", re.MULTILINE)30# We could be a lot more flexible on this re.31# We require keys to be bold-faced here.32# We don't have to require bold, as long as it's key:value33# **License:**34# Bold terms use ** or __35# Allows the mixing of ** and __ for bold but eh whatev36key_value_re = re.compile("^\s*([*_]{2}[^*_]+[*_]{2})([^\n]*)", re.MULTILINE)37# Hyphens or stars mark list items.38# Unordered list39list_item_re = re.compile("^\s*[-*+]\s+.*", re.MULTILINE)40# This is the ordered list41enum_re = re.compile("^\s*[0-9].*", re.MULTILINE)42table_re = re.compile("^\s*\|.*", re.MULTILINE)43text_item_re = re.compile("^\s*[A-Za-z(](.*)", re.MULTILINE)44# text_item_re = re.compile("^\s*#\s*.*", re.MULTILINE)45# Allows the mixing of -* and *- for italics but eh whatev46italicized_text_item_re = re.compile(47    "^[_*][^_*\s].*\n?.*[^_*][_*]$", flags=re.MULTILINE48)49tag_re = re.compile("^\s*<.*", re.MULTILINE)50image_re = re.compile("!\[.*\]\(.*\)", re.MULTILINE)51 52 53subheader_re_dict = {}54subheader_re_dict[header_re] = subheader_re55subheader_re_dict[subheader_re] = subsubheader_re56subheader_re_dict[subsubheader_re] = subsubsubheader_re57 58 59def get_metadata(section_text):60    return list(metadata_re.finditer(section_text))61 62 63def find_images(section_text):64    return list(image_re.finditer(section_text))65 66 67def find_tags(section_text):68    return list(tag_re.finditer(section_text))69 70 71def find_tables(section_text):72    return list(table_re.finditer(section_text))73 74 75def find_enums(section_text):76    return list(enum_re.finditer(section_text))77 78 79# Extracts the stuff from the .md file80def find_key_values(section_text):81    return list(key_value_re.finditer(section_text))82 83 84def find_lists(section_text):85    # Find lists: Those lines starting with either '-' or '*'86    return list(list_item_re.finditer(section_text))87 88 89def find_texts(section_text):90    # Find texts: Free writing within a section91    basic_text = list(text_item_re.finditer(section_text))92    ital_text = list(italicized_text_item_re.finditer(section_text))93    free_text = basic_text + ital_text94    return free_text95 96 97def find_headers(full_text):98    headers = list(header_re.finditer(full_text))99    subheaders = list(subheader_re.finditer(full_text))100    subsubheaders = list(subsubheader_re.finditer(full_text))101    subsubsubheaders = list(subsubsubheader_re.finditer(full_text))102    return (headers, subheaders, subsubheaders, subsubsubheaders)103 104 105metadata_list = get_metadata(model_card_md)106if metadata_list != []:107    metadata_end = metadata_list[-1].span()[-1]108    print("Metadata extracted")109    # Metadata processing can happen here.110    # For now I'm just ignoring it.111    model_card_md = model_card_md[metadata_end:]112else:113    print("No metadata found")114 115# Matches of all header types116headers_list = find_headers(model_card_md)117print("Headers extracted")118# This type of header (one #)119headers = headers_list[0]120## This type of header (two ##)121subheaders = headers_list[1]122### This type of header123subsubheaders = headers_list[2]124#### This type of header125subsubsubheaders = headers_list[3]126 127# Matches of bulleted lists128lists_list = find_lists(model_card_md)129print("Bulleted lists extracted")130 131enums_list = find_enums(model_card_md)132print("Enumerated lists extracted")133 134key_value_list = find_key_values(model_card_md)135print("Key values extracted")136 137tables_list = find_tables(model_card_md)138print("Tables extracted")139 140tags_list = find_tags(model_card_md)141print("Markup tags extracted")142 143images_list = find_images(model_card_md)144print("Images extracted")145 146# Matches of free text within a section147texts_list = find_texts(model_card_md)148print("Free text extracted")149 150 151# List items have the attribute: value;152# This provides for special handling of those strings,153# allowing us to check if it's a list item in order to split/print ok.154LIST_ITEM = "List item"155KEY_VALUE = "Key: Value"156FREE_TEXT = "Free text"157ENUM_LIST_ITEM = "Enum item"158TABLE_ITEM = "Table item"159TAG_ITEM = "Markup tag"160IMAGE_ITEM = "Image"161 162 163def create_span_dict(match_list, match_type):164    """165    Creates a dictionary made out of all the spans.166    This is useful for knowing which types to fill out with what in the app.167    Also useful for checking if there are spans in the .md file that we've missed.168    """169    span_dict = {}170    for match in match_list:171        if len(match.group().strip()) > 0:172            span_dict[(match.span())] = (match.group(), match_type)173    return span_dict174 175 176metadata_span_dict = create_span_dict(metadata_list, "Metadata")177# Makes a little dict for each span type178header_span_dict = create_span_dict(headers, "# Header")179subheader_span_dict = create_span_dict(subheaders, "## Subheader")180subsubheader_span_dict = create_span_dict(subsubheaders, "### Subsubheader")181subsubsubheader_span_dict = create_span_dict(subsubsubheaders, "#### Subsubsubheader")182key_value_span_dict = create_span_dict(key_value_list, KEY_VALUE)183lists_span_dict = create_span_dict(lists_list, LIST_ITEM)184enums_span_dict = create_span_dict(enums_list, ENUM_LIST_ITEM)185tables_span_dict = create_span_dict(tables_list, TABLE_ITEM)186tags_span_dict = create_span_dict(tags_list, TAG_ITEM)187images_span_dict = create_span_dict(images_list, IMAGE_ITEM)188texts_span_dict = create_span_dict(texts_list, FREE_TEXT)189 190# We don't have to have these organized by type necessarily.191# Doing it here for clarity.192all_spans_dict = {}193all_spans_dict["headers"] = header_span_dict194all_spans_dict["subheaders"] = subheader_span_dict195all_spans_dict["subsubheaders"] = subsubheader_span_dict196all_spans_dict["subsubsubheaders"] = subsubsubheader_span_dict197all_spans_dict[LIST_ITEM] = lists_span_dict198all_spans_dict[KEY_VALUE] = key_value_span_dict199all_spans_dict[TABLE_ITEM] = tables_span_dict200all_spans_dict[ENUM_LIST_ITEM] = enums_span_dict201all_spans_dict[TAG_ITEM] = tags_span_dict202all_spans_dict[IMAGE_ITEM] = images_span_dict203all_spans_dict[FREE_TEXT] = texts_span_dict204 205 206def get_sorted_spans(spans_dict):207    merged_spans = {}208    for span_dict in spans_dict.values():209        merged_spans.update(span_dict)210    sorted_spans = sorted(merged_spans)211    return sorted_spans, merged_spans212 213 214sorted_spans, merged_spans = get_sorted_spans(all_spans_dict)215 216# Sanity/Parse check. Have we captured all spans in the .md file?217if sorted_spans[0][0] != 0:218    print("FYI, our spans don't start at the start of the file.")219    print("We did not catch this start:")220    print(model_card_md[: sorted_spans[0][0]])221 222for idx in range(len(sorted_spans) - 1):223    last_span_end = sorted_spans[idx][1]224    new_span_start = sorted_spans[idx + 1][0]225    if new_span_start > last_span_end + 1:226        start_nonparse = sorted_spans[idx]227        end_nonparse = sorted_spans[idx + 1]228        text = model_card_md[start_nonparse[1] : end_nonparse[0]]229        if text.strip():230            print("Found an unparsed span in the file:")231            print(start_nonparse)232            print(" ---> ")233            print(end_nonparse)234            print(text)235 236# print(header_span_dict)237def section_map_to_help_text(text_retrieved):238 239    presit_states = {240        "## Model Details": "Give an overview of your model, the relevant research paper, who trained it, etc.",241        "## How to Get Started with the Model": "Give an overview of how to get started with the model",242        "## Limitations and Biases": "Provide an overview of the possible Limitations and Risks that may be associated with this model",243        "## Uses": "Detail the potential uses, intended use and out-of-scope uses for this model",244        "## Training": "Provide an overview of the Training Data and Training Procedure for this model",245        "## Evaluation Results": "Detail the Evaluation Results for this model",246        "## Environmental Impact": "Provide an estimate for the carbon emissions: Total emissions (in grams of CO2eq) and additional considerations, such as electricity usage, go here.",247        "## Citation Information": "How to best cite the model authors",248        "## Glossary": "If relevant, include terms and calculations in this section that can help readers understand the model or model card.",249        "## More Information": "Any additional information",250        "## Model Card Authors": "This section provides another layer of transparency and accountability. Whose views is this model card representing? How many voices were included in its construction? Etc.",251        "Model Card Contact": "Mediums to use, in order to contact the model creators",252        "##  Technical Specifications": " Additional technical information",253        '## Model Examination': " Examining the model",254    }255 256    for key in presit_states:257        if key == text_retrieved:258            return presit_states(key)259 260 261def section_map_to_persist(text_retrieved):262 263    presit_states = {264        "Model_details_text": "## Model Details",265        "Model_how_to": "## How to Get Started with the Model",266        "Model_Limits_n_Risks": "## Limitations and Biases",267        "Model_uses": "## Uses",268        "Model_training": "## Training",269        "Model_Eval": "## Evaluation Results",270        "Model_carbon": "## Environmental Impact",271        "Model_cite": "## Citation Information",272        "Glossary": "## Glossary",273        "More_info": "## More Information",274        "Model_card_authors": "## Model Card Authors",275        "Model_card_contact": "## Model Card Contact",276        "Technical_specs": "## Technical specifications",277        "Model_examin": "## Model Examination",278    }279 280    for key in presit_states:281        if presit_states[key] == text_retrieved:282            return key283 284 285def main():286    # st.write('here')287    print(extract_it("Model_details_text"))288 289 290def extract_headers():291    headers = {}292    subheaders = {}293    subsubheaders = {}294    subsubsubheaders = {}295    previous = (None, None, None, None)296 297    for s in sorted_spans:298        if merged_spans[s][1] == "# Header":299            headers[s] = (sorted_spans.index(s), previous[0])300            previous = (sorted_spans.index(s), previous[1], previous[2], previous[3])301        if merged_spans[s][1] == "## Subheader":302            subheaders[s] = (sorted_spans.index(s), previous[1])303            previous = (previous[0], sorted_spans.index(s), previous[2], previous[3])304        if merged_spans[s][1] == "### Subsubheader":305            subsubheaders[s] = (sorted_spans.index(s), previous[2])306            previous = (previous[0], previous[1], sorted_spans.index(s), previous[3])307        if merged_spans[s][1] == "#### Subsubsubheader":308            subsubsubheaders[s] = (sorted_spans.index(s), previous[3])309            previous = (previous[0], previous[1], previous[2], sorted_spans.index(s))310 311    return headers, subheaders, subsubheaders, subsubsubheaders312 313 314def stringify():315    headers, subheaders, subsubheaders, subsubsubheaders = extract_headers()316    headers_strings = {}317    subheaders_strings = {}318    subsubheaders_strings = {}319    subsubsubheaders_strings = {}320 321    first = None322    for i in headers:323        if headers[i][1] == None:324            continue325        sub_spans = sorted_spans[headers[i][1] : headers[i][0]]326        lines = []327        for x in sub_spans:328            lines.append(merged_spans[x][0])329        try:330            name = lines[0]331        except:332            name = "Model Details"333        lines = "".join(lines)334        # print(merged_spans[i][0] + "-------------------")335        # print(lines)336        headers_strings[337            name.replace("\n# ", "")338            .replace("    ", "")339            .replace("  ", "")340            .replace("\n", "")341            .replace("{{", "")342            .replace("}}", "")343        ] = lines344        first = i345 346    first = None347    for i in subheaders:348        if subheaders[i][1] == None:349            continue350        sub_spans = sorted_spans[subheaders[i][1] : subheaders[i][0]]351        lines = []352        for x in sub_spans:353            if merged_spans[x][1] == "## Subheader" and first == None:354                break355            elif merged_spans[x][1] == "# Header":356                break357            else:358                lines.append(merged_spans[x][0])359        try:360            name = lines[0]361        except:362            name = "Model Details"363        lines = "".join(lines)364        # print(merged_spans[i][0] + "-------------------")365        # print(lines)366        subheaders_strings[367            name.replace("\n# ", "").replace("    ", "").replace("  ", "")368        ] = lines369        first = i370 371    first = None372    for i in subsubheaders:373        if subsubheaders[i][1] == None:374            continue375        sub_spans = sorted_spans[subsubheaders[i][1] : subsubheaders[i][0]]376        lines = []377        for x in sub_spans:378            if merged_spans[x][1] == "## Subheader" or (379                merged_spans[x][1] == "### Subsubheader" and first == None380            ):381                break382            else:383                lines.append(merged_spans[x][0])384        lines = "".join(lines)385 386        subsubheaders_strings[387            merged_spans[i][0].replace("\n", "").replace("### ", "").replace("    ", "")388        ] = lines389        first = i390 391    for i in subsubsubheaders:392        if subsubsubheaders[i][1] == None:393            continue394        sub_spans = sorted_spans[subsubsubheaders[i][1] : subsubsubheaders[i][0]]395        lines = []396        for x in sub_spans:397            if (398                merged_spans[x][1] == "## Subheader"399                or merged_spans[x][1] == "### Subsubheader"400            ):401                break402            else:403                lines.append(merged_spans[x][0])404        lines = "".join(lines)405 406        subsubsubheaders_strings[407            merged_spans[i][0].replace("#### ", "").replace("**", "").replace("\n", "")408        ] = lines409 410    return (411        headers_strings,412        subheaders_strings,413        subsubheaders_strings,414        subsubsubheaders_strings,415    )416 417 418def extract_it(text_to_retrieve):419    print("Span\t\tType\t\tText")420    print("-------------------------------------")421    found_subheader = False422    current_subheader = " "423    page_state = " "424    help_text = " "425    #st.write("in cs- body here")426 427    (428        headers_strings,429        subheaders_strings,430        subsubheaders_strings,431        subsubsubheaders_strings,432    ) = stringify()433 434    h_keys = list(headers_strings.keys())435    sh_keys = list(subheaders_strings.keys())436    ssh_keys = list(subsubheaders_strings.keys())437    sssh_keys = list(subsubsubheaders_strings.keys())438 439    needed = [440        "model details",441        "howto",442        "limitations",443        "uses",444        "training",445        "evaluation",446        "environmental",447        "citation",448        "glossary",449        "more information",450        "authors",451        "contact",452    ]  # not sure what keyword should be used for citation, howto, and contact453    # info_strings = {454    #     "details": "## Model Details",455    #     "howto": "## How to Get Started with the Model",456    #     "limitations": "## Limitations and Biases",457    #     "uses": "## Uses",458    #     "training": "## Training",459    #     "evaluation": "## Evaluation Results",460    #     "environmental": "## Environmental Impact",461    #     "citation": "## Citation Information",462    #     "glossary": "## Glossary",463    #     "more information": "## More Information",464    #     "authors": "## Model Card Authors",465    #     "contact": "## Model Card Contact",466    # }467    info_strings = {468        "model details": "",469        "howto": "",470        "limitations": "",471        "uses": "",472        "training": "",473        "evaluation": "",474        "environmental": "",475        "citation": "",476        "glossary": "",477        "more information": "",478        "authors": "",479        "contact": "",480    }481 482    for x in needed:483        for l in h_keys:484            if x in l.lower():485                info_strings[x] = info_strings[x] + headers_strings[l]486        for i in sh_keys:487            if x in i.lower():488                info_strings[x] = info_strings[x] + subheaders_strings[i]489        for z in ssh_keys:490            try:491                if x in z.lower():492                    info_strings[x] = info_strings[x] + subsubheaders_strings[z]493            except:494                continue495        for y in sssh_keys:496            try:497                if x in y.lower():498                    info_strings[x] = info_strings[x] + subsubsubheaders_strings[y]499            except:500                continue501 502    extracted_info = {503        "Model_details_text": info_strings["model details"],504        "Model_how_to": info_strings["howto"],505        "Model_Limits_n_Risks": info_strings["limitations"],506        "Model_uses": info_strings["uses"],507        "Model_training": info_strings["training"],508        "Model_Eval": info_strings["evaluation"],509        "Model_carbon": info_strings["environmental"],510        "Model_cite": info_strings["citation"],511        "Glossary": info_strings["glossary"],512        "More_info": info_strings["more information"],513        "Model_card_authors": info_strings["authors"],514        "Model_card_contact": info_strings["contact"],515        "Technical_specs": "## Technical specifications",516        "Model_examin": "## Model Examination",517    }518 519    #text_to_retrieve = "Model_details_text"520 521    new_t = extracted_info[text_to_retrieve] + " "522 523    return(new_t)524 525 526if __name__ == "__main__":527 528    main()529